Skip to content

dynamic tool calls: add param exposeToContext to optionally hide tool#14501

Merged
cconger merged 6 commits intomainfrom
cconger/hidden-dynamic-tools
Mar 14, 2026
Merged

dynamic tool calls: add param exposeToContext to optionally hide tool#14501
cconger merged 6 commits intomainfrom
cconger/hidden-dynamic-tools

Conversation

@cconger
Copy link
Contributor

@cconger cconger commented Mar 12, 2026

This extends dynamic_tool_calls to allow us to hide a tool from the model context but still use it as part of the general tool calling runtime (for ex from js_repl/code_mode)

@cconger cconger requested a review from pakrym-oai March 12, 2026 19:30
@cconger cconger force-pushed the cconger/hidden-dynamic-tools branch from 8a39ba4 to db304ca Compare March 12, 2026 20:19
let hidden_dynamic_tools = turn_context
.dynamic_tools
.iter()
.filter(|tool| !tool.expose_to_context)
Copy link
Collaborator

Choose a reason for hiding this comment

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

we call this defer_loading elsewhere should we go with the same name?

.filter(|tool| !tool.expose_to_context)
.map(|tool| tool.name.as_str())
.collect::<HashSet<_>>();
let tools = if hidden_dynamic_tools.is_empty() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we need to filter them out or just set defer_loading on them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They're not callable as remote tools so I would prefer not to even expose them to responses but maybe I'm missing something here.

.bind(tool.name.as_str())
.bind(tool.description.as_str())
.bind(input_schema)
.bind(tool.expose_to_context)
Copy link
Collaborator

Choose a reason for hiding this comment

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

what happens when a model decides to run a stored tool that isn't registered anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I think this is an existing bug/problem with dynamic tool calls either way right now. Without a registry with lifecycles we're just trusting that there's a listener for the dynamic tool call for the resumer too.

Copy link
Collaborator

@pakrym-oai pakrym-oai left a comment

Choose a reason for hiding this comment

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

Consider renaming to defer_loading

@cconger cconger force-pushed the cconger/hidden-dynamic-tools branch 2 times, most recently from c54532f to 16f0e7f Compare March 13, 2026 20:10
cconger added 6 commits March 14, 2026 01:34
This extends dynamic_tool_calls to allow us to hide a tool from the
model context but still use it as part of the general tool calling
runtime/harness. (For ex from js_repl/code_mode).
@cconger cconger force-pushed the cconger/hidden-dynamic-tools branch from 16f0e7f to f70b13c Compare March 14, 2026 08:35
@cconger
Copy link
Contributor Author

cconger commented Mar 14, 2026

@codex review

Copy link
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f70b13cac9

ℹ️ 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".

router
.model_visible_specs()
.into_iter()
.filter(|spec| !deferred_dynamic_tools.contains(spec.name()))
Copy link
Contributor

Choose a reason for hiding this comment

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

P2 Badge Filter deferred tools by origin, not by name

build_prompt removes every model-visible spec whose name matches a deferred dynamic tool. If a deferred dynamic tool shares a name with a built-in/MCP tool, this line drops the unrelated tool from the prompt as well. That can silently disable expected tool access for the model, exceeding the intended “hide this dynamic tool” behavior.

Useful? React with 👍 / 👎.

@cconger cconger merged commit 70eddad into main Mar 14, 2026
37 of 40 checks passed
@cconger cconger deleted the cconger/hidden-dynamic-tools branch March 14, 2026 08:58
@github-actions github-actions bot locked and limited conversation to collaborators Mar 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants