diff --git a/crates/tinytools-agent/src/dialect/test.rs b/crates/tinytools-agent/src/dialect/test.rs index 5e51eae..0d96011 100644 --- a/crates/tinytools-agent/src/dialect/test.rs +++ b/crates/tinytools-agent/src/dialect/test.rs @@ -835,3 +835,17 @@ fn json_call_rendering_round_trips_through_the_parser() { assert_eq!(calls[0].arguments["path"], "a.txt"); assert_eq!(calls[1].arguments, serde_json::json!({})); } + +#[test] +fn native_instructions_allow_a_lead_in_but_require_the_call_in_the_same_message() { + let text = crate::render::native_instructions(); + assert!(text.contains("same message"), "{text}"); + assert!( + text.contains("never end a turn on an announcement"), + "{text}" + ); + // The old wording read as a ban on any lead-in text, which stopped models + // from streaming a one-line "looking that up" before their tool calls. + assert!(!text.contains("Let me check"), "{text}"); + assert!(!text.contains("narrate intent"), "{text}"); +} diff --git a/crates/tinytools-agent/src/render/instructions.rs b/crates/tinytools-agent/src/render/instructions.rs index 9438016..9406c38 100644 --- a/crates/tinytools-agent/src/render/instructions.rs +++ b/crates/tinytools-agent/src/render/instructions.rs @@ -71,9 +71,9 @@ pub fn native_instructions() -> String { [ "## Tool Use Protocol", "", - "When a tool is needed, emit tool calls directly via the model's native tool-calling output.", - "Do not only narrate intent (for example, avoid \"Let me check...\") without emitting the tool call.", - "After tool results are provided, continue reasoning and then produce the final answer.", + "When you need a tool, call it in this response through native tool-calling.", + "A short line saying what you are about to do is fine, but the tool call must be in the same message; never end a turn on an announcement.", + "After the results arrive, keep going until you can give the final answer.", "", ] .join("\n")