inferd_proto/v2/tool.rs
1//! v2 tool definitions and tool-call-id strong type.
2//!
3//! Per ADR 0015 ยง"v2 Tool definition". Mirrors Anthropic's tool-use
4//! shape: name + free-form description + JSON Schema input
5//! descriptor. The daemon's chat-templating layer wraps these into
6//! whatever per-engine sequence the model expects (Gemma 4's
7//! `<|tool_call>...<tool_call|>` sequence in the v0.2 default
8//! adapter).
9
10use serde::{Deserialize, Serialize};
11use serde_json::Value;
12
13/// Strong type around the string id that pairs an `assistant`-emitted
14/// `tool_use` block with the matching `tool_result` block in the
15/// consumer's follow-up request. Wrapping it lets the daemon ensure
16/// the round-trip uses the same id and lets middleware authors avoid
17/// passing raw `String` for ids.
18#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
19#[serde(transparent)]
20pub struct ToolCallId(pub String);
21
22impl ToolCallId {
23 /// Borrow the inner string.
24 pub fn as_str(&self) -> &str {
25 &self.0
26 }
27}
28
29impl From<String> for ToolCallId {
30 fn from(s: String) -> Self {
31 Self(s)
32 }
33}
34
35impl From<&str> for ToolCallId {
36 fn from(s: &str) -> Self {
37 Self(s.to_owned())
38 }
39}
40
41/// Free-form JSON object representing a tool's invocation arguments.
42///
43/// Type-aliased to `serde_json::Value` deliberately: the daemon does
44/// not enforce the consumer's `Tool::input_schema` (that's the
45/// consumer's responsibility before executing the tool). The daemon
46/// guarantees only that the model's emitted JSON parses; semantic
47/// validation lives in the consumer.
48pub type ToolUseInput = Value;
49
50/// One tool definition in the request's top-level `tools[]` table.
51///
52/// `name` must be unique within a request. The model can emit a
53/// `tool_use` content block referencing exactly this name; the
54/// daemon's chat-templating layer is responsible for shaping the
55/// definition into the format the active engine expects.
56#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
57pub struct Tool {
58 /// Caller-chosen name; unique within the enclosing request.
59 pub name: String,
60 /// Free-form description shown to the model so it can decide whether
61 /// to call this tool.
62 pub description: String,
63 /// JSON Schema for the tool's input. The daemon does not enforce
64 /// this; it's documentation for the model and validation surface
65 /// for the consumer when the result comes back.
66 pub input_schema: Value,
67}