agent-worker 0.1.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/dist/backends-BklSbwcH.mjs +381 -0
- package/dist/backends-BqaAh6cC.mjs +4 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.mjs +867 -0
- package/dist/index.d.mts +572 -0
- package/dist/index.mjs +121 -0
- package/dist/models-FOOpWB91.mjs +182 -0
- package/dist/session-DQQAmPf-.mjs +419 -0
- package/package.json +85 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { i as createModelAsync, r as createModel } from "./models-FOOpWB91.mjs";
|
|
2
|
+
import { generateText } from "ai";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
|
|
5
|
+
//#region src/backends/claude-cli.ts
|
|
6
|
+
/**
|
|
7
|
+
* Claude Code CLI backend
|
|
8
|
+
* Uses `claude -p` for non-interactive mode
|
|
9
|
+
*
|
|
10
|
+
* @see https://code.claude.com/docs/en/headless
|
|
11
|
+
*/
|
|
12
|
+
var ClaudeCliBackend = class {
|
|
13
|
+
type = "claude";
|
|
14
|
+
options;
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
}
|
|
18
|
+
async send(message, options) {
|
|
19
|
+
const args = this.buildArgs(message, options);
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const proc = spawn("claude", args, {
|
|
22
|
+
cwd: this.options.cwd,
|
|
23
|
+
env: process.env
|
|
24
|
+
});
|
|
25
|
+
let stdout = "";
|
|
26
|
+
let stderr = "";
|
|
27
|
+
proc.stdout.on("data", (data) => {
|
|
28
|
+
stdout += data.toString();
|
|
29
|
+
});
|
|
30
|
+
proc.stderr.on("data", (data) => {
|
|
31
|
+
stderr += data.toString();
|
|
32
|
+
});
|
|
33
|
+
proc.on("close", (code) => {
|
|
34
|
+
if (code !== 0) {
|
|
35
|
+
reject(/* @__PURE__ */ new Error(`claude exited with code ${code}: ${stderr}`));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (this.options.outputFormat === "json") try {
|
|
39
|
+
const parsed = JSON.parse(stdout);
|
|
40
|
+
resolve({
|
|
41
|
+
content: parsed.content || parsed.result || stdout,
|
|
42
|
+
toolCalls: parsed.toolCalls,
|
|
43
|
+
usage: parsed.usage
|
|
44
|
+
});
|
|
45
|
+
} catch {
|
|
46
|
+
resolve({ content: stdout.trim() });
|
|
47
|
+
}
|
|
48
|
+
else resolve({ content: stdout.trim() });
|
|
49
|
+
});
|
|
50
|
+
proc.on("error", (err) => {
|
|
51
|
+
reject(/* @__PURE__ */ new Error(`Failed to spawn claude: ${err.message}`));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async isAvailable() {
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
const proc = spawn("claude", ["--version"], { stdio: "pipe" });
|
|
58
|
+
proc.on("close", (code) => resolve(code === 0));
|
|
59
|
+
proc.on("error", () => resolve(false));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
getInfo() {
|
|
63
|
+
return {
|
|
64
|
+
name: "Claude Code CLI",
|
|
65
|
+
model: this.options.model
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
buildArgs(message, options) {
|
|
69
|
+
const args = ["-p", message];
|
|
70
|
+
if (this.options.model) args.push("--model", this.options.model);
|
|
71
|
+
if (options?.system || this.options.appendSystemPrompt) {
|
|
72
|
+
const system = options?.system || this.options.appendSystemPrompt;
|
|
73
|
+
args.push("--append-system-prompt", system);
|
|
74
|
+
}
|
|
75
|
+
if (this.options.allowedTools?.length) args.push("--allowed-tools", this.options.allowedTools.join(","));
|
|
76
|
+
if (this.options.outputFormat) args.push("--output-format", this.options.outputFormat);
|
|
77
|
+
if (this.options.continue) args.push("--continue");
|
|
78
|
+
if (this.options.resume) args.push("--resume", this.options.resume);
|
|
79
|
+
return args;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/backends/codex-cli.ts
|
|
85
|
+
/**
|
|
86
|
+
* OpenAI Codex CLI backend
|
|
87
|
+
* Uses `codex exec` for non-interactive mode
|
|
88
|
+
*
|
|
89
|
+
* @see https://developers.openai.com/codex/noninteractive/
|
|
90
|
+
*/
|
|
91
|
+
var CodexCliBackend = class {
|
|
92
|
+
type = "codex";
|
|
93
|
+
options;
|
|
94
|
+
constructor(options = {}) {
|
|
95
|
+
this.options = options;
|
|
96
|
+
}
|
|
97
|
+
async send(message, _options) {
|
|
98
|
+
const args = this.buildArgs(message);
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
const proc = spawn("codex", args, {
|
|
101
|
+
cwd: this.options.cwd,
|
|
102
|
+
env: process.env
|
|
103
|
+
});
|
|
104
|
+
let stdout = "";
|
|
105
|
+
let stderr = "";
|
|
106
|
+
proc.stdout.on("data", (data) => {
|
|
107
|
+
stdout += data.toString();
|
|
108
|
+
});
|
|
109
|
+
proc.stderr.on("data", (data) => {
|
|
110
|
+
stderr += data.toString();
|
|
111
|
+
});
|
|
112
|
+
proc.on("close", (code) => {
|
|
113
|
+
if (code !== 0) {
|
|
114
|
+
reject(/* @__PURE__ */ new Error(`codex exited with code ${code}: ${stderr}`));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (this.options.json) try {
|
|
118
|
+
const lines = stdout.trim().split("\n");
|
|
119
|
+
const lastEvent = JSON.parse(lines[lines.length - 1]);
|
|
120
|
+
resolve({
|
|
121
|
+
content: lastEvent.message || lastEvent.content || stdout,
|
|
122
|
+
toolCalls: lastEvent.toolCalls,
|
|
123
|
+
usage: lastEvent.usage
|
|
124
|
+
});
|
|
125
|
+
} catch {
|
|
126
|
+
resolve({ content: stdout.trim() });
|
|
127
|
+
}
|
|
128
|
+
else resolve({ content: stdout.trim() });
|
|
129
|
+
});
|
|
130
|
+
proc.on("error", (err) => {
|
|
131
|
+
reject(/* @__PURE__ */ new Error(`Failed to spawn codex: ${err.message}`));
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async isAvailable() {
|
|
136
|
+
return new Promise((resolve) => {
|
|
137
|
+
const proc = spawn("codex", ["--version"], { stdio: "pipe" });
|
|
138
|
+
proc.on("close", (code) => resolve(code === 0));
|
|
139
|
+
proc.on("error", () => resolve(false));
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
getInfo() {
|
|
143
|
+
return {
|
|
144
|
+
name: "OpenAI Codex CLI",
|
|
145
|
+
model: this.options.model
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
buildArgs(message) {
|
|
149
|
+
const args = ["exec", message];
|
|
150
|
+
if (this.options.model) args.push("--model", this.options.model);
|
|
151
|
+
if (this.options.json) args.push("--json");
|
|
152
|
+
if (this.options.skipGitRepoCheck) args.push("--skip-git-repo-check");
|
|
153
|
+
if (this.options.approvalMode) args.push("--approval-mode", this.options.approvalMode);
|
|
154
|
+
if (this.options.resume) args.push("--resume", this.options.resume);
|
|
155
|
+
return args;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/backends/cursor-cli.ts
|
|
161
|
+
/**
|
|
162
|
+
* Cursor CLI backend
|
|
163
|
+
* Uses `cursor-agent -p` or `agent chat` for non-interactive mode
|
|
164
|
+
*
|
|
165
|
+
* @see https://cursor.com/docs/cli/headless
|
|
166
|
+
*/
|
|
167
|
+
var CursorCliBackend = class {
|
|
168
|
+
type = "cursor";
|
|
169
|
+
options;
|
|
170
|
+
constructor(options = {}) {
|
|
171
|
+
this.options = {
|
|
172
|
+
timeout: 12e4,
|
|
173
|
+
...options
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
async send(message, _options) {
|
|
177
|
+
const { command, args } = this.buildCommand(message);
|
|
178
|
+
return new Promise((resolve, reject) => {
|
|
179
|
+
const proc = spawn(command, args, {
|
|
180
|
+
cwd: this.options.cwd,
|
|
181
|
+
env: process.env
|
|
182
|
+
});
|
|
183
|
+
let stdout = "";
|
|
184
|
+
let stderr = "";
|
|
185
|
+
let timedOut = false;
|
|
186
|
+
const timer = setTimeout(() => {
|
|
187
|
+
timedOut = true;
|
|
188
|
+
proc.kill("SIGTERM");
|
|
189
|
+
}, this.options.timeout);
|
|
190
|
+
proc.stdout.on("data", (data) => {
|
|
191
|
+
stdout += data.toString();
|
|
192
|
+
});
|
|
193
|
+
proc.stderr.on("data", (data) => {
|
|
194
|
+
stderr += data.toString();
|
|
195
|
+
});
|
|
196
|
+
proc.on("close", (code) => {
|
|
197
|
+
clearTimeout(timer);
|
|
198
|
+
if (timedOut) {
|
|
199
|
+
reject(/* @__PURE__ */ new Error(`cursor-agent timed out after ${this.options.timeout}ms`));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (code !== 0 && code !== null) {
|
|
203
|
+
reject(/* @__PURE__ */ new Error(`cursor-agent exited with code ${code}: ${stderr}`));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
resolve({ content: stdout.trim() });
|
|
207
|
+
});
|
|
208
|
+
proc.on("error", (err) => {
|
|
209
|
+
clearTimeout(timer);
|
|
210
|
+
reject(/* @__PURE__ */ new Error(`Failed to spawn cursor-agent: ${err.message}`));
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
async isAvailable() {
|
|
215
|
+
for (const cmd of ["cursor-agent", "agent"]) if (await this.checkCommand(cmd)) return true;
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
async checkCommand(command) {
|
|
219
|
+
return new Promise((resolve) => {
|
|
220
|
+
const proc = spawn(command, ["--version"], { stdio: "pipe" });
|
|
221
|
+
const timer = setTimeout(() => {
|
|
222
|
+
proc.kill();
|
|
223
|
+
resolve(false);
|
|
224
|
+
}, 5e3);
|
|
225
|
+
proc.on("close", (code) => {
|
|
226
|
+
clearTimeout(timer);
|
|
227
|
+
resolve(code === 0);
|
|
228
|
+
});
|
|
229
|
+
proc.on("error", () => {
|
|
230
|
+
clearTimeout(timer);
|
|
231
|
+
resolve(false);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
getInfo() {
|
|
236
|
+
return {
|
|
237
|
+
name: "Cursor Agent CLI",
|
|
238
|
+
model: this.options.model
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
buildCommand(message) {
|
|
242
|
+
if (this.options.useAgentCommand) return {
|
|
243
|
+
command: "agent",
|
|
244
|
+
args: ["chat", message]
|
|
245
|
+
};
|
|
246
|
+
const args = ["-p", message];
|
|
247
|
+
if (this.options.model) args.push("--model", this.options.model);
|
|
248
|
+
return {
|
|
249
|
+
command: "cursor-agent",
|
|
250
|
+
args
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
//#endregion
|
|
256
|
+
//#region src/backends/sdk.ts
|
|
257
|
+
/**
|
|
258
|
+
* Vercel AI SDK backend
|
|
259
|
+
* Uses the AI SDK for direct API access
|
|
260
|
+
*/
|
|
261
|
+
var SdkBackend = class {
|
|
262
|
+
type = "sdk";
|
|
263
|
+
modelId;
|
|
264
|
+
model = null;
|
|
265
|
+
maxTokens;
|
|
266
|
+
constructor(options) {
|
|
267
|
+
this.modelId = options.model;
|
|
268
|
+
this.maxTokens = options.maxTokens ?? 4096;
|
|
269
|
+
try {
|
|
270
|
+
this.model = createModel(this.modelId);
|
|
271
|
+
} catch {}
|
|
272
|
+
}
|
|
273
|
+
async send(message, options) {
|
|
274
|
+
if (!this.model) this.model = await createModelAsync(this.modelId);
|
|
275
|
+
const result = await generateText({
|
|
276
|
+
model: this.model,
|
|
277
|
+
system: options?.system,
|
|
278
|
+
prompt: message,
|
|
279
|
+
maxTokens: this.maxTokens
|
|
280
|
+
});
|
|
281
|
+
return {
|
|
282
|
+
content: result.text,
|
|
283
|
+
usage: {
|
|
284
|
+
input: result.usage.promptTokens,
|
|
285
|
+
output: result.usage.completionTokens,
|
|
286
|
+
total: result.usage.totalTokens
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
async isAvailable() {
|
|
291
|
+
try {
|
|
292
|
+
if (!this.model) this.model = await createModelAsync(this.modelId);
|
|
293
|
+
return true;
|
|
294
|
+
} catch {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
getInfo() {
|
|
299
|
+
return {
|
|
300
|
+
name: "Vercel AI SDK",
|
|
301
|
+
model: this.modelId
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region src/backends/index.ts
|
|
308
|
+
/**
|
|
309
|
+
* Create a backend instance
|
|
310
|
+
*/
|
|
311
|
+
function createBackend(config) {
|
|
312
|
+
switch (config.type) {
|
|
313
|
+
case "sdk": return new SdkBackend({
|
|
314
|
+
model: config.model,
|
|
315
|
+
maxTokens: config.maxTokens
|
|
316
|
+
});
|
|
317
|
+
case "claude": return new ClaudeCliBackend({
|
|
318
|
+
...config.options,
|
|
319
|
+
model: config.model
|
|
320
|
+
});
|
|
321
|
+
case "codex": return new CodexCliBackend({
|
|
322
|
+
...config.options,
|
|
323
|
+
model: config.model
|
|
324
|
+
});
|
|
325
|
+
case "cursor": return new CursorCliBackend({
|
|
326
|
+
...config.options,
|
|
327
|
+
model: config.model
|
|
328
|
+
});
|
|
329
|
+
default: throw new Error(`Unknown backend type: ${config.type}`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Check which backends are available
|
|
334
|
+
*/
|
|
335
|
+
async function checkBackends() {
|
|
336
|
+
const claude = new ClaudeCliBackend();
|
|
337
|
+
const codex = new CodexCliBackend();
|
|
338
|
+
const cursor = new CursorCliBackend();
|
|
339
|
+
const [claudeAvailable, codexAvailable, cursorAvailable] = await Promise.all([
|
|
340
|
+
claude.isAvailable(),
|
|
341
|
+
codex.isAvailable(),
|
|
342
|
+
cursor.isAvailable()
|
|
343
|
+
]);
|
|
344
|
+
return {
|
|
345
|
+
sdk: true,
|
|
346
|
+
claude: claudeAvailable,
|
|
347
|
+
codex: codexAvailable,
|
|
348
|
+
cursor: cursorAvailable
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* List available backends with info
|
|
353
|
+
*/
|
|
354
|
+
async function listBackends() {
|
|
355
|
+
const availability = await checkBackends();
|
|
356
|
+
return [
|
|
357
|
+
{
|
|
358
|
+
type: "sdk",
|
|
359
|
+
available: availability.sdk,
|
|
360
|
+
name: "Vercel AI SDK"
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
type: "claude",
|
|
364
|
+
available: availability.claude,
|
|
365
|
+
name: "Claude Code CLI"
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
type: "codex",
|
|
369
|
+
available: availability.codex,
|
|
370
|
+
name: "OpenAI Codex CLI"
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
type: "cursor",
|
|
374
|
+
available: availability.cursor,
|
|
375
|
+
name: "Cursor Agent CLI"
|
|
376
|
+
}
|
|
377
|
+
];
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
//#endregion
|
|
381
|
+
export { CursorCliBackend as a, SdkBackend as i, createBackend as n, CodexCliBackend as o, listBackends as r, ClaudeCliBackend as s, checkBackends as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|