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
constDEFERRED_TOOL_LISTING_GUIDANCE:&str = r#"Their definitions are not loaded at the start of the conversation.
19
-
You must obtain the tool definition using GetToolSpec before you first invoke a deferred tool. Once its definition is available in the conversation, you can call it through CallDeferredTool.
19
+
Use GetToolSpec to read a deferred tool's full definition before invoking it through CallDeferredTool. Reuse it while the successful GetToolSpec result remains in the current context. If compaction or truncation removed that result, load it again; a summary or a past call does not keep the definition loaded.
20
20
Each entry below is a deferred tool name with an optional short description."#;
.contains("Their definitions are not loaded at the start of the conversation."));
72
72
assert!(deferred_tool_listing
73
-
.contains("You must obtain the tool definition using GetToolSpec before you first invoke a deferred tool."));
73
+
.contains("Use GetToolSpec to read a deferred tool's full definition before invoking it through CallDeferredTool."));
74
74
assert!(deferred_tool_listing.contains(
75
-
"Once its definition is available in the conversation, you can call it through CallDeferredTool."
75
+
"Reuse it while the successful GetToolSpec result remains in the current context."
76
+
));
77
+
assert!(deferred_tool_listing.contains(
78
+
"If compaction or truncation removed that result, load it again; a summary or a past call does not keep the definition loaded."
76
79
));
77
80
assert!(deferred_tool_listing
78
81
.contains("Each entry below is a deferred tool name with an optional short description."));
79
82
assert!(deferred_tool_listing.contains(
80
83
"## Direct tools\nTheir definitions are already available. You can call them directly.\nEach entry below is a directly callable tool name.\n\n<direct_tools>\n- Read\n- GetToolSpec\n- CallDeferredTool\n</direct_tools>"
81
84
));
82
85
assert!(deferred_tool_listing.contains(
83
-
"## Deferred tools\nTheir definitions are not loaded at the start of the conversation.\nYou must obtain the tool definition using GetToolSpec before you first invoke a deferred tool. Once its definition is available in the conversation, you can call it through CallDeferredTool."
86
+
"## Deferred tools\nTheir definitions are not loaded at the start of the conversation.\nUse GetToolSpec"
r#"Call a deferred tool after reading its full schema with GetToolSpec.
82
82
83
+
The full GetToolSpec result must still be visible in the current context. If compaction or truncation removed it, reload it with GetToolSpec first; a summary or a past call is not a loaded definition.
83
84
Pass the exact deferred tool name in tool_name and put only that tool's arguments inside args.
84
85
The order is important. ALWAYS output tool_name first, then args."#
Copy file name to clipboardExpand all lines: src/crates/execution/tool-contracts/src/framework.rs
+8-3Lines changed: 8 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -91,7 +91,7 @@ impl fmt::Display for DeferredToolUsageError {
91
91
get_tool_spec_tool_name,
92
92
} => write!(
93
93
formatter,
94
-
"Tool '{tool_name}' is deferred. Call {get_tool_spec_tool_name} first with {{\"tool_name\":\"{tool_name}\"}} to read its full usage instructions and input schema before invoking it."
94
+
"Tool '{tool_name}' has no loaded definition in the current context. Call {get_tool_spec_tool_name} with {{\"tool_name\":\"{tool_name}\"}} to read its full usage instructions and input schema before invoking it. If compaction removed an earlier definition, reload it even if the summary says it was loaded."
r#"Read the full schema before first calling a deferred tool through CallDeferredTool.
373
373
374
-
Do not call GetToolSpec again for a tool whose definition is already loaded in the current conversation."#
374
+
Do not call GetToolSpec again while its successful result with the full definition is still visible in the current context.
375
+
If compaction or truncation removed that result, call GetToolSpec again before using CallDeferredTool. A summary mentioning a previously loaded tool or a past successful call does not load its definition. Reload also when the runtime reports a stale definition."#
"Tool '{}' is already loaded in the current conversation. Do not call GetToolSpec again for it. Use CallDeferredTool with tool_name '{}' and put the tool arguments inside args.",
443
+
"Tool '{}' is already loaded in the current context. Use CallDeferredTool with tool_name '{}' and put the tool arguments inside args. Reload with GetToolSpec only if its full definition leaves the context or the runtime reports it stale.",
443
444
tool_name, tool_name
444
445
)
445
446
}
@@ -2688,6 +2689,10 @@ mod tests {
2688
2689
2689
2690
assert!(description.contains("Read the full schema"));
2690
2691
assert!(description.contains("Do not call GetToolSpec again"));
2692
+
assert!(description.contains("full definition is still visible in the current context"));
2693
+
assert!(description
2694
+
.contains("If compaction or truncation removed that result, call GetToolSpec again"));
2695
+
assert!(description.contains("does not load its definition"));
.expect_err("deferred tool should require GetToolSpec unlock");
1471
1473
assert_eq!(
1472
1474
err.to_string(),
1473
-
"Tool 'WebFetch' is deferred. Call GetToolSpec first with {\"tool_name\":\"WebFetch\"} to read its full usage instructions and input schema before invoking it."
1475
+
"Tool 'WebFetch' has no loaded definition in the current context. Call GetToolSpec with {\"tool_name\":\"WebFetch\"} to read its full usage instructions and input schema before invoking it. If compaction removed an earlier definition, reload it even if the summary says it was loaded."
1474
1476
);
1475
1477
1476
1478
let loaded_deferred_tool_specs = vec![LoadedDeferredToolSpec{
"Tool 'WebFetch' is already loaded in the current conversation. Do not call GetToolSpec again for it. Use CallDeferredTool with tool_name 'WebFetch' and put the tool arguments inside args."
2035
+
"Tool 'WebFetch' is already loaded in the current context. Use CallDeferredTool with tool_name 'WebFetch' and put the tool arguments inside args. Reload with GetToolSpec only if its full definition leaves the context or the runtime reports it stale."
"Tool 'WebFetch' is already loaded in the current conversation. Do not call GetToolSpec again for it. Use CallDeferredTool with tool_name 'WebFetch' and put the tool arguments inside args."
2057
+
"Tool 'WebFetch' is already loaded in the current context. Use CallDeferredTool with tool_name 'WebFetch' and put the tool arguments inside args. Reload with GetToolSpec only if its full definition leaves the context or the runtime reports it stale."
"Tool 'WebFetch' is already loaded in the current conversation. Do not call GetToolSpec again for it. Use CallDeferredTool with tool_name 'WebFetch' and put the tool arguments inside args."
3344
+
"Tool 'WebFetch' is already loaded in the current context. Use CallDeferredTool with tool_name 'WebFetch' and put the tool arguments inside args. Reload with GetToolSpec only if its full definition leaves the context or the runtime reports it stale."
0 commit comments