@te-river/opencode-team-mode 1.5.15 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/README.md +853 -690
  2. package/README.zh-CN.md +761 -631
  3. package/dist/agents.d.ts +5 -3
  4. package/dist/agents.d.ts.map +1 -1
  5. package/dist/agents.js +19 -8
  6. package/dist/agents.js.map +1 -1
  7. package/dist/capabilities.d.ts +1 -1
  8. package/dist/capabilities.js +2 -2
  9. package/dist/capabilities.js.map +1 -1
  10. package/dist/host/note.d.ts +7 -0
  11. package/dist/host/note.d.ts.map +1 -0
  12. package/dist/host/note.js +28 -0
  13. package/dist/host/note.js.map +1 -0
  14. package/dist/host/v1.d.ts +14 -0
  15. package/dist/host/v1.d.ts.map +1 -0
  16. package/dist/host/v1.js +340 -0
  17. package/dist/host/v1.js.map +1 -0
  18. package/dist/host/v2-browser-gate.d.ts +45 -0
  19. package/dist/host/v2-browser-gate.d.ts.map +1 -0
  20. package/dist/host/v2-browser-gate.js +319 -0
  21. package/dist/host/v2-browser-gate.js.map +1 -0
  22. package/dist/host/v2-capabilities.d.ts +68 -0
  23. package/dist/host/v2-capabilities.d.ts.map +1 -0
  24. package/dist/host/v2-capabilities.js +146 -0
  25. package/dist/host/v2-capabilities.js.map +1 -0
  26. package/dist/host/v2-client.d.ts +53 -0
  27. package/dist/host/v2-client.d.ts.map +1 -0
  28. package/dist/host/v2-client.js +193 -0
  29. package/dist/host/v2-client.js.map +1 -0
  30. package/dist/host/v2-events.d.ts +56 -0
  31. package/dist/host/v2-events.d.ts.map +1 -0
  32. package/dist/host/v2-events.js +158 -0
  33. package/dist/host/v2-events.js.map +1 -0
  34. package/dist/host/v2-guard.d.ts +101 -0
  35. package/dist/host/v2-guard.d.ts.map +1 -0
  36. package/dist/host/v2-guard.js +199 -0
  37. package/dist/host/v2-guard.js.map +1 -0
  38. package/dist/host/v2-offload.d.ts +148 -0
  39. package/dist/host/v2-offload.d.ts.map +1 -0
  40. package/dist/host/v2-offload.js +288 -0
  41. package/dist/host/v2-offload.js.map +1 -0
  42. package/dist/host/v2-permissions.d.ts +123 -0
  43. package/dist/host/v2-permissions.d.ts.map +1 -0
  44. package/dist/host/v2-permissions.js +190 -0
  45. package/dist/host/v2-permissions.js.map +1 -0
  46. package/dist/host/v2-probe.d.ts +85 -0
  47. package/dist/host/v2-probe.d.ts.map +1 -0
  48. package/dist/host/v2-probe.js +268 -0
  49. package/dist/host/v2-probe.js.map +1 -0
  50. package/dist/host/v2-scope.d.ts +51 -0
  51. package/dist/host/v2-scope.d.ts.map +1 -0
  52. package/dist/host/v2-scope.js +58 -0
  53. package/dist/host/v2-scope.js.map +1 -0
  54. package/dist/host/v2-session-client.d.ts +74 -0
  55. package/dist/host/v2-session-client.d.ts.map +1 -0
  56. package/dist/host/v2-session-client.js +171 -0
  57. package/dist/host/v2-session-client.js.map +1 -0
  58. package/dist/host/v2-session.d.ts +85 -0
  59. package/dist/host/v2-session.d.ts.map +1 -0
  60. package/dist/host/v2-session.js +171 -0
  61. package/dist/host/v2-session.js.map +1 -0
  62. package/dist/host/v2-subagent.d.ts +157 -0
  63. package/dist/host/v2-subagent.d.ts.map +1 -0
  64. package/dist/host/v2-subagent.js +286 -0
  65. package/dist/host/v2-subagent.js.map +1 -0
  66. package/dist/host/v2-tool.d.ts +67 -0
  67. package/dist/host/v2-tool.d.ts.map +1 -0
  68. package/dist/host/v2-tool.js +209 -0
  69. package/dist/host/v2-tool.js.map +1 -0
  70. package/dist/host/v2-transcript.d.ts +73 -0
  71. package/dist/host/v2-transcript.d.ts.map +1 -0
  72. package/dist/host/v2-transcript.js +151 -0
  73. package/dist/host/v2-transcript.js.map +1 -0
  74. package/dist/host/v2-types.d.ts +229 -0
  75. package/dist/host/v2-types.d.ts.map +1 -0
  76. package/dist/host/v2-types.js +17 -0
  77. package/dist/host/v2-types.js.map +1 -0
  78. package/dist/host/v2.d.ts +42 -0
  79. package/dist/host/v2.d.ts.map +1 -0
  80. package/dist/host/v2.js +706 -0
  81. package/dist/host/v2.js.map +1 -0
  82. package/dist/host-hooks.d.ts +13 -2
  83. package/dist/host-hooks.d.ts.map +1 -1
  84. package/dist/host-hooks.js +18 -5
  85. package/dist/host-hooks.js.map +1 -1
  86. package/dist/index.d.ts +23 -17
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +29 -326
  89. package/dist/index.js.map +1 -1
  90. package/dist/prompts/lead.d.ts +1 -1
  91. package/dist/prompts/lead.d.ts.map +1 -1
  92. package/dist/prompts/lead.js +452 -359
  93. package/dist/prompts/lead.js.map +1 -1
  94. package/dist/prompts/shared.d.ts +2 -2
  95. package/dist/prompts/shared.d.ts.map +1 -1
  96. package/dist/prompts/shared.js +89 -17
  97. package/dist/prompts/shared.js.map +1 -1
  98. package/dist/prompts/specialists.d.ts +2 -2
  99. package/dist/prompts/specialists.d.ts.map +1 -1
  100. package/dist/prompts/specialists.js +44 -10
  101. package/dist/prompts/specialists.js.map +1 -1
  102. package/dist/task-offload.d.ts +83 -0
  103. package/dist/task-offload.d.ts.map +1 -0
  104. package/dist/task-offload.js +174 -0
  105. package/dist/task-offload.js.map +1 -0
  106. package/dist/tm/args-schema.d.ts +4 -0
  107. package/dist/tm/args-schema.d.ts.map +1 -1
  108. package/dist/tm/args-schema.js +36 -3
  109. package/dist/tm/args-schema.js.map +1 -1
  110. package/dist/tm/board.d.ts +113 -0
  111. package/dist/tm/board.d.ts.map +1 -0
  112. package/dist/tm/board.js +275 -0
  113. package/dist/tm/board.js.map +1 -0
  114. package/dist/tm/browser.d.ts +325 -6
  115. package/dist/tm/browser.d.ts.map +1 -1
  116. package/dist/tm/browser.js +1360 -135
  117. package/dist/tm/browser.js.map +1 -1
  118. package/dist/tm/config.d.ts +36 -25
  119. package/dist/tm/config.d.ts.map +1 -1
  120. package/dist/tm/config.js +29 -7
  121. package/dist/tm/config.js.map +1 -1
  122. package/dist/tm/dispatch.d.ts +133 -53
  123. package/dist/tm/dispatch.d.ts.map +1 -1
  124. package/dist/tm/dispatch.js +481 -279
  125. package/dist/tm/dispatch.js.map +1 -1
  126. package/dist/tm/dupe-guard.d.ts +16 -3
  127. package/dist/tm/dupe-guard.d.ts.map +1 -1
  128. package/dist/tm/dupe-guard.js +27 -7
  129. package/dist/tm/dupe-guard.js.map +1 -1
  130. package/dist/tm/egress.d.ts +44 -0
  131. package/dist/tm/egress.d.ts.map +1 -0
  132. package/dist/tm/egress.js +191 -0
  133. package/dist/tm/egress.js.map +1 -0
  134. package/dist/tm/guard.js +1 -1
  135. package/dist/tm/guard.js.map +1 -1
  136. package/dist/tm/index.d.ts +67 -2
  137. package/dist/tm/index.d.ts.map +1 -1
  138. package/dist/tm/index.js +228 -20
  139. package/dist/tm/index.js.map +1 -1
  140. package/dist/tm/ledger.d.ts +114 -0
  141. package/dist/tm/ledger.d.ts.map +1 -0
  142. package/dist/tm/ledger.js +308 -0
  143. package/dist/tm/ledger.js.map +1 -0
  144. package/dist/tm/perm-ask.d.ts +45 -5
  145. package/dist/tm/perm-ask.d.ts.map +1 -1
  146. package/dist/tm/perm-ask.js +107 -7
  147. package/dist/tm/perm-ask.js.map +1 -1
  148. package/dist/tm/pipelines.d.ts.map +1 -1
  149. package/dist/tm/pipelines.js +24 -2
  150. package/dist/tm/pipelines.js.map +1 -1
  151. package/dist/tm/preview.d.ts +55 -0
  152. package/dist/tm/preview.d.ts.map +1 -1
  153. package/dist/tm/preview.js +225 -0
  154. package/dist/tm/preview.js.map +1 -1
  155. package/dist/tm/ptc/tool.d.ts.map +1 -1
  156. package/dist/tm/ptc/tool.js +2 -4
  157. package/dist/tm/ptc/tool.js.map +1 -1
  158. package/dist/tm/pty.d.ts.map +1 -1
  159. package/dist/tm/pty.js +6 -3
  160. package/dist/tm/pty.js.map +1 -1
  161. package/dist/tm/search.d.ts +5 -0
  162. package/dist/tm/search.d.ts.map +1 -1
  163. package/dist/tm/search.js +40 -8
  164. package/dist/tm/search.js.map +1 -1
  165. package/dist/tm/serp-loop.d.ts +45 -0
  166. package/dist/tm/serp-loop.d.ts.map +1 -0
  167. package/dist/tm/serp-loop.js +80 -0
  168. package/dist/tm/serp-loop.js.map +1 -0
  169. package/dist/tm/stats.d.ts +26 -0
  170. package/dist/tm/stats.d.ts.map +1 -1
  171. package/dist/tm/stats.js +194 -4
  172. package/dist/tm/stats.js.map +1 -1
  173. package/dist/tm/webfetch.d.ts +56 -0
  174. package/dist/tm/webfetch.d.ts.map +1 -1
  175. package/dist/tm/webfetch.js +187 -19
  176. package/dist/tm/webfetch.js.map +1 -1
  177. package/dist/tool-coerce.d.ts +24 -0
  178. package/dist/tool-coerce.d.ts.map +1 -0
  179. package/dist/tool-coerce.js +63 -0
  180. package/dist/tool-coerce.js.map +1 -0
  181. package/dist/types.d.ts +7 -1
  182. package/dist/types.d.ts.map +1 -1
  183. package/docs/installation-v2.md +436 -0
  184. package/docs/installation.md +81 -2
  185. package/docs/research/agent-data-exchange.md +117 -0
  186. package/docs/research/browser-pane.md +89 -0
  187. package/docs/research/host-http-api.md +132 -0
  188. package/docs/research/host-subagent-injection.md +187 -0
  189. package/docs/research/plugin-loader-contract.md +261 -0
  190. package/docs/research/v2-builtin-tools.md +447 -0
  191. package/docs/v2-port-notes.md +315 -0
  192. package/index.js +7 -0
  193. package/package.json +4 -1
  194. package/scripts/gen-v2-config.mjs +304 -0
  195. package/scripts/lib/config-surgery.cjs +239 -0
  196. package/scripts/lib/fake-ctx.mjs +146 -0
