Skip to content

Conversation

@rabi
Copy link
Contributor

@rabi rabi commented Jan 6, 2026

Summary

  • Auto-prefix unprefixed tool names (read_module -> code_execution__read_module)
  • Parse stringified JSON arrays in search_modules terms parameter
  • Add note that all tool calls are synchronous (no async/await)
  • Improve search_modules documentation to clarify array parameter format

Fixes issues where some models (e.g. Nemotron) strip tool prefixes or stringify array parameters.

Type of Change

  • Feature
  • Bug fix
  • Refactor / Code quality
  • Performance improvement
  • Documentation
  • Tests
  • Security fix
  • Build / Release
  • Other (specify below)

AI Assistance

  • This PR was created or reviewed with AI assistance

Testing

Tested with vLLM and Nemotron Hybrid MoE Model (nemotron-3-nano-30b-a3b)

- Auto-prefix unprefixed tool names (read_module -> code_execution__read_module)
- Parse stringified JSON arrays in search_modules terms parameter
- Add note that all tool calls are synchronous (no async/await)
- Improve search_modules documentation to clarify array parameter format

Fixes issues where some models (e.g. Nemotron) strip tool prefixes or
stringify array parameters.

Signed-off-by: rabi <ramishra@redhat.com>
- WRONG: Multiple execute_code calls, each with one tool
- RIGHT: One execute_code call with a script that calls all needed tools
IMPORTANT: All tool calls are SYNCHRONOUS. Do NOT use async/await.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hrm - I guess this is true - are we sure?
Also, I wonder if there is some other way to enforce this than prompting, but I think this is is ok @alexhancock

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by this part of the code @rabi . Isn't the builtin function we provide async, and therefor don't any calls the model writes to functions which call a tool need to be awaited?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems tools are exposed to the model as synchronous JavaScript functions via the Boa JS engine. create_tool_function wraps each tool using blocking_recv() which blocks until the async Rust handler responds. So, model-generated code I think should use const x = tool({...}) not await tool({...}).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense @rabi. I had misremembered. Merged

- Multiple terms: terms=["git", "shell"] (a JSON array, NOT a string)
- Regex patterns: terms="sh.*", regex=true
IMPORTANT: Do NOT stringify arrays. Use terms=["a","b"] not terms="[\"a\",\"b\"]"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have found saying NOT can use up attention and hurt performance, wonder if we need that so explicitly (if there is a way to feedback errors then that can help)

