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.
@@ -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,4 @@
1
+ import "./models-FOOpWB91.mjs";
2
+ import { a as CursorCliBackend, i as SdkBackend, n as createBackend, o as CodexCliBackend, r as listBackends, s as ClaudeCliBackend, t as checkBackends } from "./backends-BklSbwcH.mjs";
3
+
4
+ export { listBackends };
@@ -0,0 +1 @@
1
+ export { };