@@ -0,0 +1,286 @@
1
+ /**
2
+ * The v2 host's own sub-agents, made collectable by `tm_join` (decision 4, 2026-09-26).
3
+ *
4
+ * What was broken: on v2 every dispatch goes through the host's `subagent` tool (v1's
5
+ * `tm_dispatch` is gone and the plugin forces `background:true`), so the child session
6
+ * was never entered into `tm_join`'s registry. `tm_join` then answered 没有待收集的派发
7
+ * about work that was running on screen, a wait could never end, and the lead had to
8
+ * re-read the round from the injected message like a person paging through mail. The
9
+ * event feed added in 1.7.x made this worse in the specific way goal #6 refuses: the
10
+ * dispatcher ignores a session id it has no record of, so a settled child produced
11
+ * silence that read as "nothing to report".
12
+ *
13
+ * Why these two hooks and not a session query: the v2 plugin ctx has no
14
+ * `session.children` and our `ctx.session.get` bridge has never resolved a shape on a
15
+ * live host, so a tree walk is not available. What IS available is measured, from the
16
+ * user's own desktop session (`docs/research/host-subagent-injection.md`):
17
+ *
18
+ * execute.before subagent {agent, background, description, prompt}
19
+ * execute.after result.metadata = {sessionID:"ses_…", status:"running", truncated:false}
20
+ * result text "The subagent is working in the background
21
+ * (sessionID: ses_…). You will be notified…"
22
+ * later, as a message the plugin never sees as a tool result:
23
+ * metadata {source:"subagent", childID:"ses_…", agent, state}
24
+ * text <subagent sessionID="ses_…" state="completed" …>body</subagent>
25
+ *
26
+ * So the before hook supplies who and what-for, the after hook supplies the child's id,
27
+ * and the pairing is per CALLER session — a lead that fires three dispatches in one round
28
+ * gets three pending rows and pairs them oldest-first as the acks come back.
29
+ *
30
+ * The reply BODY is deliberately not promised: it reaches the parent as an injected
31
+ * message, not through this seam, so a registered child reports where its answer comes
32
+ * from instead of pretending we can fetch it. Claiming to hold a report we never read
33
+ * is the defect this product exists to refuse.
34
+ *
35
+ * Privacy: the trajectory records the child id and the agent name only — never the
36
+ * description or the prompt (R6 binds a diagnostic as much as a guard).
37
+ */
38
+ /** How many unclaimed acks one caller may have in flight before we stop guessing which
39
+ * `description` belongs to which child. Past this the child is registered with a
40
+ * generic label rather than a possibly-wrong one. */
41
+ export const PENDING_PER_CALLER = 8;
42
+ /** Read the dispatch out of the tool input (the host's `execute.before` field is
43
+ * `input`, and it IS the argument object). Returns null for anything that is not a
44
+ * recognisable `subagent` call — a non-object input is left alone, never invented. */
45
+ export function pendingDispatchOf(raw, at = Date.now()) {
46
+ if (!raw || typeof raw !== "object")
47
+ return null;
48
+ const a = raw;
49
+ const agent = typeof a.agent === "string" ? a.agent.trim().toLowerCase() : "";
50
+ if (!agent)
51
+ return null;
52
+ const desc = typeof a.description === "string" ? a.description.trim() : "";
53
+ return { agent, label: (desc || "host subagent").slice(0, 40), at };
54
+ }
55
+ /** The child's session id, from the two places the host puts it (measured). A
56
+ * synchronous child DOES have a `metadata.sessionID` — the host always sets
57
+ * `{sessionID, status}` — but its `status` is already `completed` and its content IS the
58
+ * reply, so there is nothing to
59
+ * collect and null is the correct answer, not a failure. */
60
+ export function hostChildIdOf(result) {
61
+ const r = result;
62
+ if (!r || typeof r !== "object")
63
+ return null;
64
+ const meta = r.metadata;
65
+ const fromMeta = typeof meta?.sessionID === "string" ? meta.sessionID.trim() : "";
66
+ if (fromMeta)
67
+ return fromMeta;
68
+ // The ack sentence, as a fallback: metadata is the host's own field and the text is
69
+ // what the model reads, so a shape change in one of the two still leaves a path.
70
+ const parts = Array.isArray(r.content) ? r.content : [];
71
+ for (const p of parts) {
72
+ if (typeof p?.text !== "string")
73
+ continue;
74
+ const m = /sessionID:\s*(ses_[A-Za-z0-9]+)/.exec(p.text);
75
+ if (m)
76
+ return m[1];
77
+ }
78
+ const flat = typeof r.output === "string" ? /sessionID:\s*(ses_[A-Za-z0-9]+)/.exec(r.output) : null;
79
+ return flat ? flat[1] : null;
80
+ }
81
+ /** True when the ack says the child is still open — i.e. worth registering. Read from
82
+ * the host's own code (2.0.18): the `subagent` result always carries
83
+ * `metadata:{sessionID, status}`, and a SYNCHRONOUS child arrives with
84
+ * `status:"completed"` and the body itself, so there is nothing left to collect. A
85
+ * `status` we do not recognise registers anyway, because a missed child costs the lead a
86
+ * whole round while a spurious row only costs a line in a table. */
87
+ export function hostChildIsOpen(result) {
88
+ const meta = result?.metadata;
89
+ return String(meta?.status ?? "running").toLowerCase() !== "completed";
90
+ }
91
+ /** The host's own completion envelope, in either generation's spelling. Returns the child
92
+ * id and the state the host asserted, or null when the text is not an injection.
93
+ * `[B]` 2.0.18 builds the wrapper as `<subagent sessionID="…" state="completed" …>`; v1
94
+ * used `<task id="…" state="completed">`. Both are matched because a plugin reload can
95
+ * serve a session whose history contains either. */
96
+ export function completionFromText(text) {
97
+ const m = /<(?:subagent|task)\s[^>]*?(?:sessionID|id)="(ses_[A-Za-z0-9]+)"[^>]*?state="([a-zA-Z_]+)"/.exec(text);
98
+ return m ? { sessionID: m[1], state: m[2].toLowerCase() } : null;
99
+ }
100
+ /** Pull the candidate text out of whatever a hook payload carries. Names only are ever
101
+ * reported; the text itself is read to find an envelope and is not stored. */
102
+ function textsOf(payload) {
103
+ const p = payload;
104
+ if (!p || typeof p !== "object")
105
+ return [];
106
+ const out = [];
107
+ const push = (v) => { if (typeof v === "string" && v)
108
+ out.push(v); };
109
+ push(p.text);
110
+ for (const key of ["parts", "messages"]) {
111
+ const arr = p[key];
112
+ if (!Array.isArray(arr))
113
+ continue;
114
+ for (const item of arr) {
115
+ const rec = item;
116
+ push(rec?.text);
117
+ // A v2 message is `{info, parts[]}` and a provider message is `{role, content[]}`;
118
+ // the envelope can ride either, and reading only one of them is how this watcher
119
+ // fired on every hook and settled nothing (caught by the suite, not by the host).
120
+ for (const listKey of ["parts", "content"]) {
121
+ const list = rec?.[listKey];
122
+ if (!Array.isArray(list))
123
+ continue;
124
+ for (const c of list)
125
+ push(c?.text);
126
+ }
127
+ }
128
+ }
129
+ return out;
130
+ }
131
+ /**
132
+ * The settle path for a child the plugin never created (#31, 2026-09-26).
133
+ *
134
+ * A live 2.0.18 round proved the two obvious paths do not work: the host does NOT forward a
135
+ * child session's `session.idle` to a plugin subscriber, and the parent-idle presumption
136
+ * cannot fire mid-turn because the parent is by definition busy while it works. So a
137
+ * background child whose full report had ALREADY been injected stayed 运行中 — goal #6's
138
+ * overstated claim wearing the opposite face.
139
+ *
140
+ * A second round then proved a hook can exist and still be the wrong one: `session.prompt`
141
+ * fired 0 times and `session.model.request` fired 6 but carried no messages at all (the
142
+ * message list is assembled separately from that payload). The seam that DOES carry the
143
+ * parent's history is `session.hook("context")` — the same one the request trim and the
144
+ * probe read, and the one whose `messages` the probe counted at 8 in that round.
145
+ *
146
+ * So: watch `context`, and only when something is actually open. The scan is O(messages)
147
+ * per request, which is a real cost on a long-lived lead session, so an idle registry skips
148
+ * it entirely and the skip is counted — "we did not look because there was nothing to look
149
+ * for" stays distinguishable from "we looked and saw nothing".
150
+ *
151
+ * `session.prompt` is kept registered and counted as well: it costs nothing, and if a future
152
+ * host routes the injection through it, the counter is where we would learn that.
153
+ */
154
+ export function applyV2CompletionWatch(ctx, deps) {
155
+ const report = { contextFired: 0, promptFired: 0, seen: 0, settled: 0, skipped: 0 };
156
+ const session = ctx?.session;
157
+ const hook = session?.hook;
158
+ if (typeof hook !== "function")
159
+ return { registrations: [], report, active: false };
160
+ const reg = hook;
161
+ const scan = (which) => (raw) => {
162
+ try {
163
+ const event = raw;
164
+ if (deps.scope && deps.scope.count(deps.scope.decide(event)) !== "ours")
165
+ return;
166
+ if (which === "context")
167
+ report.contextFired++;
168
+ else
169
+ report.promptFired++;
170
+ if (deps.hasOpen && !deps.hasOpen()) {
171
+ report.skipped++;
172
+ return;
173
+ }
174
+ for (const text of textsOf(raw)) {
175
+ const c = completionFromText(text);
176
+ if (!c)
177
+ continue;
178
+ report.seen++;
179
+ if (deps.settle(c.sessionID, c.state))
180
+ report.settled++;
181
+ }
182
+ }
183
+ catch {
184
+ /* a diagnostic may never block a request */
185
+ }
186
+ };
187
+ return {
188
+ registrations: [reg("context", scan("context")), reg("prompt", scan("prompt"))],
189
+ report,
190
+ active: true,
191
+ };
192
+ }
193
+ export function applyV2SubagentRegistry(ctx, deps) {
194
+ const report = { seen: 0, registered: 0, noChildId: 0, settledAtOnce: 0, unpaired: 0, labelGuessed: 0 };
195
+ const hook = ctx?.tool?.hook;
196
+ if (typeof hook !== "function")
197
+ return { registrations: [], report, active: false };
198
+ const now = deps.now ?? (() => Date.now());
199
+ const pending = new Map();
200
+ const reg = hook;
201
+ const ours = (event) => {
202
+ if (!deps.scope)
203
+ return true;
204
+ if (deps.scope.count(deps.scope.decide(event)) !== "ours")
205
+ return false;
206
+ deps.scope.learn(event.agent, event.sessionID);
207
+ return true;
208
+ };
209
+ const before = reg("execute.before", (raw) => {
210
+ // The host's own field name is `input` — read out of 2.0.18:
211
+ // e.trigger("tool","execute.before",{tool,sessionID,agent,messageID,id,input:m})
212
+ // Reading `args` here was the live-round failure: the stash silently stayed empty,
213
+ // so every ack arrived unpaired and the child was registered under a generic label
214
+ // instead of the role and task it was dispatched for.
215
+ const event = raw;
216
+ try {
217
+ if (String(event?.tool ?? "") !== "subagent")
218
+ return;
219
+ if (!ours(event))
220
+ return;
221
+ const p = pendingDispatchOf(event?.input, now());
222
+ if (!p)
223
+ return;
224
+ const caller = String(event.sessionID ?? "").trim();
225
+ if (!caller)
226
+ return;
227
+ const list = pending.get(caller) ?? [];
228
+ list.push(p);
229
+ // Bounded, oldest-first: an unbounded map is how a long-lived lead process grows,
230
+ // and past the cap the pairing stops being a fact.
231
+ if (list.length > PENDING_PER_CALLER)
232
+ list.splice(0, list.length - PENDING_PER_CALLER);
233
+ pending.set(caller, list);
234
+ }
235
+ catch {
236
+ /* a diagnostic may never break a dispatch */
237
+ }
238
+ });
239
+ const after = reg("execute.after", (raw) => {
240
+ const event = raw;
241
+ try {
242
+ if (String(event?.tool ?? "") !== "subagent")
243
+ return;
244
+ if (!ours(event))
245
+ return;
246
+ report.seen++;
247
+ const child = hostChildIdOf(event?.result);
248
+ if (!child) {
249
+ report.noChildId++;
250
+ return;
251
+ }
252
+ const caller = String(event.sessionID ?? "").trim();
253
+ if (!caller || caller === child)
254
+ return;
255
+ if (!hostChildIsOpen(event?.result)) {
256
+ report.settledAtOnce++; // a synchronous child: its result IS the reply
257
+ return;
258
+ }
259
+ const list = pending.get(caller) ?? [];
260
+ const p = list.shift();
261
+ if (list.length >= PENDING_PER_CALLER)
262
+ report.labelGuessed++;
263
+ if (!p)
264
+ report.unpaired++;
265
+ const opened = deps.register({
266
+ sessionID: child,
267
+ parentSessionID: caller,
268
+ agent: p?.agent ?? "subagent",
269
+ // An unpaired ack still deserves a row: the child exists and the user can see
270
+ // it. What we do not do is invent a task name for it.
271
+ label: p?.label ?? "宿主子代理(未配到派发)",
272
+ });
273
+ if (opened)
274
+ report.registered++;
275
+ if (list.length)
276
+ pending.set(caller, list);
277
+ else
278
+ pending.delete(caller);
279
+ }
280
+ catch {
281
+ /* never throw into the host's hook */
282
+ }
283
+ });
284
+ return { registrations: [before, after], report, active: true };
285
+ }
286
+ //# sourceMappingURL=v2-subagent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-subagent.js","sourceRoot":"","sources":["../../src/host/v2-subagent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * v1 tool definitions -> v2 tool registrations.
3
+ *
4
+ * Two shapes have to be translated, and both translations are load-bearing:
5
+ *
6
+ * 1. THE RESULT. v1 tools answer `{output: string, attachments?: [...]}`. A
7
+ * live probe measured what the v2 host does with that: every tool that
8
+ * returned a bare `output` without declaring an `output` schema came back as
9
+ * "Tool result declared output without an output schema". So the v2 adapter
10
+ * answers with `content` parts instead — text plus `file` entries, which is
11
+ * also the first time tm_browser's screenshot attachment has had a host
12
+ * contract we can VERIFY rather than assume (the v1 capability row for it is
13
+ * still 未验证).
14
+ * 2. THE CONTEXT. Our tools read `{directory, sessionID, agent, ask}` off the
15
+ * per-call ctx. v2's ToolContext carries `{sessionID, agent, messageID, id,
16
+ * progress}` and NO directory and NO ask bridge. Directory comes from the
17
+ * boot location; the missing ask bridge is left missing on purpose, because
18
+ * `askFnOf` then reports "unavailable" and every governed call fails CLOSED
19
+ * rather than pretending somebody approved it.
20
+ */
21
+ import type { ToolDefinition } from "../types.js";
22
+ import type { V2ToolContext, V2ToolInfo, V2ToolResult } from "./v2-types.js";
23
+ /**
24
+ * `args` is a ZodRawShape (see `src/tm/args-schema.ts`) — but it is a
25
+ * *descriptor* when zod could not be loaded, and it may already be a JSON
26
+ * Schema. `exact:false` means the model gets no parameter guidance for this
27
+ * tool, which the caller reports instead of hiding: a tool the model cannot
28
+ * call correctly is a tool that is broken, whatever the code says.
29
+ */
30
+ export declare function inputSchemaFor(args: unknown): Promise<{
31
+ schema: Record<string, unknown>;
32
+ exact: boolean;
33
+ source: string;
34
+ note?: string;
35
+ }>;
36
+ /** The per-execute literal our pipelines expect. */
37
+ export declare function v2ToolCtx(ctx: V2ToolContext, directory: string): Record<string, unknown>;
38
+ export declare function v2Result(res: unknown): V2ToolResult;
39
+ export interface V2ToolBinding {
40
+ readonly tool: V2ToolInfo;
41
+ readonly inputExact: boolean;
42
+ /** How the schema was obtained: "zod" | "json-schema" | "descriptor" |
43
+ * "permissive". `exact` alone cannot tell a translated zod shape from a
44
+ * regex read of a descriptor string, and the boot log must not claim the
45
+ * two are the same fact. */
46
+ readonly inputSource: string;
47
+ readonly note?: string;
48
+ }
49
+ /**
50
+ * Wrap one v1 ToolDefinition. `execute` may be absent on exotic hosts; a tool
51
+ * that cannot run must not be registered at all, because the model would spend
52
+ * a round on it and get nothing.
53
+ */
54
+ export declare function bindV2Tool(name: string, def: ToolDefinition, directory: string,
55
+ /** Every call to OUR tool tells the host-scope resolver which sessions belong to
56
+ * Team (#22) — the one fact about a session we can learn from the inside. */
57
+ onCall?: (agent: unknown, sessionID: unknown) => void,
58
+ /** `codemodeDirect: true` sends `options:{codemode:false}`, which the 2.0.16
59
+ * binary uses as the visibility switch: without it a registered tool reaches the
60
+ * model ONLY inside the Code Mode catalog, with its description cut to the first
61
+ * line — so every governance sentence we wrote below that line never arrives.
62
+ * Off by default because the cost is the whole definition set riding every
63
+ * request; the number is measured, not argued (see TM_V2_CODEMODE). */
64
+ opts?: {
65
+ codemodeDirect?: boolean;
66
+ }): Promise<V2ToolBinding | null>;
67
+ //# sourceMappingURL=v2-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-tool.d.ts","sourceRoot":"","sources":["../../src/host/v2-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAoC,MAAM,aAAa,CAAA;AACnF,OAAO,KAAK,EAAa,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAkFvF;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgC7F;AAED,oDAAoD;AACpD,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWxF;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAcnD;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B;;;iCAG6B;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM;AACjB;8EAC8E;AAC9E,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI;AACrD;;;;;wEAKwE;AACxE,IAAI,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAkB/B"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * v1 tool definitions -> v2 tool registrations.
3
+ *
4
+ * Two shapes have to be translated, and both translations are load-bearing:
5
+ *
6
+ * 1. THE RESULT. v1 tools answer `{output: string, attachments?: [...]}`. A
7
+ * live probe measured what the v2 host does with that: every tool that
8
+ * returned a bare `output` without declaring an `output` schema came back as
9
+ * "Tool result declared output without an output schema". So the v2 adapter
10
+ * answers with `content` parts instead — text plus `file` entries, which is
11
+ * also the first time tm_browser's screenshot attachment has had a host
12
+ * contract we can VERIFY rather than assume (the v1 capability row for it is
13
+ * still 未验证).
14
+ * 2. THE CONTEXT. Our tools read `{directory, sessionID, agent, ask}` off the
15
+ * per-call ctx. v2's ToolContext carries `{sessionID, agent, messageID, id,
16
+ * progress}` and NO directory and NO ask bridge. Directory comes from the
17
+ * boot location; the missing ask bridge is left missing on purpose, because
18
+ * `askFnOf` then reports "unavailable" and every governed call fails CLOSED
19
+ * rather than pretending somebody approved it.
20
+ */
21
+ /** zod is a peer the host ships, never a dependency we require: the same
22
+ * variable-specifier trick `args-schema.ts` uses for the arg schemas. */
23
+ async function loadZod() {
24
+ try {
25
+ const spec = "zod";
26
+ const mod = (await import(spec));
27
+ const z = (mod.z ?? mod.default?.z);
28
+ return z && typeof z.object === "function" ? z : null;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ /** A descriptor entry: `{ key: { descriptor: "name: type (…) — guidance" } }`.
35
+ * Three tools ship this shape (tm_join / tm_pty / tm_stats) because their args
36
+ * are built without zod, and feeding it to `z.object()` throws
37
+ * `undefined is not an object (evaluating 'schema._zod.def')` — measured live,
38
+ * where those three reached the model with NO parameter guidance at all.
39
+ * The descriptor's leading `name: type` is parseable, and the whole string is
40
+ * the guidance, so translating it is strictly better than a permissive schema. */
41
+ const DESCRIPTOR_HEAD = /^([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([\s\S]*)$/;
42
+ /** `typed` is what follows the `name:` in the descriptor — the type is read off
43
+ * its first token. Passing the whole line instead would read the parameter
44
+ * NAME plus its colon (`action:`), which matches no type shape at all, so every
45
+ * descriptor would collapse to `string` and the enum/array/number guidance
46
+ * would be silently lost. `full` stays the description verbatim: the guidance
47
+ * after the type is the part the model actually needs. */
48
+ function descriptorToProperty(full, typed) {
49
+ const head = (typed.trim().match(/^[^\s(,]+/) ?? [""])[0];
50
+ let type = "string";
51
+ let enumValues;
52
+ if (/^[A-Za-z][\w.]*\[\]$/.test(head)) {
53
+ type = "array";
54
+ }
55
+ else if (/^\d+$/.test(head) || /^(number|int|integer)/i.test(head)) {
56
+ type = "number";
57
+ }
58
+ else if (/^(true|false|boolean)$/i.test(head)) {
59
+ type = "boolean";
60
+ }
61
+ else if (/^[A-Za-z0-9_|-]*\|[A-Za-z0-9_|-]+$/.test(head)) {
62
+ enumValues = head.split("|").filter(Boolean);
63
+ type = "string";
64
+ }
65
+ const prop = { type };
66
+ if (type === "array")
67
+ prop.items = { type: "string" };
68
+ if (enumValues)
69
+ prop.enum = enumValues;
70
+ prop.description = full.trim();
71
+ return prop;
72
+ }
73
+ function fromDescriptors(shape) {
74
+ const properties = {};
75
+ const required = [];
76
+ let seen = 0;
77
+ for (const [key, value] of Object.entries(shape)) {
78
+ const text = typeof value === "string"
79
+ ? `${key}: ${value}`
80
+ : typeof value?.descriptor === "string"
81
+ ? String(value.descriptor)
82
+ : null;
83
+ if (!text)
84
+ continue;
85
+ seen++;
86
+ const m = text.match(DESCRIPTOR_HEAD);
87
+ properties[key] = m
88
+ ? descriptorToProperty(text, m[2] ?? "")
89
+ : { type: "string", description: text };
90
+ // `(required)` is explicit in the fallback schemas; `(optional` marks the
91
+ // rest. Anything unmarked stays optional — execute() coerces raw args
92
+ // itself, and a wrong `required` makes the host reject a valid call.
93
+ if (/\(required\)/i.test(text) && !/optional/i.test(text))
94
+ required.push(key);
95
+ }
96
+ if (!seen || seen !== Object.keys(shape).length)
97
+ return null;
98
+ const schema = { type: "object", properties, additionalProperties: false };
99
+ if (required.length)
100
+ schema.required = required;
101
+ return { schema, required };
102
+ }
103
+ /**
104
+ * `args` is a ZodRawShape (see `src/tm/args-schema.ts`) — but it is a
105
+ * *descriptor* when zod could not be loaded, and it may already be a JSON
106
+ * Schema. `exact:false` means the model gets no parameter guidance for this
107
+ * tool, which the caller reports instead of hiding: a tool the model cannot
108
+ * call correctly is a tool that is broken, whatever the code says.
109
+ */
110
+ export async function inputSchemaFor(args) {
111
+ if (args && typeof args === "object") {
112
+ const shape = args;
113
+ if (typeof shape.type === "string" && (shape.properties || shape.additionalProperties !== undefined)) {
114
+ return { schema: shape, exact: true, source: "json-schema" };
115
+ }
116
+ const descriptors = fromDescriptors(shape);
117
+ if (descriptors) {
118
+ return { schema: descriptors.schema, exact: true, source: "descriptor" };
119
+ }
120
+ const z = await loadZod();
121
+ const toJSONSchema = z?.toJSONSchema;
122
+ if (z && toJSONSchema) {
123
+ try {
124
+ const schema = toJSONSchema(z.object(shape));
125
+ return { schema, exact: true, source: "zod" };
126
+ }
127
+ catch (err) {
128
+ return {
129
+ schema: { type: "object", additionalProperties: true },
130
+ exact: false,
131
+ source: "permissive",
132
+ note: `zod 形状转换失败:${err?.message ?? String(err)}`,
133
+ };
134
+ }
135
+ }
136
+ }
137
+ return {
138
+ schema: { type: "object", additionalProperties: true },
139
+ exact: false,
140
+ source: "permissive",
141
+ note: "宿主未提供 zod,参数表退化为不限形状",
142
+ };
143
+ }
144
+ /** The per-execute literal our pipelines expect. */
145
+ export function v2ToolCtx(ctx, directory) {
146
+ const c = (ctx ?? {});
147
+ return {
148
+ // A future host may carry a per-call directory (sessions CAN move); honor it
149
+ // when present instead of pinning the boot value.
150
+ directory: typeof c.directory === "string" && c.directory ? c.directory : directory,
151
+ sessionID: String(c.sessionID ?? ""),
152
+ agent: String(c.agent ?? ""),
153
+ // NOTE: no `ask` on purpose — see the header. Adding a stub that resolves
154
+ // would be the self-allowing this codebase refuses.
155
+ };
156
+ }
157
+ export function v2Result(res) {
158
+ // `ToolResult` is a union: most tm_* answers are already plain strings.
159
+ if (typeof res === "string")
160
+ return { content: [{ type: "text", text: res }] };
161
+ const out = (res ?? {});
162
+ const text = typeof out.output === "string" ? out.output : String(out.output ?? "");
163
+ const content = [{ type: "text", text }];
164
+ for (const att of (out.attachments ?? [])) {
165
+ if (!att || typeof att.url !== "string" || !att.url)
166
+ continue;
167
+ content.push({ type: "file", uri: att.url, mime: att.mime, name: att.filename });
168
+ }
169
+ const metadata = out.metadata;
170
+ return metadata && typeof metadata === "object"
171
+ ? { content, metadata }
172
+ : { content };
173
+ }
174
+ /**
175
+ * Wrap one v1 ToolDefinition. `execute` may be absent on exotic hosts; a tool
176
+ * that cannot run must not be registered at all, because the model would spend
177
+ * a round on it and get nothing.
178
+ */
179
+ export async function bindV2Tool(name, def, directory,
180
+ /** Every call to OUR tool tells the host-scope resolver which sessions belong to
181
+ * Team (#22) — the one fact about a session we can learn from the inside. */
182
+ onCall,
183
+ /** `codemodeDirect: true` sends `options:{codemode:false}`, which the 2.0.16
184
+ * binary uses as the visibility switch: without it a registered tool reaches the
185
+ * model ONLY inside the Code Mode catalog, with its description cut to the first
186
+ * line — so every governance sentence we wrote below that line never arrives.
187
+ * Off by default because the cost is the whole definition set riding every
188
+ * request; the number is measured, not argued (see TM_V2_CODEMODE). */
189
+ opts = {}) {
190
+ if (typeof def?.execute !== "function")
191
+ return null;
192
+ const { schema, exact, source, note } = await inputSchemaFor(def.args);
193
+ const tool = {
194
+ name,
195
+ description: String(def.description ?? ""),
196
+ input: schema,
197
+ ...(opts.codemodeDirect ? { options: { codemode: false } } : {}),
198
+ async execute(args, ctx) {
199
+ onCall?.(ctx?.agent, ctx?.sessionID);
200
+ // Our tools are defensive about raw model args already (they coerce
201
+ // string booleans and JSON-array strings themselves), so nothing is
202
+ // normalized here beyond a guaranteed object.
203
+ const res = await def.execute?.((args ?? {}), v2ToolCtx(ctx, directory));
204
+ return v2Result(res);
205
+ },
206
+ };
207
+ return { tool, inputExact: exact, inputSource: source, note };
208
+ }
209
+ //# sourceMappingURL=v2-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-tool.js","sourceRoot":"","sources":["../../src/host/v2-tool.ts"],"names":[],"mappings":"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"}