tool_call: CallToolRequestParam,
cancellation_token: CancellationToken,
) -> Result<ToolCallResult> {
// Some models strip the tool prefix, so auto-add it for known code_execution tools
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this special casing for code execution as it needs to prefix it, but in other cases - they work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think code_execution tools (execute_code, read_module, search_modules) are the only tools the model calls directly when code_execution extension is enabled. Model is expected to call the tools with the extension prefix, but I suspect when all visible tools share the same prefix and the instruction is to use without prefix, some models strip them.

@michaelneale
Copy link
Collaborator

thanks @rabi - cc @alexhancock shoudl we do some benchmarks/checking with frontier models to make sure this is no worse (I am worryed about the use of "not" in the prompts as it consumes extra attention heads).

Copy link
Collaborator

@michaelneale michaelneale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems a functional improvement, would like a +1 from @alexhancock though

Copy link
Collaborator

@alexhancock alexhancock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM other than the Q I asked

@alexhancock alexhancock merged commit d9a30a8 into block:main Jan 13, 2026
17 checks passed
wpfleger96 added a commit that referenced this pull request Jan 13, 2026
* main: (41 commits)
  Allow customizing the new line keybinding in the CLI (#5956)
  Ask for permission in the CLI (#6475)
  docs: add Ralph Loop tutorial for multi-model iterative development (#6455)
  Remove gitignore fallback from gooseignore docs (#6480)
  fix: clean up result recording for code mode (#6343)
  fix(code_execution): handle model quirks with tool calls (#6352)
  feat(ui): support prefersBorder option for MCP Apps (#6465)
  fixed line breaks (#6459)
  Use Intl.NumberFormat for token formatting in SessionsInsights (#6466)
  feat(ui): format large and small token counts for readability (#6449)
  fix: apply subrecipes when using slash commands (#6460)
  Fix: exclude platform_schedule_tool in CLI (#6442)
  Fix: Small update in how ML-based prompt injection determines final result (#6439)
  docs: remove SSE transport and rename to Streamable HTTP (#6319)
  fix: correct Cloudinary extension command and env variable (#6453)
  fix: add gap between buttons in MacDesktopInstallButtons.js (#6452)
  refactor: include hidden dotfiles folders in file picker search (#6315)
  upgraded safe npm packages (#6450)
  chore(deps): bump react-router and react-router-dom in /ui/desktop (#6408)
  chore(deps): bump lru from 0.12.5 to 0.16.3 (#6379)
  ...
lifeizhou-ap added a commit that referenced this pull request Jan 14, 2026
* main:
  fix: require auth when running goose on non loopback address (#6478)
  chore(deps): bump hono from 4.11.3 to 4.11.4 in /ui/desktop (#6485)
  feat(cli): graceful fallback for keyring failures (#5808)
  fix: support global .gooseignore and negation patterns (#6157)
  docs: manual config for jetbrains (#6490)
  fix: Recipe slash command doesn't work with single optional parameter (#6235)
  fix(openrouter): Handle Gemini thoughtSignature for tool calls (#6370)
  docs: fix extensions page (#6484)
  Allow customizing the new line keybinding in the CLI (#5956)
  Ask for permission in the CLI (#6475)
  docs: add Ralph Loop tutorial for multi-model iterative development (#6455)
  Remove gitignore fallback from gooseignore docs (#6480)
  fix: clean up result recording for code mode (#6343)
  fix(code_execution): handle model quirks with tool calls (#6352)
  feat(ui): support prefersBorder option for MCP Apps (#6465)
  fixed line breaks (#6459)
  Use Intl.NumberFormat for token formatting in SessionsInsights (#6466)
  feat(ui): format large and small token counts for readability (#6449)
  fix: apply subrecipes when using slash commands (#6460)
ThanhNguyxn pushed a commit to ThanhNguyxn/goose that referenced this pull request Jan 14, 2026
Signed-off-by: rabi <ramishra@redhat.com>
Signed-off-by: ThanhNguyxn <thanhnguyentuan2007@gmail.com>
zanesq added a commit that referenced this pull request Jan 14, 2026
…ased

* 'main' of github.com:block/goose:
  fix(code_execution): serialize record_result output as JSON (#6495)
  perf(google): avoid accumulating thoughtSignatures across conversation history (#6462)
  fix(openai): make tool_call arguments optional and fix silent stream termination (#6309)
  fix: Improve error messages for invalid tool calls (#6483)
  fix: require auth when running goose on non loopback address (#6478)
  chore(deps): bump hono from 4.11.3 to 4.11.4 in /ui/desktop (#6485)
  feat(cli): graceful fallback for keyring failures (#5808)
  fix: support global .gooseignore and negation patterns (#6157)
  docs: manual config for jetbrains (#6490)
  fix: Recipe slash command doesn't work with single optional parameter (#6235)
  fix(openrouter): Handle Gemini thoughtSignature for tool calls (#6370)
  docs: fix extensions page (#6484)
  Allow customizing the new line keybinding in the CLI (#5956)
  Ask for permission in the CLI (#6475)
  docs: add Ralph Loop tutorial for multi-model iterative development (#6455)
  Remove gitignore fallback from gooseignore docs (#6480)
  fix: clean up result recording for code mode (#6343)
  fix(code_execution): handle model quirks with tool calls (#6352)
  feat(ui): support prefersBorder option for MCP Apps (#6465)
  fixed line breaks (#6459)
fbalicchia pushed a commit to fbalicchia/goose that referenced this pull request Jan 23, 2026
Signed-off-by: rabi <ramishra@redhat.com>
Signed-off-by: fbalicchia <fbalicchia@cuebiq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants