@nxisai/agent-harness 0.2.0
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.
- package/README.md +434 -0
- package/dist/a2ui/cards.d.ts +55 -0
- package/dist/a2ui/cards.d.ts.map +1 -0
- package/dist/a2ui/cards.js +133 -0
- package/dist/a2ui/cards.js.map +1 -0
- package/dist/a2ui/emit.d.ts +33 -0
- package/dist/a2ui/emit.d.ts.map +1 -0
- package/dist/a2ui/emit.js +116 -0
- package/dist/a2ui/emit.js.map +1 -0
- package/dist/a2ui/form.d.ts +20 -0
- package/dist/a2ui/form.d.ts.map +1 -0
- package/dist/a2ui/form.js +92 -0
- package/dist/a2ui/form.js.map +1 -0
- package/dist/a2ui/host.d.ts +34 -0
- package/dist/a2ui/host.d.ts.map +1 -0
- package/dist/a2ui/host.js +47 -0
- package/dist/a2ui/host.js.map +1 -0
- package/dist/a2ui/index.d.ts +23 -0
- package/dist/a2ui/index.d.ts.map +1 -0
- package/dist/a2ui/index.js +20 -0
- package/dist/a2ui/index.js.map +1 -0
- package/dist/a2ui/stepper.d.ts +26 -0
- package/dist/a2ui/stepper.d.ts.map +1 -0
- package/dist/a2ui/stepper.js +162 -0
- package/dist/a2ui/stepper.js.map +1 -0
- package/dist/a2ui/theme.d.ts +21 -0
- package/dist/a2ui/theme.d.ts.map +1 -0
- package/dist/a2ui/theme.js +134 -0
- package/dist/a2ui/theme.js.map +1 -0
- package/dist/a2ui/to-v09.d.ts +31 -0
- package/dist/a2ui/to-v09.d.ts.map +1 -0
- package/dist/a2ui/to-v09.js +104 -0
- package/dist/a2ui/to-v09.js.map +1 -0
- package/dist/engine.d.ts +209 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +505 -0
- package/dist/engine.js.map +1 -0
- package/dist/harness/harness.d.ts +284 -0
- package/dist/harness/harness.d.ts.map +1 -0
- package/dist/harness/harness.js +568 -0
- package/dist/harness/harness.js.map +1 -0
- package/dist/harness/plan.d.ts +32 -0
- package/dist/harness/plan.d.ts.map +1 -0
- package/dist/harness/plan.js +68 -0
- package/dist/harness/plan.js.map +1 -0
- package/dist/harness/policy.d.ts +49 -0
- package/dist/harness/policy.d.ts.map +1 -0
- package/dist/harness/policy.js +34 -0
- package/dist/harness/policy.js.map +1 -0
- package/dist/harness/renderer.d.ts +163 -0
- package/dist/harness/renderer.d.ts.map +1 -0
- package/dist/harness/renderer.js +12 -0
- package/dist/harness/renderer.js.map +1 -0
- package/dist/harness/router/coordinator.d.ts +120 -0
- package/dist/harness/router/coordinator.d.ts.map +1 -0
- package/dist/harness/router/coordinator.js +145 -0
- package/dist/harness/router/coordinator.js.map +1 -0
- package/dist/harness/router/rules.d.ts +48 -0
- package/dist/harness/router/rules.d.ts.map +1 -0
- package/dist/harness/router/rules.js +38 -0
- package/dist/harness/router/rules.js.map +1 -0
- package/dist/harness/slots.d.ts +73 -0
- package/dist/harness/slots.d.ts.map +1 -0
- package/dist/harness/slots.js +68 -0
- package/dist/harness/slots.js.map +1 -0
- package/dist/harness/tools/bridge.d.ts +71 -0
- package/dist/harness/tools/bridge.d.ts.map +1 -0
- package/dist/harness/tools/bridge.js +271 -0
- package/dist/harness/tools/bridge.js.map +1 -0
- package/dist/harness/tools/client.d.ts +11 -0
- package/dist/harness/tools/client.d.ts.map +1 -0
- package/dist/harness/tools/client.js +21 -0
- package/dist/harness/tools/client.js.map +1 -0
- package/dist/harness/tools/discovery.d.ts +13 -0
- package/dist/harness/tools/discovery.d.ts.map +1 -0
- package/dist/harness/tools/discovery.js +43 -0
- package/dist/harness/tools/discovery.js.map +1 -0
- package/dist/harness/tools/local-context.d.ts +38 -0
- package/dist/harness/tools/local-context.d.ts.map +1 -0
- package/dist/harness/tools/local-context.js +55 -0
- package/dist/harness/tools/local-context.js.map +1 -0
- package/dist/harness/tools/schema.d.ts +52 -0
- package/dist/harness/tools/schema.d.ts.map +1 -0
- package/dist/harness/tools/schema.js +175 -0
- package/dist/harness/tools/schema.js.map +1 -0
- package/dist/harness/tools/source.d.ts +65 -0
- package/dist/harness/tools/source.d.ts.map +1 -0
- package/dist/harness/tools/source.js +89 -0
- package/dist/harness/tools/source.js.map +1 -0
- package/dist/harness/tools/webmcp.d.ts +50 -0
- package/dist/harness/tools/webmcp.d.ts.map +1 -0
- package/dist/harness/tools/webmcp.js +114 -0
- package/dist/harness/tools/webmcp.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/types.d.ts +123 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/types.d.ts +223 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/agent-fullscreen.d.ts +41 -0
- package/dist/ui/agent-fullscreen.d.ts.map +1 -0
- package/dist/ui/agent-fullscreen.js +2821 -0
- package/dist/ui/agent-fullscreen.js.map +1 -0
- package/dist/ui/config.d.ts +88 -0
- package/dist/ui/config.d.ts.map +1 -0
- package/dist/ui/config.js +96 -0
- package/dist/ui/config.js.map +1 -0
- package/dist/ui/index.d.ts +22 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +19 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/tailwind.generated.d.ts +2 -0
- package/dist/ui/tailwind.generated.d.ts.map +1 -0
- package/dist/ui/tailwind.generated.js +3 -0
- package/dist/ui/tailwind.generated.js.map +1 -0
- package/dist/webmcp-contract.d.ts +57 -0
- package/dist/webmcp-contract.d.ts.map +1 -0
- package/dist/webmcp-contract.js +11 -0
- package/dist/webmcp-contract.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turn loop: discover tools, generate, parse the tool call, resolve what is
|
|
3
|
+
* still unknown, decide whether to ask or act, run the tool, report the result.
|
|
4
|
+
*
|
|
5
|
+
* The harness decides; a {@link HarnessRenderer} draws. What a turn does
|
|
6
|
+
* depends on the tool's own annotations and on how much the model supplied:
|
|
7
|
+
*
|
|
8
|
+
* | Tool | Missing values | Outcome |
|
|
9
|
+
* |---|---|---|
|
|
10
|
+
* | read | none | runs immediately, no UI |
|
|
11
|
+
* | read | some | asks for those, then runs |
|
|
12
|
+
* | write | none | read-only summary and one Submit |
|
|
13
|
+
* | write | several | a stepper, then a confirmation |
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import { stripMarkers, humanize, } from '../engine.js';
|
|
18
|
+
import { LocalGemmaProvider } from '../engine.js';
|
|
19
|
+
import { WebMcpTools } from './tools/webmcp.js';
|
|
20
|
+
import { extractResult, reconcileArgs, toolSchema } from './tools/schema.js';
|
|
21
|
+
import { decide, policyFor } from './policy.js';
|
|
22
|
+
import { buildPlan } from './plan.js';
|
|
23
|
+
import { resolveSlots, summarySlots } from './slots.js';
|
|
24
|
+
/**
|
|
25
|
+
* Whether a reply reads as the model asking rather than answering.
|
|
26
|
+
*
|
|
27
|
+
* Intentionally crude: it gates one extra generation, so a false positive costs
|
|
28
|
+
* a wasted round rather than a wrong action.
|
|
29
|
+
*/
|
|
30
|
+
function looksLikeQuestion(text) {
|
|
31
|
+
return /\?\s*$/.test(stripMarkers(text).trim());
|
|
32
|
+
}
|
|
33
|
+
/** Stands in when a reply was neither prose nor a recognisable tool call. */
|
|
34
|
+
const WORKING_ON_IT = 'Working on that.';
|
|
35
|
+
/**
|
|
36
|
+
* Whether an error represents a cancelled operation rather than a failure.
|
|
37
|
+
*
|
|
38
|
+
* @param err - The caught value.
|
|
39
|
+
* @returns True for a DOM `AbortError`, as thrown by an aborted `fetch`.
|
|
40
|
+
*/
|
|
41
|
+
export function isAbort(err) {
|
|
42
|
+
return err?.name === 'AbortError';
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A sentence to show for a turn whose model output was only a tool call.
|
|
46
|
+
*
|
|
47
|
+
* Claims no more than the harness knows at that point: which tool was chosen,
|
|
48
|
+
* and whether it reads or writes.
|
|
49
|
+
*
|
|
50
|
+
* @param call - The parsed tool call, or null if there was none.
|
|
51
|
+
* @param tools - The tools available this turn, used to read the annotations.
|
|
52
|
+
* @returns A short line to display in place of the model's own words.
|
|
53
|
+
*/
|
|
54
|
+
export function narrateCall(call, tools) {
|
|
55
|
+
if (!call)
|
|
56
|
+
return WORKING_ON_IT;
|
|
57
|
+
const tool = tools.find((t) => t.name === call.name);
|
|
58
|
+
if (tool && policyFor(tool).readOnly)
|
|
59
|
+
return 'Looking that up.';
|
|
60
|
+
return `Filling in the ${humanize(call.name).toLowerCase()}.`;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* How many records a tool response contained.
|
|
64
|
+
*
|
|
65
|
+
* Best-effort: it feeds a summary line, so an unrecognised shape reports
|
|
66
|
+
* nothing rather than guessing.
|
|
67
|
+
*
|
|
68
|
+
* @param res - The tool response, whose `structuredContent` is preferred.
|
|
69
|
+
* @param text - The same response flattened to text, parsed as JSON if needed.
|
|
70
|
+
* @returns The record count, or undefined when the shape is not recognised.
|
|
71
|
+
*/
|
|
72
|
+
export function countRecords(res, text) {
|
|
73
|
+
const structured = res?.structuredContent;
|
|
74
|
+
if (Array.isArray(structured?.results))
|
|
75
|
+
return structured.results.length;
|
|
76
|
+
if (typeof structured?.total === 'number')
|
|
77
|
+
return structured.total;
|
|
78
|
+
try {
|
|
79
|
+
const parsed = JSON.parse(text);
|
|
80
|
+
if (Array.isArray(parsed?.results))
|
|
81
|
+
return parsed.results.length;
|
|
82
|
+
if (typeof parsed?.total === 'number')
|
|
83
|
+
return parsed.total;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// A plain-text response carries no count.
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* One agent: a provider, a set of tools, and the loop that runs a turn.
|
|
92
|
+
*
|
|
93
|
+
* Use it directly for a single-agent page, or several behind an
|
|
94
|
+
* {@link AgentCoordinator} to route between specialists.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const harness = new AgentHarness({ renderer });
|
|
99
|
+
* const messages: ChatMessage[] = [];
|
|
100
|
+
* await harness.turn('what are your opening hours?', messages);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export class AgentHarness {
|
|
104
|
+
constructor(opts) {
|
|
105
|
+
/** Values typed into a prompt that is still open, kept across turns. */
|
|
106
|
+
this.entered = {};
|
|
107
|
+
this.liveTool = null;
|
|
108
|
+
/** The in-flight turn's controller, so it can be cancelled. */
|
|
109
|
+
this.abort = null;
|
|
110
|
+
/** The previous request's system prompt and tool names, for the cache hint. */
|
|
111
|
+
this.lastPrompt = '';
|
|
112
|
+
this.lastTools = '';
|
|
113
|
+
this.provider = opts.provider ?? new LocalGemmaProvider();
|
|
114
|
+
this.toolSource = opts.toolSource ?? new WebMcpTools();
|
|
115
|
+
this.renderer = opts.renderer;
|
|
116
|
+
this.opts = opts;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* End a turn that the user stopped.
|
|
120
|
+
*
|
|
121
|
+
* Discards any partial answer and keeps the question, recording it if the
|
|
122
|
+
* stop arrived before the turn had done so, so the transcript matches what is
|
|
123
|
+
* on screen.
|
|
124
|
+
*/
|
|
125
|
+
stopTurn(bubble, messages, goal) {
|
|
126
|
+
bubble.finalize('');
|
|
127
|
+
this.renderer.status('');
|
|
128
|
+
const asked = [...messages].reverse().find((m) => m.role === 'user');
|
|
129
|
+
if (asked?.content !== goal) {
|
|
130
|
+
messages.push({ role: 'user', content: goal });
|
|
131
|
+
this.opts.onMessages?.(messages);
|
|
132
|
+
}
|
|
133
|
+
return this.finished({ decision: 'stopped' });
|
|
134
|
+
}
|
|
135
|
+
/** Report a finished turn and clear the stoppable state. */
|
|
136
|
+
finished(result) {
|
|
137
|
+
this.renderer.stoppable?.(false);
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
/** Whether the current turn has been stopped. */
|
|
141
|
+
get stopped() {
|
|
142
|
+
return !!this.abort?.signal.aborted;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Abandon the turn in flight.
|
|
146
|
+
*
|
|
147
|
+
* Aborts tool discovery or generation, whichever is running. The turn
|
|
148
|
+
* resolves as `'stopped'` rather than rejecting, so a cancellation is not
|
|
149
|
+
* reported as a failure. Safe to call when nothing is running.
|
|
150
|
+
*
|
|
151
|
+
* A tool call already in progress is not interrupted, since it may have
|
|
152
|
+
* reached a server already.
|
|
153
|
+
*/
|
|
154
|
+
stop() {
|
|
155
|
+
this.abort?.abort();
|
|
156
|
+
this.abort = null;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Render a completion for the transcript.
|
|
160
|
+
*
|
|
161
|
+
* The transcript must record the tool call, or the model repeats it on the
|
|
162
|
+
* next turn. Providers returning structured calls have no text form for one,
|
|
163
|
+
* so this writes it. Never displayed: the UI shows `completion.text`.
|
|
164
|
+
*/
|
|
165
|
+
transcribe(completion) {
|
|
166
|
+
if (!completion.call)
|
|
167
|
+
return completion.text;
|
|
168
|
+
const args = JSON.stringify(completion.call.args ?? {});
|
|
169
|
+
const said = completion.text ? `${completion.text}\n` : '';
|
|
170
|
+
return `${said}[called ${completion.call.name} with ${args}]`;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Compare this request with the previous one to build a {@link CacheHint}.
|
|
174
|
+
*
|
|
175
|
+
* Must be called after `applySystemPrompt`, since a handoff between agents
|
|
176
|
+
* replaces both the system message and the tool slice.
|
|
177
|
+
*/
|
|
178
|
+
cacheHint(messages, tools) {
|
|
179
|
+
const names = tools.map((t) => t.name).join(',');
|
|
180
|
+
const prompt = messages[0]?.role === 'system' ? messages[0].content : '';
|
|
181
|
+
const hint = {
|
|
182
|
+
stableMessages: prompt && prompt === this.lastPrompt ? 1 : 0,
|
|
183
|
+
toolsStable: names === this.lastTools,
|
|
184
|
+
};
|
|
185
|
+
this.lastPrompt = prompt;
|
|
186
|
+
this.lastTools = names;
|
|
187
|
+
return hint;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Run one turn.
|
|
191
|
+
*
|
|
192
|
+
* The turn moves through phases the renderer is told about as they happen
|
|
193
|
+
* (loading the model, finding tools, generating, running the tool), each on a
|
|
194
|
+
* {@link HarnessRenderer.streaming} bubble with its own label. A renderer
|
|
195
|
+
* should expect the first bubble before any token exists.
|
|
196
|
+
*
|
|
197
|
+
* Starting a turn supersedes any turn still running.
|
|
198
|
+
*
|
|
199
|
+
* @param goal - The user's message.
|
|
200
|
+
* @param messages - The live conversation, appended to in place. The caller
|
|
201
|
+
* keeps ownership of persistence; see {@link HarnessOptions.onMessages}.
|
|
202
|
+
* @returns How the turn ended. A page with no tools, a tool that errors, and
|
|
203
|
+
* a cancellation all resolve normally; see {@link TurnResult.decision}.
|
|
204
|
+
* @throws If the model cannot be loaded (no WebGPU, unreachable weights) or a
|
|
205
|
+
* generation fails for a reason other than being aborted.
|
|
206
|
+
*/
|
|
207
|
+
async turn(goal, messages) {
|
|
208
|
+
// Created before the first await, so `stopped` reads this turn's signal
|
|
209
|
+
// rather than the previous turn's.
|
|
210
|
+
this.abort?.abort();
|
|
211
|
+
this.abort = new AbortController();
|
|
212
|
+
this.renderer.stoppable?.(true);
|
|
213
|
+
// Opened before the model is touched: loading weights is the longest
|
|
214
|
+
// silence in a turn, and the thread should not be empty during it.
|
|
215
|
+
const bubble = this.renderer.streaming();
|
|
216
|
+
bubble.thinking(this.provider.ready ? 'Thinking…' : 'Loading model…');
|
|
217
|
+
try {
|
|
218
|
+
await this.provider.load?.();
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
// A stop during a load is not a failure to load. The download continues
|
|
222
|
+
// and its bytes are cached, so the next attempt resumes rather than
|
|
223
|
+
// starting over.
|
|
224
|
+
if (this.stopped || isAbort(err))
|
|
225
|
+
return this.stopTurn(bubble, messages, goal);
|
|
226
|
+
bubble.finalize('');
|
|
227
|
+
throw err;
|
|
228
|
+
}
|
|
229
|
+
// Asserted per turn rather than seeded once, because agents share the
|
|
230
|
+
// transcript and each has its own prompt.
|
|
231
|
+
this.applySystemPrompt(messages);
|
|
232
|
+
if (this.stopped) {
|
|
233
|
+
return this.stopTurn(bubble, messages, goal);
|
|
234
|
+
}
|
|
235
|
+
bubble.thinking('Finding tools…');
|
|
236
|
+
const registered = await this.toolSource.discoverTools(this.abort?.signal);
|
|
237
|
+
if (this.stopped) {
|
|
238
|
+
return this.stopTurn(bubble, messages, goal);
|
|
239
|
+
}
|
|
240
|
+
const tools = this.visibleTools(registered);
|
|
241
|
+
if (!tools.length) {
|
|
242
|
+
bubble.finalize('');
|
|
243
|
+
this.renderer.status('');
|
|
244
|
+
// A page with no tools at all is a host misconfiguration; this agent
|
|
245
|
+
// having none of them is answerable to the user. The slice is never
|
|
246
|
+
// widened to compensate, since using the wrong tool succeeds at the wrong
|
|
247
|
+
// thing rather than failing visibly.
|
|
248
|
+
if (registered.length) {
|
|
249
|
+
console.warn(`[nxis-agent] ${this.opts.name ?? 'agent'} has no tools on this page ` +
|
|
250
|
+
`(page has: ${registered.map((t) => t.name).join(', ')})`);
|
|
251
|
+
this.renderer.message('assistant', this.opts.unavailable ??
|
|
252
|
+
'I cannot do that from this page — the tools for it are not available here.');
|
|
253
|
+
return { decision: 'unavailable' };
|
|
254
|
+
}
|
|
255
|
+
// Actionable only by the host, so the detail goes to the console.
|
|
256
|
+
console.warn('No tools are registered on this page yet — make sure nxis.js has loaded.');
|
|
257
|
+
this.renderer.message('assistant', 'No tools are registered on this page yet.');
|
|
258
|
+
return { decision: 'none' };
|
|
259
|
+
}
|
|
260
|
+
messages.push({ role: 'user', content: goal });
|
|
261
|
+
bubble.thinking('Thinking…');
|
|
262
|
+
this.renderer.status('Thinking…');
|
|
263
|
+
let completion;
|
|
264
|
+
try {
|
|
265
|
+
completion = await this.provider.complete({
|
|
266
|
+
messages,
|
|
267
|
+
tools,
|
|
268
|
+
onToken: (t) => bubble.update(t),
|
|
269
|
+
signal: this.abort?.signal,
|
|
270
|
+
cache: this.cacheHint(messages, tools),
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
// A remote provider rejects on abort (as `fetch` does); the local one
|
|
275
|
+
// returns what it had. Neither is a failure to report.
|
|
276
|
+
if (this.stopped || isAbort(err))
|
|
277
|
+
return this.stopTurn(bubble, messages, goal);
|
|
278
|
+
bubble.finalize('');
|
|
279
|
+
throw err;
|
|
280
|
+
}
|
|
281
|
+
// Nothing the model produced survives a stop, on screen or in the
|
|
282
|
+
// transcript: a model that reads its own unfinished reply back as history
|
|
283
|
+
// will continue from it or contradict it.
|
|
284
|
+
if (this.stopped) {
|
|
285
|
+
return this.stopTurn(bubble, messages, goal);
|
|
286
|
+
}
|
|
287
|
+
// A reply is often nothing but the tool call. Left empty the bubble would
|
|
288
|
+
// be dropped, and the thread would jump from the question to a rendered
|
|
289
|
+
// card with no turn between them.
|
|
290
|
+
bubble.finalize(completion.text || narrateCall(completion.call ?? null, tools));
|
|
291
|
+
messages.push({ role: 'assistant', content: this.transcribe(completion) });
|
|
292
|
+
this.opts.onMessages?.(messages);
|
|
293
|
+
this.renderer.status('');
|
|
294
|
+
let call = completion.call ?? null;
|
|
295
|
+
// Small models sometimes ask in prose instead of calling the tool. One
|
|
296
|
+
// nudge, then accept the question: a clarifying question is better than a
|
|
297
|
+
// retry loop.
|
|
298
|
+
if (!call && looksLikeQuestion(completion.text)) {
|
|
299
|
+
const retry = await this.retryForToolCall(messages, tools, bubble);
|
|
300
|
+
if (retry)
|
|
301
|
+
call = retry;
|
|
302
|
+
else if (this.stopped)
|
|
303
|
+
return this.finished({ decision: 'stopped' });
|
|
304
|
+
}
|
|
305
|
+
// Still prose: a legitimate turn, already rendered and in the transcript.
|
|
306
|
+
if (!call)
|
|
307
|
+
return { decision: 'none' };
|
|
308
|
+
const tool = tools.find((t) => t.name === call.name);
|
|
309
|
+
if (!tool) {
|
|
310
|
+
// A tool the page has but this agent may not use is a routing problem,
|
|
311
|
+
// which a coordinator can correct. A tool no page has was invented by the
|
|
312
|
+
// model.
|
|
313
|
+
const elsewhere = registered.some((t) => t.name === call.name);
|
|
314
|
+
if (elsewhere)
|
|
315
|
+
return { decision: 'handback', wanted: call.name };
|
|
316
|
+
this.renderer.message('assistant', `I picked an unknown tool ("${call.name}"). Try rephrasing.`);
|
|
317
|
+
return { decision: 'none' };
|
|
318
|
+
}
|
|
319
|
+
return this.act(tool, call.args, messages);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Narrow the page's tools to this agent's slice.
|
|
323
|
+
*
|
|
324
|
+
* @param registered - Every tool the tool source reported.
|
|
325
|
+
* @returns The tools matching {@link HarnessOptions.tools}, or all of them
|
|
326
|
+
* when no filter is set.
|
|
327
|
+
*/
|
|
328
|
+
visibleTools(tools) {
|
|
329
|
+
const filter = this.opts.tools;
|
|
330
|
+
return filter ? tools.filter((t) => filter(t)) : tools;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Whether this agent's filter accepts a tool, by name.
|
|
334
|
+
*
|
|
335
|
+
* Called by {@link AgentCoordinator} when another agent hands a turn back.
|
|
336
|
+
* The filter receives a tool with only its name set, so a filter that
|
|
337
|
+
* inspects annotations should reject a bare name and let the fallback take
|
|
338
|
+
* the turn.
|
|
339
|
+
*
|
|
340
|
+
* @param name - The tool name to test.
|
|
341
|
+
* @returns True when this agent would use that tool.
|
|
342
|
+
*/
|
|
343
|
+
owns(name) {
|
|
344
|
+
const filter = this.opts.tools;
|
|
345
|
+
if (!filter)
|
|
346
|
+
return true;
|
|
347
|
+
try {
|
|
348
|
+
return filter({ name });
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Place this agent's instructions at the head of the shared transcript,
|
|
356
|
+
* replacing another agent's if one is there.
|
|
357
|
+
*/
|
|
358
|
+
applySystemPrompt(messages) {
|
|
359
|
+
const prompt = this.opts.systemPrompt;
|
|
360
|
+
if (!prompt)
|
|
361
|
+
return;
|
|
362
|
+
if (messages[0]?.role === 'system') {
|
|
363
|
+
if (messages[0].content !== prompt)
|
|
364
|
+
messages[0] = { role: 'system', content: prompt };
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
messages.unshift({ role: 'system', content: prompt });
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Generate once more, instructing the model to call a tool.
|
|
372
|
+
*
|
|
373
|
+
* The instruction is added as a user turn, which carries the most weight in a
|
|
374
|
+
* chat template mid-conversation, and is removed again afterwards so it never
|
|
375
|
+
* remains in the transcript as something the user said.
|
|
376
|
+
*
|
|
377
|
+
* @returns The tool call, or null if the model still did not produce one.
|
|
378
|
+
*/
|
|
379
|
+
async retryForToolCall(messages, tools, bubble) {
|
|
380
|
+
const nudge = {
|
|
381
|
+
role: 'user',
|
|
382
|
+
content: 'Call the appropriate tool now with the fields you already have. ' +
|
|
383
|
+
'Omit any field you do not know — do not ask me for it.',
|
|
384
|
+
};
|
|
385
|
+
messages.push(nudge);
|
|
386
|
+
let completion;
|
|
387
|
+
try {
|
|
388
|
+
completion = await this.provider.complete({
|
|
389
|
+
messages,
|
|
390
|
+
tools,
|
|
391
|
+
onToken: (t) => bubble.update(t),
|
|
392
|
+
signal: this.abort?.signal,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
catch (err) {
|
|
396
|
+
// The nudge is the harness's own text, so it is removed however the retry
|
|
397
|
+
// ends rather than being left in the transcript.
|
|
398
|
+
messages.splice(messages.indexOf(nudge), 1);
|
|
399
|
+
if (this.stopped || isAbort(err))
|
|
400
|
+
return null;
|
|
401
|
+
throw err;
|
|
402
|
+
}
|
|
403
|
+
const call = completion.call ?? null;
|
|
404
|
+
if (this.stopped) {
|
|
405
|
+
messages.splice(messages.indexOf(nudge), 1);
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
if (call) {
|
|
409
|
+
// Keep the assistant's tool call; drop the nudge the user never said.
|
|
410
|
+
messages.splice(messages.indexOf(nudge), 1);
|
|
411
|
+
messages.push({ role: 'assistant', content: this.transcribe(completion) });
|
|
412
|
+
bubble.finalize(completion.text || narrateCall(call, tools));
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
messages.splice(messages.indexOf(nudge), 1);
|
|
416
|
+
}
|
|
417
|
+
return call;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Resolve a proposed call's arguments, then run it, confirm it, or ask.
|
|
421
|
+
*
|
|
422
|
+
* @param tool - The tool the model chose.
|
|
423
|
+
* @param rawArgs - Its arguments, before reconciliation against the schema.
|
|
424
|
+
* @param messages - The live conversation.
|
|
425
|
+
* @returns The decision taken and the values it was taken with.
|
|
426
|
+
*/
|
|
427
|
+
async act(tool, rawArgs, messages) {
|
|
428
|
+
const schema = toolSchema(tool);
|
|
429
|
+
const modelArgs = reconcileArgs(rawArgs, schema);
|
|
430
|
+
// Keep values already typed while the model revises a call to the same
|
|
431
|
+
// tool; discard them when it moves to a different one.
|
|
432
|
+
const entered = this.liveTool?.name === tool.name ? this.entered : {};
|
|
433
|
+
const resolution = resolveSlots(schema, {
|
|
434
|
+
modelArgs,
|
|
435
|
+
entered,
|
|
436
|
+
profile: this.opts.profile?.(schema),
|
|
437
|
+
context: this.opts.context?.(tool),
|
|
438
|
+
});
|
|
439
|
+
const policy = policyFor(tool);
|
|
440
|
+
const decision = decide(policy, resolution.missing.length);
|
|
441
|
+
if (decision === 'execute') {
|
|
442
|
+
await this.run(tool, resolution.values, messages);
|
|
443
|
+
return { decision, tool, values: resolution.values };
|
|
444
|
+
}
|
|
445
|
+
if (decision === 'confirm') {
|
|
446
|
+
this.liveTool = tool;
|
|
447
|
+
this.renderer.confirm({
|
|
448
|
+
tool,
|
|
449
|
+
slots: summarySlots(resolution),
|
|
450
|
+
values: resolution.values,
|
|
451
|
+
onSubmit: (values) => void this.run(tool, values, messages),
|
|
452
|
+
onCancel: () => this.cancel(),
|
|
453
|
+
onEdit: () => this.askAll(tool, resolution, messages),
|
|
454
|
+
});
|
|
455
|
+
return { decision, tool, values: resolution.values };
|
|
456
|
+
}
|
|
457
|
+
// decision === 'ask': the gaps only, stepped when there are several.
|
|
458
|
+
this.liveTool = tool;
|
|
459
|
+
const plan = buildPlan(resolution.missing, this.opts.groupRelated !== false);
|
|
460
|
+
this.renderer.message('assistant', plan.stepped
|
|
461
|
+
? `I need ${plan.steps.length} more details for ${humanize(tool.name)}.`
|
|
462
|
+
: `One more thing for ${humanize(tool.name)}.`);
|
|
463
|
+
this.renderer.ask({
|
|
464
|
+
tool,
|
|
465
|
+
plan,
|
|
466
|
+
resolution,
|
|
467
|
+
onComplete: (answers) => {
|
|
468
|
+
const values = { ...resolution.values, ...answers };
|
|
469
|
+
this.entered = values;
|
|
470
|
+
// A read was waiting only on the gap. A write still needs its
|
|
471
|
+
// confirmation, now a summary rather than a form.
|
|
472
|
+
if (policy.confirmWhenSatisfied) {
|
|
473
|
+
this.renderer.confirm({
|
|
474
|
+
tool,
|
|
475
|
+
slots: summarySlots(resolveSlots(schema, { modelArgs: values })),
|
|
476
|
+
values,
|
|
477
|
+
onSubmit: (v) => void this.run(tool, v, messages),
|
|
478
|
+
onCancel: () => this.cancel(),
|
|
479
|
+
onEdit: () => this.askAll(tool, resolution, messages),
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
void this.run(tool, values, messages);
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
onCancel: () => this.cancel(),
|
|
487
|
+
});
|
|
488
|
+
return { decision, tool, values: resolution.values };
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Reopen a confirmation as an editable form covering every field, not only
|
|
492
|
+
* the gaps. Reached through {@link ConfirmRequest.onEdit}.
|
|
493
|
+
*/
|
|
494
|
+
askAll(tool, resolution, messages) {
|
|
495
|
+
const editable = resolution.all.filter((s) => s.name in resolution.values || s.required);
|
|
496
|
+
this.renderer.ask({
|
|
497
|
+
tool,
|
|
498
|
+
plan: buildPlan(editable, false),
|
|
499
|
+
resolution,
|
|
500
|
+
onComplete: (answers) => void this.run(tool, { ...resolution.values, ...answers }, messages),
|
|
501
|
+
onCancel: () => this.cancel(),
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
/** Discard a live prompt and the values typed into it. */
|
|
505
|
+
cancel() {
|
|
506
|
+
this.entered = {};
|
|
507
|
+
this.liveTool = null;
|
|
508
|
+
this.renderer.dismissPrompt?.();
|
|
509
|
+
this.renderer.message('assistant', 'Okay — cancelled. Tell me what you’d like to do.');
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Execute a fully resolved call and render its result.
|
|
513
|
+
*
|
|
514
|
+
* Read tools render as records, writes as a detail card. Either way the
|
|
515
|
+
* outcome is written into the transcript so the model can refer back to it.
|
|
516
|
+
*/
|
|
517
|
+
async run(tool, values, messages) {
|
|
518
|
+
this.renderer.dismissPrompt?.();
|
|
519
|
+
// Past this point the turn cannot be stopped: the call may reach a server
|
|
520
|
+
// before an abort could arrive.
|
|
521
|
+
this.renderer.stoppable?.(false);
|
|
522
|
+
this.renderer.status(`Running ${tool.name}…`);
|
|
523
|
+
// A remote tool call is another silence, and the generation bubble that
|
|
524
|
+
// covered the last one has been finalized by now.
|
|
525
|
+
const working = this.renderer.streaming();
|
|
526
|
+
working.thinking(`Running ${humanize(tool.name)}…`);
|
|
527
|
+
try {
|
|
528
|
+
const res = await this.toolSource.execTool(tool, tool.name, values);
|
|
529
|
+
const text = extractResult(res);
|
|
530
|
+
working.finalize('');
|
|
531
|
+
this.renderer.status('');
|
|
532
|
+
this.renderer.trace?.({
|
|
533
|
+
tool,
|
|
534
|
+
args: values,
|
|
535
|
+
text,
|
|
536
|
+
isError: !!res?.isError,
|
|
537
|
+
count: countRecords(res, text),
|
|
538
|
+
});
|
|
539
|
+
if (res?.isError) {
|
|
540
|
+
this.renderer.toolError(tool, text || 'Failed');
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
this.entered = {};
|
|
544
|
+
this.liveTool = null;
|
|
545
|
+
if (policyFor(tool).readOnly) {
|
|
546
|
+
this.renderer.results(tool, res);
|
|
547
|
+
messages.push({ role: 'user', content: `[${tool.name} returned: ${text.slice(0, 400)}]` });
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
this.renderer.detail(tool, values, text);
|
|
551
|
+
messages.push({
|
|
552
|
+
role: 'user',
|
|
553
|
+
content: `[${tool.name} submitted with: ${JSON.stringify(values)}]. Keep these unless I ask to change them.`,
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
this.opts.onMessages?.(messages);
|
|
557
|
+
}
|
|
558
|
+
catch (err) {
|
|
559
|
+
const message = String(err?.message || err);
|
|
560
|
+
working.finalize('');
|
|
561
|
+
this.renderer.status('');
|
|
562
|
+
// A call that threw is the main reason to open a trace.
|
|
563
|
+
this.renderer.trace?.({ tool, args: values, text: message, isError: true });
|
|
564
|
+
this.renderer.toolError(tool, message);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/harness/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arranges missing values into the steps a renderer asks for them in.
|
|
3
|
+
*
|
|
4
|
+
* A single missing value is one question; several become a stepper.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import type { Slot } from './slots.js';
|
|
9
|
+
/** One screen of the plan. */
|
|
10
|
+
export interface PlanStep {
|
|
11
|
+
/** Position in {@link ClarificationPlan.steps}, from zero. */
|
|
12
|
+
index: number;
|
|
13
|
+
/** Slots asked together. One by default; grouped when they belong together. */
|
|
14
|
+
slots: Slot[];
|
|
15
|
+
title: string;
|
|
16
|
+
}
|
|
17
|
+
/** The questions to ask before a tool call can proceed. */
|
|
18
|
+
export interface ClarificationPlan {
|
|
19
|
+
steps: PlanStep[];
|
|
20
|
+
/** True when the renderer should draw stepper chrome (Back, Step n of m). */
|
|
21
|
+
stepped: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Arrange missing slots into steps.
|
|
25
|
+
*
|
|
26
|
+
* @param missing - The slots still needing values, in the order to ask for them.
|
|
27
|
+
* @param groupRelated - Whether to place related fields (see {@link AFFINITY})
|
|
28
|
+
* on one step. Pass `false` to ask for every field separately.
|
|
29
|
+
* @returns A plan whose `stepped` flag is true when it has more than one step.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildPlan(missing: Slot[], groupRelated?: boolean): ClarificationPlan;
|
|
32
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/harness/plan.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,8BAA8B;AAC9B,MAAM,WAAW,QAAQ;IACvB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;CAClB;AAkBD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,YAAY,UAAO,GAAG,iBAAiB,CAyBjF"}
|