Repository navigation
feat(binding): support composite capability inputs - #67
Conversation
Inputs now bind lists, string-keyed dicts, nested structs, optionals, and every integer and float width through one shared input/output type compiler. The worker binds against a private post-order InputSchema; the parent re-binds the canonical map by reflection before authorization. Ints are accepted for float fields. Nested input and all output field names only need to be valid JSON names; root input names stay Starlark identifiers.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 029e45fa6c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| target.SetFloat(checked) | ||
| return checked, nil |
There was a problem hiding this comment.
Canonicalize float32 values after narrowing
When a capability input contains a float32 field, SetFloat narrows the validated float64, but the canonical authorization map receives the original value. For example, a Starlark 0.1 is authorized as its float64 representation while the handler receives the different float32-rounded value; a boundary-based policy can therefore authorize a value other than the one acted upon. Return the widened value read back from target after assignment so authorization and handler inputs remain identical.
Useful? React with 👍 / 👎.
Address review findings on composite inputs: - Worker Bind charges every argument node against MaxValueDepth and the MaxValueBytes-derived node budget before materializing, so aliased Starlark containers fail with ErrResourceLimit instead of expanding. - Diagnostic paths are a push/pop segment stack rendered only on error, making worker Bind and parent BindValue linear in argument size. - float32 inputs canonicalize to the rounded float32 value so policy sees exactly what the handler receives.
Summary
Capability inputs now accept the same structural types as outputs (with a few direction-specific exceptions), so agents can pass lists, dicts, and nested objects to capabilities.
string,bool, every signed/unsigned integer width (range-checked),float32/float64,*T(optional),[]T(list or tuple;[]byte= list of 0–255),map[string-kind]T, and nested structs (dicts with exactly the declared keys).json.Unmarshaler/encoding.TextUnmarshalertypes (e.g.time.Time).float64in canonical arguments).encoding/jsontag names (e.g.from,created-at); notation quotes non-identifiers. Root input names stay Starlark identifiers (keyword arguments).filter.owner,tags[1],labels['env'],window['until-day'], with "or None" for optional values and range messages for narrow integers.map[string]any/[]any. Optional struct members that are omitted orNoneare absent at every level.Design
internal/binding/compile.go) builds a post-order node arena for inputs and outputs with per-direction rules.binding.InputSchemathat replaces the flat[]FieldShapein the worker manifest andexecution.CapabilityBinding. The worker validates it once at load and binds Starlark values against it, so model-facing detail stays child-origin (session 012 rule).FieldShapeand the MCP schema stay flat; only thetypestrings got richer.Prototyped in a throwaway spike first; this is the clean implementation.
Testing
go test -race ./...passes;golangci-lint run ./...reports 0 issues;moon run docs:buildpasses.internal/executionandinternal/worker(real worker subprocess) carrying composite arguments.TestActualMCPCompositeInputProgram(added tomcp-smoke): describe → execute over MCP → typed handler input + nested canonical authorization map; malformed calls return exact path diagnostics and never reach policy.docs/docs/reference/public-api.mdwas checked by running its exact signature and canonical maps against the implementation.