agent-worker 0.13.0 → 0.15.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 +6 -3
- package/dist/{backends-BWzhErjT.mjs → backends-BYWmuyF9.mjs} +1 -1
- package/dist/{backends-CziIqKRg.mjs → backends-C7pQwuAx.mjs} +310 -222
- package/dist/cli/index.mjs +2044 -478
- package/dist/context-CdcZpO-0.mjs +4 -0
- package/dist/create-tool-gcUuI1FD.mjs +32 -0
- package/dist/index.d.mts +65 -87
- package/dist/index.mjs +465 -21
- package/dist/{memory-provider-BtLYtdQH.mjs → memory-provider-ZLOKyCxA.mjs} +8 -3
- package/dist/runner-DB-b57iZ.mjs +670 -0
- package/dist/workflow-DQ6Eju4n.mjs +664 -0
- package/package.json +4 -3
- package/dist/context-BqEyt2SF.mjs +0 -4
- package/dist/logger-Bfdo83xL.mjs +0 -63
- package/dist/runner-CnxROIev.mjs +0 -1496
- package/dist/worker-DBJ8136Q.mjs +0 -448
- package/dist/workflow-CIE3WPNx.mjs +0 -272
- /package/dist/{display-pretty-BCJq5v9d.mjs → display-pretty-Kyd40DEF.mjs} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,459 @@
|
|
|
1
|
-
import { M as SUPPORTED_PROVIDERS, N as createModel, P as createModelAsync, a as createMockBackend, d as CodexBackend, f as ClaudeCodeBackend, i as MockAIBackend, j as FRONTIER_MODELS, n as createBackend, o as SdkBackend, r as listBackends, t as checkBackends, u as CursorBackend } from "./backends-
|
|
2
|
-
import { t as
|
|
3
|
-
import {
|
|
1
|
+
import { F as createModelWithProvider, M as SUPPORTED_PROVIDERS, N as createModel, P as createModelAsync, a as createMockBackend, d as CodexBackend, f as ClaudeCodeBackend, i as MockAIBackend, j as FRONTIER_MODELS, n as createBackend, o as SdkBackend, r as listBackends, t as checkBackends, u as CursorBackend } from "./backends-C7pQwuAx.mjs";
|
|
2
|
+
import { t as createTool } from "./create-tool-gcUuI1FD.mjs";
|
|
3
|
+
import { ToolLoopAgent, stepCountIs } from "ai";
|
|
4
4
|
import { createBashTool } from "bash-tool";
|
|
5
5
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
6
6
|
import { join, normalize } from "node:path";
|
|
7
|
-
import { parse } from "yaml";
|
|
8
7
|
import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
|
|
8
|
+
import { parse } from "yaml";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { tmpdir } from "node:os";
|
|
11
11
|
import { spawn } from "node:child_process";
|
|
12
12
|
|
|
13
|
+
//#region src/agent/worker.ts
|
|
14
|
+
/**
|
|
15
|
+
* AgentWorker - Stateful worker for controlled agent execution
|
|
16
|
+
*
|
|
17
|
+
* Uses ToolLoopAgent internally for multi-step reasoning loops.
|
|
18
|
+
* Maintains conversation state across multiple send() calls,
|
|
19
|
+
* enabling improvisational testing where you observe responses
|
|
20
|
+
* and decide next actions.
|
|
21
|
+
*
|
|
22
|
+
* Tools are AI SDK tool() objects passed as Record<name, tool()>.
|
|
23
|
+
* Approval is configured separately via Record<name, check>.
|
|
24
|
+
*/
|
|
25
|
+
var AgentWorker = class {
|
|
26
|
+
id;
|
|
27
|
+
model;
|
|
28
|
+
system;
|
|
29
|
+
createdAt;
|
|
30
|
+
tools;
|
|
31
|
+
approval;
|
|
32
|
+
maxTokens;
|
|
33
|
+
maxSteps;
|
|
34
|
+
messages = [];
|
|
35
|
+
totalUsage = {
|
|
36
|
+
input: 0,
|
|
37
|
+
output: 0,
|
|
38
|
+
total: 0
|
|
39
|
+
};
|
|
40
|
+
pendingApprovals = [];
|
|
41
|
+
backend;
|
|
42
|
+
provider;
|
|
43
|
+
cachedAgent = null;
|
|
44
|
+
toolsChanged = false;
|
|
45
|
+
/**
|
|
46
|
+
* Whether this session supports tool management (SDK backend only)
|
|
47
|
+
*/
|
|
48
|
+
get supportsTools() {
|
|
49
|
+
return this.backend === null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Convert AgentMessage[] to ModelMessage[] for AI SDK
|
|
53
|
+
*/
|
|
54
|
+
toModelMessages() {
|
|
55
|
+
return this.messages.filter((m) => m.status !== "responding").map((m) => ({
|
|
56
|
+
role: m.role,
|
|
57
|
+
content: m.content
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
constructor(config, restore) {
|
|
61
|
+
if (restore) {
|
|
62
|
+
this.id = restore.id;
|
|
63
|
+
this.createdAt = restore.createdAt;
|
|
64
|
+
this.messages = [...restore.messages];
|
|
65
|
+
this.totalUsage = { ...restore.totalUsage };
|
|
66
|
+
this.pendingApprovals = [...restore.pendingApprovals ?? []];
|
|
67
|
+
} else {
|
|
68
|
+
this.id = crypto.randomUUID();
|
|
69
|
+
this.createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
70
|
+
}
|
|
71
|
+
this.model = config.model;
|
|
72
|
+
this.system = config.system;
|
|
73
|
+
this.tools = config.tools ? { ...config.tools } : {};
|
|
74
|
+
this.approval = config.approval ? { ...config.approval } : {};
|
|
75
|
+
this.maxTokens = config.maxTokens ?? 4096;
|
|
76
|
+
this.maxSteps = config.maxSteps ?? 200;
|
|
77
|
+
this.backend = config.backend ?? null;
|
|
78
|
+
this.provider = config.provider;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if a tool needs approval for given arguments
|
|
82
|
+
*/
|
|
83
|
+
checkApproval(name, args) {
|
|
84
|
+
const check = this.approval[name];
|
|
85
|
+
if (!check) return false;
|
|
86
|
+
if (typeof check === "function") return check(args);
|
|
87
|
+
return check;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Build tools with approval wrapping for ToolLoopAgent
|
|
91
|
+
*/
|
|
92
|
+
buildTools(autoApprove) {
|
|
93
|
+
if (Object.keys(this.tools).length === 0) return void 0;
|
|
94
|
+
if (autoApprove || Object.keys(this.approval).length === 0) return this.tools;
|
|
95
|
+
const wrapped = {};
|
|
96
|
+
for (const [name, t] of Object.entries(this.tools)) {
|
|
97
|
+
if (!this.approval[name]) {
|
|
98
|
+
wrapped[name] = t;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
wrapped[name] = {
|
|
102
|
+
...t,
|
|
103
|
+
execute: async (args, options) => {
|
|
104
|
+
if (this.checkApproval(name, args)) {
|
|
105
|
+
const approval = {
|
|
106
|
+
id: crypto.randomUUID(),
|
|
107
|
+
toolName: name,
|
|
108
|
+
toolCallId: crypto.randomUUID(),
|
|
109
|
+
arguments: args,
|
|
110
|
+
requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
111
|
+
status: "pending"
|
|
112
|
+
};
|
|
113
|
+
this.pendingApprovals.push(approval);
|
|
114
|
+
return {
|
|
115
|
+
__approvalRequired: true,
|
|
116
|
+
approvalId: approval.id
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return t.execute?.(args, options);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return wrapped;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get or create cached agent, rebuild if tools changed
|
|
127
|
+
*/
|
|
128
|
+
async getAgent(autoApprove) {
|
|
129
|
+
if (!this.cachedAgent || this.toolsChanged || !autoApprove) {
|
|
130
|
+
this.cachedAgent = new ToolLoopAgent({
|
|
131
|
+
model: this.provider ? await createModelWithProvider(this.model, this.provider) : await createModelAsync(this.model),
|
|
132
|
+
instructions: this.system,
|
|
133
|
+
tools: this.buildTools(autoApprove),
|
|
134
|
+
maxOutputTokens: this.maxTokens,
|
|
135
|
+
stopWhen: stepCountIs(this.maxSteps)
|
|
136
|
+
});
|
|
137
|
+
if (autoApprove) this.toolsChanged = false;
|
|
138
|
+
}
|
|
139
|
+
return this.cachedAgent;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Send a message via CLI backend (non-SDK path)
|
|
143
|
+
*/
|
|
144
|
+
async sendViaBackend(content) {
|
|
145
|
+
const startTime = performance.now();
|
|
146
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
147
|
+
this.messages.push({
|
|
148
|
+
role: "user",
|
|
149
|
+
content,
|
|
150
|
+
status: "complete",
|
|
151
|
+
timestamp
|
|
152
|
+
});
|
|
153
|
+
const result = await this.backend.send(content, { system: this.system });
|
|
154
|
+
const latency = Math.round(performance.now() - startTime);
|
|
155
|
+
this.messages.push({
|
|
156
|
+
role: "assistant",
|
|
157
|
+
content: result.content,
|
|
158
|
+
status: "complete",
|
|
159
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
160
|
+
});
|
|
161
|
+
const usage = {
|
|
162
|
+
input: result.usage?.input ?? 0,
|
|
163
|
+
output: result.usage?.output ?? 0,
|
|
164
|
+
total: result.usage?.total ?? 0
|
|
165
|
+
};
|
|
166
|
+
this.totalUsage.input += usage.input;
|
|
167
|
+
this.totalUsage.output += usage.output;
|
|
168
|
+
this.totalUsage.total += usage.total;
|
|
169
|
+
const toolCalls = (result.toolCalls ?? []).map((tc) => ({
|
|
170
|
+
name: tc.name,
|
|
171
|
+
arguments: tc.arguments,
|
|
172
|
+
result: tc.result,
|
|
173
|
+
timing: 0
|
|
174
|
+
}));
|
|
175
|
+
return {
|
|
176
|
+
content: result.content,
|
|
177
|
+
toolCalls,
|
|
178
|
+
pendingApprovals: [],
|
|
179
|
+
usage,
|
|
180
|
+
latency
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Send a message and get the agent's response
|
|
185
|
+
*/
|
|
186
|
+
async send(content, options = {}) {
|
|
187
|
+
if (this.backend) return this.sendViaBackend(content);
|
|
188
|
+
const { autoApprove = true, onStepFinish } = options;
|
|
189
|
+
const startTime = performance.now();
|
|
190
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
191
|
+
this.messages.push({
|
|
192
|
+
role: "user",
|
|
193
|
+
content,
|
|
194
|
+
status: "complete",
|
|
195
|
+
timestamp
|
|
196
|
+
});
|
|
197
|
+
const agent = await this.getAgent(autoApprove);
|
|
198
|
+
const allToolCalls = [];
|
|
199
|
+
let stepNumber = 0;
|
|
200
|
+
const result = await agent.generate({
|
|
201
|
+
messages: this.toModelMessages(),
|
|
202
|
+
onStepFinish: async ({ usage, toolCalls, toolResults }) => {
|
|
203
|
+
stepNumber++;
|
|
204
|
+
const stepToolCalls = [];
|
|
205
|
+
if (toolCalls) for (const tc of toolCalls) {
|
|
206
|
+
const toolResult = toolResults?.find((tr) => tr.toolCallId === tc.toolCallId);
|
|
207
|
+
const toolCall = {
|
|
208
|
+
name: tc.toolName,
|
|
209
|
+
arguments: tc.input,
|
|
210
|
+
result: toolResult?.output ?? null,
|
|
211
|
+
timing: 0
|
|
212
|
+
};
|
|
213
|
+
stepToolCalls.push(toolCall);
|
|
214
|
+
allToolCalls.push(toolCall);
|
|
215
|
+
}
|
|
216
|
+
if (onStepFinish) {
|
|
217
|
+
const stepUsage = {
|
|
218
|
+
input: usage?.inputTokens ?? 0,
|
|
219
|
+
output: usage?.outputTokens ?? 0,
|
|
220
|
+
total: (usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0)
|
|
221
|
+
};
|
|
222
|
+
await onStepFinish({
|
|
223
|
+
stepNumber,
|
|
224
|
+
toolCalls: stepToolCalls,
|
|
225
|
+
usage: stepUsage
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
const latency = Math.round(performance.now() - startTime);
|
|
231
|
+
this.messages.push({
|
|
232
|
+
role: "assistant",
|
|
233
|
+
content: result.text,
|
|
234
|
+
status: "complete",
|
|
235
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
236
|
+
});
|
|
237
|
+
const usage = {
|
|
238
|
+
input: result.usage?.inputTokens ?? 0,
|
|
239
|
+
output: result.usage?.outputTokens ?? 0,
|
|
240
|
+
total: (result.usage?.inputTokens ?? 0) + (result.usage?.outputTokens ?? 0)
|
|
241
|
+
};
|
|
242
|
+
this.totalUsage.input += usage.input;
|
|
243
|
+
this.totalUsage.output += usage.output;
|
|
244
|
+
this.totalUsage.total += usage.total;
|
|
245
|
+
if (this.maxSteps > 0 && stepNumber >= this.maxSteps && allToolCalls.length > 0) console.warn(`⚠️ Agent reached maxSteps limit (${this.maxSteps}) but wanted to continue. Consider increasing maxSteps or removing the limit.`);
|
|
246
|
+
const currentPending = this.pendingApprovals.filter((p) => p.status === "pending");
|
|
247
|
+
return {
|
|
248
|
+
content: result.text,
|
|
249
|
+
toolCalls: allToolCalls,
|
|
250
|
+
pendingApprovals: currentPending,
|
|
251
|
+
usage,
|
|
252
|
+
latency
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Send a message and stream the response
|
|
257
|
+
*/
|
|
258
|
+
async *sendStream(content, options = {}) {
|
|
259
|
+
if (this.backend) {
|
|
260
|
+
const response = await this.sendViaBackend(content);
|
|
261
|
+
yield response.content;
|
|
262
|
+
return response;
|
|
263
|
+
}
|
|
264
|
+
const { autoApprove = true, onStepFinish } = options;
|
|
265
|
+
const startTime = performance.now();
|
|
266
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
267
|
+
this.messages.push({
|
|
268
|
+
role: "user",
|
|
269
|
+
content,
|
|
270
|
+
status: "complete",
|
|
271
|
+
timestamp
|
|
272
|
+
});
|
|
273
|
+
const assistantMsg = {
|
|
274
|
+
role: "assistant",
|
|
275
|
+
content: "",
|
|
276
|
+
status: "responding",
|
|
277
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
278
|
+
};
|
|
279
|
+
this.messages.push(assistantMsg);
|
|
280
|
+
const agent = await this.getAgent(autoApprove);
|
|
281
|
+
const allToolCalls = [];
|
|
282
|
+
let stepNumber = 0;
|
|
283
|
+
const result = await agent.stream({
|
|
284
|
+
messages: this.toModelMessages(),
|
|
285
|
+
onStepFinish: async ({ usage, toolCalls, toolResults }) => {
|
|
286
|
+
stepNumber++;
|
|
287
|
+
const stepToolCalls = [];
|
|
288
|
+
if (toolCalls) for (const tc of toolCalls) {
|
|
289
|
+
const toolResult = toolResults?.find((tr) => tr.toolCallId === tc.toolCallId);
|
|
290
|
+
const toolCall = {
|
|
291
|
+
name: tc.toolName,
|
|
292
|
+
arguments: tc.input,
|
|
293
|
+
result: toolResult?.output ?? null,
|
|
294
|
+
timing: 0
|
|
295
|
+
};
|
|
296
|
+
stepToolCalls.push(toolCall);
|
|
297
|
+
allToolCalls.push(toolCall);
|
|
298
|
+
}
|
|
299
|
+
if (onStepFinish) {
|
|
300
|
+
const stepUsage = {
|
|
301
|
+
input: usage?.inputTokens ?? 0,
|
|
302
|
+
output: usage?.outputTokens ?? 0,
|
|
303
|
+
total: (usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0)
|
|
304
|
+
};
|
|
305
|
+
await onStepFinish({
|
|
306
|
+
stepNumber,
|
|
307
|
+
toolCalls: stepToolCalls,
|
|
308
|
+
usage: stepUsage
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
for await (const chunk of result.textStream) {
|
|
314
|
+
assistantMsg.content += chunk;
|
|
315
|
+
yield chunk;
|
|
316
|
+
}
|
|
317
|
+
const latency = Math.round(performance.now() - startTime);
|
|
318
|
+
const text = await result.text;
|
|
319
|
+
assistantMsg.content = text;
|
|
320
|
+
assistantMsg.status = "complete";
|
|
321
|
+
const finalUsage = await result.usage;
|
|
322
|
+
const usage = {
|
|
323
|
+
input: finalUsage?.inputTokens ?? 0,
|
|
324
|
+
output: finalUsage?.outputTokens ?? 0,
|
|
325
|
+
total: (finalUsage?.inputTokens ?? 0) + (finalUsage?.outputTokens ?? 0)
|
|
326
|
+
};
|
|
327
|
+
this.totalUsage.input += usage.input;
|
|
328
|
+
this.totalUsage.output += usage.output;
|
|
329
|
+
this.totalUsage.total += usage.total;
|
|
330
|
+
return {
|
|
331
|
+
content: text,
|
|
332
|
+
toolCalls: allToolCalls,
|
|
333
|
+
pendingApprovals: this.pendingApprovals.filter((p) => p.status === "pending"),
|
|
334
|
+
usage,
|
|
335
|
+
latency
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Add an AI SDK tool
|
|
340
|
+
* Only supported for SDK backends (ToolLoopAgent)
|
|
341
|
+
*/
|
|
342
|
+
addTool(name, t) {
|
|
343
|
+
if (this.backend) throw new Error("Tool management not supported for CLI backends");
|
|
344
|
+
this.tools[name] = t;
|
|
345
|
+
this.toolsChanged = true;
|
|
346
|
+
this.cachedAgent = null;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Set approval requirement for a tool
|
|
350
|
+
*/
|
|
351
|
+
setApproval(name, check) {
|
|
352
|
+
this.approval[name] = check;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Replace a tool's execute function (for testing)
|
|
356
|
+
*/
|
|
357
|
+
mockTool(name, mockFn) {
|
|
358
|
+
if (this.backend) throw new Error("Tool management not supported for CLI backends");
|
|
359
|
+
const t = this.tools[name];
|
|
360
|
+
if (!t) throw new Error(`Tool not found: ${name}`);
|
|
361
|
+
this.tools[name] = {
|
|
362
|
+
...t,
|
|
363
|
+
execute: mockFn
|
|
364
|
+
};
|
|
365
|
+
this.toolsChanged = true;
|
|
366
|
+
this.cachedAgent = null;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Set a static mock response for an existing tool
|
|
370
|
+
*/
|
|
371
|
+
setMockResponse(name, response) {
|
|
372
|
+
if (this.backend) throw new Error("Tool management not supported for CLI backends");
|
|
373
|
+
const t = this.tools[name];
|
|
374
|
+
if (!t) throw new Error(`Tool not found: ${name}`);
|
|
375
|
+
this.tools[name] = {
|
|
376
|
+
...t,
|
|
377
|
+
execute: () => response
|
|
378
|
+
};
|
|
379
|
+
this.toolsChanged = true;
|
|
380
|
+
this.cachedAgent = null;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Get tool info (names, descriptions, approval status)
|
|
384
|
+
*/
|
|
385
|
+
getTools() {
|
|
386
|
+
return Object.entries(this.tools).map(([name, t]) => {
|
|
387
|
+
return {
|
|
388
|
+
name,
|
|
389
|
+
description: t?.description,
|
|
390
|
+
needsApproval: !!this.approval[name]
|
|
391
|
+
};
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
history() {
|
|
395
|
+
return [...this.messages];
|
|
396
|
+
}
|
|
397
|
+
stats() {
|
|
398
|
+
return {
|
|
399
|
+
messageCount: this.messages.length,
|
|
400
|
+
usage: { ...this.totalUsage }
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
export() {
|
|
404
|
+
return {
|
|
405
|
+
sessionId: this.id,
|
|
406
|
+
model: this.model,
|
|
407
|
+
system: this.system,
|
|
408
|
+
messages: [...this.messages],
|
|
409
|
+
totalUsage: { ...this.totalUsage },
|
|
410
|
+
createdAt: this.createdAt
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
getState() {
|
|
414
|
+
return {
|
|
415
|
+
id: this.id,
|
|
416
|
+
createdAt: this.createdAt,
|
|
417
|
+
messages: [...this.messages],
|
|
418
|
+
totalUsage: { ...this.totalUsage },
|
|
419
|
+
pendingApprovals: [...this.pendingApprovals]
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
getPendingApprovals() {
|
|
423
|
+
return this.pendingApprovals.filter((p) => p.status === "pending");
|
|
424
|
+
}
|
|
425
|
+
async approve(approvalId) {
|
|
426
|
+
const approval = this.pendingApprovals.find((p) => p.id === approvalId);
|
|
427
|
+
if (!approval) throw new Error(`Approval not found: ${approvalId}`);
|
|
428
|
+
if (approval.status !== "pending") throw new Error(`Approval already ${approval.status}: ${approvalId}`);
|
|
429
|
+
const t = this.tools[approval.toolName];
|
|
430
|
+
if (!t) throw new Error(`Tool not found: ${approval.toolName}`);
|
|
431
|
+
let result;
|
|
432
|
+
const tool = t;
|
|
433
|
+
if (typeof tool.execute === "function") result = await tool.execute(approval.arguments);
|
|
434
|
+
else result = { error: "No implementation provided" };
|
|
435
|
+
approval.status = "approved";
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
deny(approvalId, reason) {
|
|
439
|
+
const approval = this.pendingApprovals.find((p) => p.id === approvalId);
|
|
440
|
+
if (!approval) throw new Error(`Approval not found: ${approvalId}`);
|
|
441
|
+
if (approval.status !== "pending") throw new Error(`Approval already ${approval.status}: ${approvalId}`);
|
|
442
|
+
approval.status = "denied";
|
|
443
|
+
approval.denyReason = reason;
|
|
444
|
+
}
|
|
445
|
+
clear() {
|
|
446
|
+
this.messages = [];
|
|
447
|
+
this.totalUsage = {
|
|
448
|
+
input: 0,
|
|
449
|
+
output: 0,
|
|
450
|
+
total: 0
|
|
451
|
+
};
|
|
452
|
+
this.pendingApprovals = [];
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
//#endregion
|
|
13
457
|
//#region src/agent/tools/bash.ts
|
|
14
458
|
/**
|
|
15
459
|
* Integration with Vercel's bash-tool for file system operations
|
|
@@ -36,41 +480,41 @@ async function createBashTools(options = {}) {
|
|
|
36
480
|
const { includeReadFile = true, includeWriteFile = true, ...bashOptions } = options;
|
|
37
481
|
const toolkit = await createBashTool(bashOptions);
|
|
38
482
|
const tools = {};
|
|
39
|
-
tools.bash =
|
|
483
|
+
tools.bash = createTool({
|
|
40
484
|
description: "Execute bash commands in a sandboxed environment. Returns stdout, stderr, and exit code.",
|
|
41
|
-
|
|
485
|
+
schema: {
|
|
42
486
|
type: "object",
|
|
43
487
|
properties: { command: {
|
|
44
488
|
type: "string",
|
|
45
489
|
description: "The bash command to execute"
|
|
46
490
|
} },
|
|
47
491
|
required: ["command"]
|
|
48
|
-
}
|
|
492
|
+
},
|
|
49
493
|
execute: async (args) => {
|
|
50
494
|
const bashTool = toolkit.tools.bash;
|
|
51
495
|
if (!bashTool?.execute) throw new Error("Bash tool not available");
|
|
52
496
|
return bashTool.execute(args, {});
|
|
53
497
|
}
|
|
54
498
|
});
|
|
55
|
-
if (includeReadFile) tools.readFile =
|
|
499
|
+
if (includeReadFile) tools.readFile = createTool({
|
|
56
500
|
description: "Read the contents of a file from the sandbox filesystem.",
|
|
57
|
-
|
|
501
|
+
schema: {
|
|
58
502
|
type: "object",
|
|
59
503
|
properties: { path: {
|
|
60
504
|
type: "string",
|
|
61
505
|
description: "The path to the file to read"
|
|
62
506
|
} },
|
|
63
507
|
required: ["path"]
|
|
64
|
-
}
|
|
508
|
+
},
|
|
65
509
|
execute: async (args) => {
|
|
66
510
|
const readFileTool = toolkit.tools.readFile;
|
|
67
511
|
if (!readFileTool?.execute) throw new Error("ReadFile tool not available");
|
|
68
512
|
return readFileTool.execute(args, {});
|
|
69
513
|
}
|
|
70
514
|
});
|
|
71
|
-
if (includeWriteFile) tools.writeFile =
|
|
515
|
+
if (includeWriteFile) tools.writeFile = createTool({
|
|
72
516
|
description: "Write content to a file in the sandbox filesystem. Creates parent directories if needed.",
|
|
73
|
-
|
|
517
|
+
schema: {
|
|
74
518
|
type: "object",
|
|
75
519
|
properties: {
|
|
76
520
|
path: {
|
|
@@ -83,7 +527,7 @@ async function createBashTools(options = {}) {
|
|
|
83
527
|
}
|
|
84
528
|
},
|
|
85
529
|
required: ["path", "content"]
|
|
86
|
-
}
|
|
530
|
+
},
|
|
87
531
|
execute: async (args) => {
|
|
88
532
|
const writeFileTool = toolkit.tools.writeFile;
|
|
89
533
|
if (!writeFileTool?.execute) throw new Error("WriteFile tool not available");
|
|
@@ -152,9 +596,9 @@ function createFeedbackTool(options = {}) {
|
|
|
152
596
|
const { onFeedback, maxEntries = 50 } = options;
|
|
153
597
|
const entries = [];
|
|
154
598
|
return {
|
|
155
|
-
tool:
|
|
599
|
+
tool: createTool({
|
|
156
600
|
description: "Report a workflow improvement need. Use when you hit something inconvenient — a missing tool, an awkward step, or a capability you wished you had.",
|
|
157
|
-
|
|
601
|
+
schema: {
|
|
158
602
|
type: "object",
|
|
159
603
|
properties: {
|
|
160
604
|
target: {
|
|
@@ -184,7 +628,7 @@ function createFeedbackTool(options = {}) {
|
|
|
184
628
|
"type",
|
|
185
629
|
"description"
|
|
186
630
|
]
|
|
187
|
-
}
|
|
631
|
+
},
|
|
188
632
|
execute: async (args) => {
|
|
189
633
|
const validTypes = [
|
|
190
634
|
"missing",
|
|
@@ -220,7 +664,7 @@ const frontmatterSchema = z.object({
|
|
|
220
664
|
description: z.string().min(1).max(1024),
|
|
221
665
|
license: z.string().optional(),
|
|
222
666
|
compatibility: z.string().max(500).optional(),
|
|
223
|
-
metadata: z.record(z.string()).optional(),
|
|
667
|
+
metadata: z.record(z.string(), z.string()).optional(),
|
|
224
668
|
"allowed-tools": z.string().optional()
|
|
225
669
|
});
|
|
226
670
|
var SkillsProvider = class {
|
|
@@ -374,9 +818,9 @@ var SkillsProvider = class {
|
|
|
374
818
|
* Create a Skills tool as an AI SDK tool() object
|
|
375
819
|
*/
|
|
376
820
|
function createSkillsTool(provider) {
|
|
377
|
-
return
|
|
821
|
+
return createTool({
|
|
378
822
|
description: "Interact with available agent skills. Use \"list\" to see all skills with their descriptions, \"view\" to read a complete SKILL.md file, \"readFile\" to read files within a skill directory (e.g., references/, scripts/, assets/).",
|
|
379
|
-
|
|
823
|
+
schema: {
|
|
380
824
|
type: "object",
|
|
381
825
|
properties: {
|
|
382
826
|
operation: {
|
|
@@ -398,7 +842,7 @@ function createSkillsTool(provider) {
|
|
|
398
842
|
}
|
|
399
843
|
},
|
|
400
844
|
required: ["operation"]
|
|
401
|
-
}
|
|
845
|
+
},
|
|
402
846
|
execute: async (args) => {
|
|
403
847
|
const operation = args.operation;
|
|
404
848
|
const skillName = args.skillName;
|
|
@@ -664,4 +1108,4 @@ var SkillImporter = class {
|
|
|
664
1108
|
};
|
|
665
1109
|
|
|
666
1110
|
//#endregion
|
|
667
|
-
export { AgentWorker
|
|
1111
|
+
export { AgentWorker, ClaudeCodeBackend, CodexBackend, CursorBackend, FEEDBACK_PROMPT, FRONTIER_MODELS, MockAIBackend, SUPPORTED_PROVIDERS, SdkBackend, SkillImporter, SkillsProvider, buildGitUrl, checkBackends, createBackend, createBashTool, createBashTools, createBashToolsFromDirectory, createBashToolsFromFiles, createFeedbackTool, createMockBackend, createModel, createModelAsync, createSkillsTool, getSpecDisplayName, listBackends, parseImportSpec };
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as DefaultDocumentStore, D as MemoryStorage, O as ContextProviderImpl, S as DefaultResourceStore, T as DefaultChannelStore, w as DefaultInboxStore, x as DefaultStatusStore } from "./cli/index.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/workflow/context/memory-provider.ts
|
|
4
4
|
/**
|
|
5
5
|
* In-memory ContextProvider for testing.
|
|
6
|
-
* All domain logic is
|
|
6
|
+
* All domain logic is in the composed stores;
|
|
7
7
|
* this class adds test helpers for inspection and cleanup.
|
|
8
8
|
*/
|
|
9
9
|
var MemoryContextProvider = class extends ContextProviderImpl {
|
|
10
10
|
memoryStorage;
|
|
11
11
|
constructor(validAgents) {
|
|
12
12
|
const storage = new MemoryStorage();
|
|
13
|
-
|
|
13
|
+
const channel = new DefaultChannelStore(storage, validAgents);
|
|
14
|
+
const inbox = new DefaultInboxStore(channel, storage);
|
|
15
|
+
const documents = new DefaultDocumentStore(storage);
|
|
16
|
+
const resources = new DefaultResourceStore(storage);
|
|
17
|
+
const status = new DefaultStatusStore(storage);
|
|
18
|
+
super(channel, inbox, documents, resources, status, validAgents);
|
|
14
19
|
this.memoryStorage = storage;
|
|
15
20
|
}
|
|
16
21
|
/** Get underlying MemoryStorage (for testing) */
|