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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//! **The loaded set** (REMOTE §5, bl-c907): which of a tool host's advertised
//! tools an agent has made callable, and the file that survives the step.
//!
//! REMOTE §5: *"Loading is the agent's own point-in-time act. From a `get`, the
//! agent loads a client's tools; loaded definitions are callable from that turn
//! on … the invariant is that nothing but an explicit load ever changes the
//! tool surface."*
//!
//! ```text
//! <yog-state-root>/loaded/<workspace>/<agent>.json
//! ```
//!
//! **It is durable because a driver is not.** Each step is a fresh process
//! (§2.11's exec baton), so a set held in RAM would be unloaded by the next
//! hop — the load act would last exactly one turn, which is not what "callable
//! from that turn on" says. It sits under yog's own state root rather than in
//! the workspace, because the workspace is the conversation's git repository
//! and a yog document does not belong in an agent's worktree.
//!
//! **The definition is frozen at the load act, not re-read at assembly.** The
//! file carries the whole advertised element — name, description, JSON Schema —
//! as it stood when the agent loaded it, so [`crate::tool_host::Injection::tools`]
//! is a pure local file read that needs no engine and cannot fail. That is the
//! REMOTE §5 rule (bl-bc7c) rather than a shortcut: *"definitions frozen in the
//! prefix, presence answered at invocation"*. A prefix that changed when a
//! client reconnected would put a connectivity-rate fact inside the model's
//! cached context, which is the whole defect §5 was amended to remove; and the
//! staleness that freezing admits is corrected where §5 already corrects it —
//! *"a client refuses a tool it no longer carries"*, in band, at the call.
//!
//! **The key is the agent, and there is no unload.** v1 offers no subtraction
//! and no inheritance: the set belongs to the agent that loaded it, so a fresh
//! conversation — and a freshly dispatched subagent — starts clean and loads
//! what it needs through the same `clients` tool every agent always has.
use io;
use ;
use ;
use cratestr_of;
use crate;
/// The loaded-set root's leaf under yog's state root.
pub const LOADED: &str = "loaded";
/// One loaded remote tool: the client that advertises it, and the definition
/// frozen as it read at the load act.
/// [`Eq`] for [`Tool`]'s own reason: a schema that came through a JSON decoder
/// cannot hold a `NaN`, so equality here is reflexive by construction.
/// True iff `name` is a name a provider will accept for a tool: ASCII letters,
/// digits, `_` and `-`, one to sixty-four of them. The advertised half is
/// already a path component (§5.1) and a client identity already is one, but
/// neither rules out the characters a tool block refuses — so the composed
/// name is checked once, here, and a load that cannot produce a callable name
/// declines naming it.
/// This agent's document. A workspace or agent that is not a plain path
/// component has no document — the same emptiness a fresh agent reads, rather
/// than a name that addresses the filesystem.
/// The set as JSON — one array, each element the advertised three facts with
/// the client beside them. The tool half is spelled by
/// [`tools::one`](crate::registry::tools::one), the same encoder the
/// advertisement and the boundary codec spend, so a stored definition and a
/// presented one cannot drift.
/// Read a set back strictly, naming the offending key — the advertisement's
/// own decode discipline, applied to yog's own document.
/// What this agent has loaded. A document that is absent, unreadable or
/// undecodable reads as the **empty set** — which is also what every agent
/// reads before its first load, so no reader carries two cases.
/// Add `entries` to this agent's set and answer the whole of it. Union by
/// presented name, later wins: re-loading a tool the client has re-advertised
/// refreshes the frozen definition, which is the only way a definition ever
/// changes (there is no unload, and no other writer).