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
90
91
92
93
94
95
96
97
98
//! The two error surfaces of the tool layer: [`HandlerError`], which a tool's
//! own code returns, and [`ToolError`], which the type-erased dispatch layer
//! returns.
//!
//! Keeping them separate is the point. The runtime loop treats a bad
//! input from the model differently from a tool that ran and failed: the first
//! is fed back to the model so it can correct its arguments, the second is
//! recorded and surfaced per the effect's retry policy. That difference is
//! encoded as distinct [`ToolError`] variants, not left to string matching.
use Error;
/// The error a [`ToolHandler`](crate::ToolHandler) returns from its own code.
///
/// A handler is only ever called with an already-typed, already-validated
/// input, so it never has to report a schema mismatch. What it reports is a
/// genuine failure of the work it does: a provider rejected the request, a
/// precondition did not hold, and so on. This type carries a human-readable
/// message and an optional underlying source error.
///
/// The dispatch layer wraps a returned `HandlerError` in
/// [`ToolError::Handler`], tagging it with the tool name.
/// The error the type-erased dispatch layer
/// ([`DynTool::call_json`](crate::DynTool::call_json)) returns.
///
/// The variants are deliberately distinct so the runtime loop can route on them:
///
/// - [`ToolError::InvalidInput`] means the JSON the model produced did not
/// deserialize into the tool's `Input` type. The handler was **not** called.
/// The loop feeds this back to the model to let it fix its arguments.
/// - [`ToolError::Handler`] means the handler ran and returned a
/// [`HandlerError`]. This is a real execution failure, subject to the
/// effect's [retry policy](crate::RetryPolicy).
/// - [`ToolError::OutputSerialization`] means the handler succeeded but its
/// `Output` value could not be serialized to JSON. This is an internal fault
/// in the tool definition, not the model's doing and not a retryable failure.