You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Project the live tool registry onto the advertised set: the fixed built-in
144
145
// prefix (its order never changes — this is what keeps the provider cache
145
-
// prefix stable) followed by session-activated tools (MCP or otherwise) in
146
-
// first-activation order. The wire array is byte-stable turn to turn until a
147
-
// discovery appends a new name, at which point it grows once and then holds
148
-
// steady again. `activated` is expected to already be deduped/ordered (see
146
+
// prefix stable) followed by wire-committed tools (MCP or otherwise) in
147
+
// first-commit order. The wire array is byte-stable turn to turn: callers pass
148
+
// only names committed via flushPromotions at a cache-safe boundary, never the
149
+
// live activation list, so a mid-session discovery cannot append here.
150
+
// `activated` is expected to already be deduped/ordered (see
149
151
// `createActivatedToolTracker`), but names are deduped again here defensively
150
152
// so a caller passing raw matches still can't reorder or duplicate an entry.
151
153
exportfunctionadvertisedTools(
@@ -209,7 +211,7 @@ export function createActivatedToolTracker(): ActivatedToolTracker {
209
211
exportconsttoolSearchDefinition: ToolDefinition={
210
212
name: "tool_search",
211
213
description:
212
-
"Discover callable tools by capability. Most tools — MCP servers, present, and other integrations — are not advertised until this search promotes them onto the wire. Core tools (read_file, run_shell, web_fetch, web_search, spawn_agent, …) are already on the wire — do not tool_search for them. wait_agents is mounted on exec-primary runs only, so it is not on the wire elsewhere and this search cannot promote it there. Call this with a short description of what you need (e.g. 'issue tracker', 'render layout', 'granola notes') to get matching tools' names, descriptions, and input schemas. Matched tools are promoted and callable on return — invoke them directly, no separate load step.",
214
+
"Discover callable tools by capability. Most tools — MCP servers, present, and other integrations — are not callable until this search promotes them. Core tools (read_file, run_shell, web_fetch, web_search, spawn_agent, …) are already on the wire — do not tool_search for them. wait_agents is mounted on exec-primary runs only, so it is not on the wire elsewhere and this search cannot promote it there. Call this with a short description of what you need (e.g. 'issue tracker', 'render layout', 'granola notes') to get matching tools' names, descriptions, and input schemas. Matched tools are promoted and callable on return — invoke them directly, no separate load step.",
213
215
inputSchema: {
214
216
type: "object",
215
217
properties: {
@@ -283,9 +285,9 @@ export function createToolIndex(
283
285
exportinterfaceToolSearchDeps{
284
286
search: (query: string)=>string[];
285
287
lookup: (name: string)=>ToolDefinition|undefined;
286
-
// Promote matches onto the advertised set and the call gate so the model can
287
-
// invoke them this turn. The next inference also declares them on the wire
288
-
// for strict providers.
288
+
// Promote matches onto the call gate so the model can invoke them this turn
289
+
// from the result card's schema. Wire declaration follows at the next
290
+
// cache-safe boundary (compaction fold), never mid-thread.
289
291
promote: (names: string[])=>void;
290
292
// Resolves to the remaining in-flight MCP handshake count after waiting up
291
293
// to `timeoutMs`. The toolset bounds its own wait; the handler re-races
@@ -374,12 +376,12 @@ export function createToolSearchTool(deps: ToolSearchDeps): AgentTool {
374
376
if(names.length===0){
375
377
return`No tools matched "${query}". Try different keywords describing the capability.`;
376
378
}
377
-
// Matches are promoted into the advertised set so the next inference
378
-
// declares them on the wire — required for strict providers (e.g. the grok
379
-
// Responses API) where a model cannot call a tool that was never declared.
380
-
// The tool result below still carries name, description, AND input schema
381
-
// so the model can shape arguments this same turn, before the promoted
382
-
// definition round-trips through the next infer call.
379
+
// Matches open on the call gate at once; the full schema joins the wire
380
+
// declarations at the next cache-safe boundary (compaction fold), never
381
+
// mid-thread, so the provider's cached prefix stays byte-stable. The
382
+
// tool result below still carries name, description, AND input schema
383
+
// so the model can shape arguments and call this same turn, before the
0 commit comments