refactor(kernel-agents): make the exo membrane the sole capability arg enforcer#960
Merged
Merged
Conversation
fc7d58e to
9e110e2
Compare
0ad88c7 to
6465e1f
Compare
Contributor
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
9e110e2 to
6c6abee
Compare
6465e1f to
99b92e4
Compare
6c6abee to
620c437
Compare
41f106b to
cf4502f
Compare
1812ca4 to
06d6853
Compare
cf4502f to
70eefa2
Compare
…g enforcer Now that every capability is a pattern-guarded discoverable exo, retire the membraneless authoring and validation paths: - Remove the `capability()` authoring helper and the `validateCapabilityArgs` validator (and its now-dead module). A capability's arguments are enforced only by its exo's interface guard; the chat strategy no longer re-validates before invoking, relying on the guard rejection it already catches. - Add a `test/make-method-capability.ts` helper that wraps a single described method (an `S.method`) into a guarded discoverable-exo capability via `makeInternalCapabilities`, and migrate the chat and JSON evaluator tests (and the capability test, repurposed to cover the surviving `extract*` helpers) onto it. - Collapse the redundant `CapabilitySchema` type into kernel-utils' `MethodSchema`: a capability's `schema` is exactly the `MethodSchema` its exo describes, so the parallel type (and its `ExtractRecordKeys` helper) is gone. - Drop the unused `@metamask/superstruct` dependency. BREAKING: the `capability()` authoring helper is no longer exported from `@ocap/kernel-agents/capabilities/capability`. Author capabilities as discoverable exos (via the `described*()` combinators) and convert them with `discover`. (`validateCapabilityArgs` was internal and never exported.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
70eefa2 to
1ab9888
Compare
sirtimid
reviewed
Jun 25, 2026
Normalize capability invocation failures at the exo membrane: capabilitiesFrom wraps every guarded call so a guard rejection (or any thrown value) becomes a real Error naming the expected signature, e.g. "Error calling add(a: number, b: number): …". This holds even when the guard rejects with an opaque value (as under the test shim), so every caller — both agent strategies and remote discover() — gets an actionable message instead of a load-bearing String(error) fallback at one call site. The chat agent surfaces that message verbatim and only frames JSON parse failures itself. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
377acb5 to
6dc44a8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation
The base PRs (#958, #959) made every built-in capability a pattern-guarded discoverable exo. Now that the exo's interface guard already enforces each capability's argument shape, this PR retires the parallel membraneless authoring and validation paths so the guard is the single argument enforcer:
capability()authoring helper and the internalvalidateCapabilityArgsvalidator (and its now-dead module). The chat strategy no longer re-validates arguments before invoking — it relies on the guard rejection it catches and reports as anError calling …tool message. That catch is hardened to handle a non-Errorrejection, so an invalid-argument tool call surfaces as a tool error instead of crashing the task (covered by a new regression test).CapabilitySchematype into kernel-utils'MethodSchema(a capability'sschemais exactly theMethodSchemaits exo describes), removing the parallel type and itsExtractRecordKeyshelper.test/make-method-capability.tshelper that builds a guarded, discovered single-method capability from anS.method, and migrates the chat and JSON evaluator tests (and the capability test, repurposed to cover the survivingextract*helpers) onto it.@metamask/superstructdependency.Breaking changes
capability()authoring helper is no longer exported from@ocap/kernel-agents/capabilities/capability. Author capabilities as pattern-guarded discoverable exos (via thedescribed*()combinators in@metamask/kernel-utils) and convert them withdiscover. (validateCapabilityArgswas internal and never exported.)Test plan
Note
Medium Risk
Breaking public API (
capability()removal) affects downstream authors, but runtime behavior stays aligned with prior exo-backed builtins; main risk is consumers still using the old helper or assuming pre-invoke Superstruct errors.Overview
Breaking: Removes the exported
capability()helper and the internal Superstruct-basedvalidateCapabilityArgspath. Capabilities are expected to be authored as pattern-guarded discoverable exos (described*()+discover/makeInternalCapabilities);CapabilitySpec.schemais now kernel-utilsMethodSchemainstead of a parallelCapabilitySchematype.Invocation errors from the exo interface guard are normalized in
capabilitiesFromtoError calling <name>(<params>): …so chat and other callers can surface actionable tool messages without a second validation layer. The chat agent parses tool JSON locally when needed, invokes capabilities directly, and pushes guard/implementation failures as tool errors (including a regression test for bad args) instead of crashing the loop.Tests migrate to
test/make-method-capability.ts;@metamask/superstructis dropped from dependencies.Reviewed by Cursor Bugbot for commit 6dc44a8. Bugbot is set up for automated code reviews on this repo. Configure here.