feat(codemode): unify parallel() calling convention with the sequential ns.tool() form#7
Merged
Merged
Conversation
…al ns.tool() form
The concurrent path required a separate string-descriptor convention
(parallel([{tool: "ns__name", args}, ...])) that diverged from the natural
sequential form (ns.tool(args)) — a recurring agent error source and extra
mental model. parallel() now also accepts bound tool references, matching the
sequential call form:
parallel([[github.list_issues, {repo}], [linear.search, {query}]]) // tuple
parallel([{tool: github.list_issues, args}, ...]) // object + ref
Each tool function carries its canonical "ns__name" in a hidden
(non-enumerable) property so parallel() recovers the name for concurrent
Go-goroutine dispatch — real concurrency is preserved; only the surface
changes. The legacy string form still works, so this is backward compatible.
Also normalizes no-arg parallel calls to send "{}" (matching the sequential
marshalToolArgs) instead of "null", which a downstream tool expecting an
object could reject — the two paths now send identical shapes for identical
calls, in dispatch and in the audit record.
help() and the execute_code tool descriptions advertise the new form.
Tests: bound tuple/object/mixed dispatch with arg round-trip, non-tool-closure
rejection, hidden-tag invisibility to Object.keys, and the no-arg "{}"
normalization; existing string-descriptor tests unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MW9JEiRKg9zVffe14ybKGm
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.
What
parallel()now accepts bound tool references in the same call form as the sequential path, in addition to the legacy string descriptor:Why
The concurrent path required a separate string-descriptor convention that diverged from the natural
ns.tool(args)sequential form. That mismatch is a recurring agent error source (wrong__name, args nested wrong) and a second mental model for "call a tool." Unifying them means the multi-call path reads like the one-call path.How
ns__namein a hidden (non-enumerable, non-writable) own property (tagToolFunc).parallel()recovers the name from a passed reference and dispatches via the same Go-goroutine concurrency as before — real concurrency is preserved; only the surface changes.parseParallelArgswalks the live Goja values (notExport(), which erases the tag) to classify tuple vs object items and resolve the tool slot (function or string) and args.{}(matching the sequentialmarshalToolArgs) instead ofnull, in both dispatch and the audit record — a downstream tool expecting an object could rejectnull.help()and bothexecute_codetool descriptions advertise the new form.Tests
Object.keys(){}normalizationIsolated build (
go build -tags p2p ./...) andgo test ./internal/codemode/green.🤖 Generated with Claude Code
https://claude.ai/code/session_01MW9JEiRKg9zVffe14ybKGm