Dispatch tools when code mode is not awaited directly#14437
Conversation
c472815 to
9c4ffb8
Compare
codex-rs/core/src/tools/code_mode.rs
Outdated
| section.push_str("- Import nested tools from `tools.js`, for example `import { exec_command } from \"tools.js\"` or `import { ALL_TOOLS } from \"tools.js\"` to inspect the available `{ module, name, description }` entries. Namespaced tools are also available from `tools/<namespace...>.js`; MCP tools use `tools/mcp/<server>.js`, for example `import { append_notebook_logs_chart } from \"tools/mcp/ologs.js\"`. Nested tool calls resolve to their code-mode result values.\n"); | ||
| section.push_str(&format!( | ||
| "- Import `{{ output_text, output_image, set_max_output_tokens_per_exec_call, set_yield_time, store, load }}` from `@openai/code_mode` (or `\"openai/code_mode\"`). `output_text(value)` surfaces text back to the model and stringifies non-string objects with `JSON.stringify(...)` when possible. `output_image(imageUrl)` appends an `input_image` content item for `http(s)` or `data:` URLs. `store(key, value)` persists JSON-serializable values across `{PUBLIC_TOOL_NAME}` calls in the current session, and `load(key)` returns a cloned stored value or `undefined`. `set_max_output_tokens_per_exec_call(value)` sets the token budget used to truncate direct `{PUBLIC_TOOL_NAME}` returns; `{WAIT_TOOL_NAME}` uses its own `max_tokens` argument instead and defaults to `10000`. `set_yield_time(value)` asks `{PUBLIC_TOOL_NAME}` to return early if the script is still running after that many milliseconds so `{WAIT_TOOL_NAME}` can resume it later. The returned content starts with a separate `Script completed`, `Script failed`, or `Script running with session ID …` text item that includes wall time. When truncation happens, the final text may include `Total output lines:` and the usual `…N tokens truncated…` marker.\n", | ||
| "- Import `{{ output_text, output_image, set_max_output_tokens_per_exec_call, set_yield_time, store, load, yield_control }}` from `@openai/code_mode` (or `\"openai/code_mode\"`). `output_text(value)` surfaces text back to the model and stringifies non-string objects with `JSON.stringify(...)` when possible. `output_image(imageUrl)` appends an `input_image` content item for `http(s)` or `data:` URLs. `store(key, value)` persists JSON-serializable values across `{PUBLIC_TOOL_NAME}` calls in the current session, and `load(key)` returns a cloned stored value or `undefined`. `set_max_output_tokens_per_exec_call(value)` sets the token budget used to truncate direct `{PUBLIC_TOOL_NAME}` returns; `{WAIT_TOOL_NAME}` uses its own `max_tokens` argument instead and defaults to `10000`. `set_yield_time(value)` asks `{PUBLIC_TOOL_NAME}` to return early if the script is still running after that many milliseconds so `{WAIT_TOOL_NAME}` can resume it later. `yield_control()` returns a yielded `{PUBLIC_TOOL_NAME}` response immediately while the script keeps running in the background. The returned content starts with a separate `Script completed`, `Script failed`, or `Script running with session ID …` text item that includes wall time. When truncation happens, the final text may include `Total output lines:` and the usual `…N tokens truncated…` marker.\n", |
There was a problem hiding this comment.
I'm realizing that yield doesn't actually feel quite right here, its more about "detaching" focus or backgrounding. The yield is actually just fire and forget and has no impact on the control flow in repl. This is all the more apparent when we're allowing tool calls to run backgrounded too.
cconger
left a comment
There was a problem hiding this comment.
Naming nit, curious your thoughts.
codex-rs/core/src/tools/code_mode.rs
Outdated
| tool_call.name, | ||
| tool_call.input, | ||
| ) | ||
| .await, |
There was a problem hiding this comment.
We actually have head of line blocking here in this loop. Since our tool calls are async its possible that multiple could be in flight from js at a time, and here we are serially executing so a slow one blocks the rest.
There was a problem hiding this comment.
Its even more exacerbated by this being shared across the process.
There was a problem hiding this comment.
I agree but one step at a time. Want to keep individual changes small.
Summary
Testing