1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Known transitive dependency version duplicates intentionally kept:
// bitflags 1.x/2.x, thiserror 1.x/2.x, phf 0.11/0.13, rand 0.8/0.9, etc.
// These cannot be unified without breaking upstream crates.
// The tool-description schemas are single `serde_json::json!` macros with
// deep `allOf`/`anyOf` nesting (computer_control carries the deepest) —
// the default 128 recursion limit overflows while expanding them.
// TOOL DESCRIPTION CONVENTION (applies to every tool in this crate)
//
// A tool description tells the model HOW to use the tool and WHEN to reach
// for it. It never explains the tool's internals. Do not document
// implementation details in descriptions — no dispatch modes, engine names,
// internal batching or fallback behavior, error-handling strategy, or
// "one file per call" style rules that the input schema already expresses
// structurally (a flat {path, content} schema says it plainly). The model
// gets the advertised schema and the description; anything the schema can
// communicate on its own belongs to the schema, not to prose.
//
// What belongs in a description:
// - what the tool does, in direct language ("Write content to one file")
// - required usage the schema cannot enforce by itself (e.g. "you MUST
// include the `file_hash` from a previous read before overwriting")
// - useful cases and disambiguation vs. sibling tools
//
// What does NOT belong:
// - how the tool works internally (engines, modes, dispatch, fallbacks)
// - rules that restate the schema's structure in words
// - history or rationale ("we changed this from X because Y") — that lives
// in code comments and commit messages, where maintainers will find it
//
// When a model misuses a tool, correct it at the rejection site with a
// targeted, actionable message; do not pre-pollute every session's context
// with instructions guarding against a mistake most sessions never make.
/// MCP Tool description: name, description, and inputSchema as a JSON value.
/// Follows the [MCP Tool schema](https://modelcontextprotocol.io/specification/2025-11-25/server/tools)
/// so it can be passed directly to an rmcp server in the future.
/// Structure: `{ "name": string, "description": string, "inputSchema": { ... } }`
pub type ToolDescription = Value;
pub const TOOL_FORMAT: &str = concat!;
/// Native function-calling instruction for providers that MUST use their
/// structured tool mechanism instead of inline JSON text.
///
/// Gemini 3.x models obey the legacy inline-JSON `TOOL_FORMAT` literally:
/// with it in the prompt they emit tool calls as raw TEXT frames (`{"name":
/// "fs_read", ...}`) even when the request also carries `toolConfig AUTO` —
/// the API then rejects the turn with `MALFORMED_FUNCTION_CALL` and stray
/// fragments (`}`) plus reasoning text leak to the user. The harness selects
/// this variant when the active provider is Gemini (OpenAI/Claude ignore the
/// inline instruction and use their native mechanism regardless).
pub const TOOL_FORMAT_NATIVE: &str = concat!;