agent-worker 0.4.0 → 0.6.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-DenGdkrj.mjs → backends-BJyk6zvs.mjs} +434 -53
- package/dist/backends-fLwD_6G_.mjs +3 -0
- package/dist/cli/index.mjs +64 -12
- package/dist/context-DW7xrslO.mjs +4 -0
- package/dist/index.d.mts +20 -11
- package/dist/index.mjs +2 -2
- package/dist/logger-L9AtbIPS.mjs +63 -0
- package/dist/{mcp-server-DtIApaBD.mjs → mcp-server-ONSDOpt5.mjs} +3 -11
- package/dist/{skills-VyC7eQyK.mjs → skills-CuAfAkHU.mjs} +1 -1
- package/dist/{workflow-CaRCNEh6.mjs → workflow-C26F4PpH.mjs} +25 -87
- package/package.json +1 -1
- package/dist/backends-D3MAlJBX.mjs +0 -3
- package/dist/context-C7nBmU5D.mjs +0 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { gateway, generateText } from "ai";
|
|
2
|
-
import {
|
|
2
|
+
import { execa } from "execa";
|
|
3
3
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { stringify } from "yaml";
|
|
@@ -297,6 +297,335 @@ function parseModel(model) {
|
|
|
297
297
|
};
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
+
//#endregion
|
|
301
|
+
//#region src/backends/idle-timeout.ts
|
|
302
|
+
/**
|
|
303
|
+
* Idle timeout for CLI subprocess execution
|
|
304
|
+
*
|
|
305
|
+
* Unlike a hard timeout (kill after N ms total), an idle timeout only fires
|
|
306
|
+
* when the process produces no stdout/stderr output for the configured duration.
|
|
307
|
+
* This allows long-running agent tasks to continue as long as they're actively
|
|
308
|
+
* producing output (tool calls, analysis, etc.).
|
|
309
|
+
*/
|
|
310
|
+
/**
|
|
311
|
+
* Execute a command with idle timeout.
|
|
312
|
+
*
|
|
313
|
+
* The timeout resets every time the process writes to stdout or stderr.
|
|
314
|
+
* If the process goes silent for longer than `timeout` ms, it's killed.
|
|
315
|
+
*/
|
|
316
|
+
/** Minimum idle timeout to prevent accidental instant kills */
|
|
317
|
+
const MIN_TIMEOUT_MS = 1e3;
|
|
318
|
+
async function execWithIdleTimeout(options) {
|
|
319
|
+
const { command, args, cwd, onStdout } = options;
|
|
320
|
+
const timeout = Math.max(options.timeout, MIN_TIMEOUT_MS);
|
|
321
|
+
let idleTimedOut = false;
|
|
322
|
+
let timer;
|
|
323
|
+
let stdout = "";
|
|
324
|
+
let stderr = "";
|
|
325
|
+
const subprocess = execa(command, args, {
|
|
326
|
+
cwd,
|
|
327
|
+
stdin: "ignore",
|
|
328
|
+
buffer: false
|
|
329
|
+
});
|
|
330
|
+
const resetTimer = () => {
|
|
331
|
+
clearTimeout(timer);
|
|
332
|
+
timer = setTimeout(() => {
|
|
333
|
+
idleTimedOut = true;
|
|
334
|
+
subprocess.kill();
|
|
335
|
+
}, timeout);
|
|
336
|
+
};
|
|
337
|
+
subprocess.stdout?.on("data", (chunk) => {
|
|
338
|
+
const text = chunk.toString();
|
|
339
|
+
stdout += text;
|
|
340
|
+
if (onStdout) onStdout(text);
|
|
341
|
+
resetTimer();
|
|
342
|
+
});
|
|
343
|
+
subprocess.stderr?.on("data", (chunk) => {
|
|
344
|
+
stderr += chunk.toString();
|
|
345
|
+
resetTimer();
|
|
346
|
+
});
|
|
347
|
+
resetTimer();
|
|
348
|
+
try {
|
|
349
|
+
await subprocess;
|
|
350
|
+
clearTimeout(timer);
|
|
351
|
+
return {
|
|
352
|
+
stdout: stdout.trimEnd(),
|
|
353
|
+
stderr: stderr.trimEnd()
|
|
354
|
+
};
|
|
355
|
+
} catch (error) {
|
|
356
|
+
clearTimeout(timer);
|
|
357
|
+
if (idleTimedOut) throw new IdleTimeoutError(timeout, stdout, stderr);
|
|
358
|
+
throw error;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Execute a command with idle timeout and return abort controller
|
|
363
|
+
* This version returns both the promise and an abort function for external control
|
|
364
|
+
*/
|
|
365
|
+
function execWithIdleTimeoutAbortable(options) {
|
|
366
|
+
const { command, args, cwd, onStdout } = options;
|
|
367
|
+
const timeout = Math.max(options.timeout, MIN_TIMEOUT_MS);
|
|
368
|
+
let idleTimedOut = false;
|
|
369
|
+
let timer;
|
|
370
|
+
let stdout = "";
|
|
371
|
+
let stderr = "";
|
|
372
|
+
let isAborted = false;
|
|
373
|
+
const subprocess = execa(command, args, {
|
|
374
|
+
cwd,
|
|
375
|
+
stdin: "ignore",
|
|
376
|
+
buffer: false
|
|
377
|
+
});
|
|
378
|
+
const resetTimer = () => {
|
|
379
|
+
clearTimeout(timer);
|
|
380
|
+
timer = setTimeout(() => {
|
|
381
|
+
idleTimedOut = true;
|
|
382
|
+
subprocess.kill();
|
|
383
|
+
}, timeout);
|
|
384
|
+
};
|
|
385
|
+
subprocess.stdout?.on("data", (chunk) => {
|
|
386
|
+
const text = chunk.toString();
|
|
387
|
+
stdout += text;
|
|
388
|
+
if (onStdout) onStdout(text);
|
|
389
|
+
resetTimer();
|
|
390
|
+
});
|
|
391
|
+
subprocess.stderr?.on("data", (chunk) => {
|
|
392
|
+
stderr += chunk.toString();
|
|
393
|
+
resetTimer();
|
|
394
|
+
});
|
|
395
|
+
resetTimer();
|
|
396
|
+
const abort = () => {
|
|
397
|
+
if (!isAborted) {
|
|
398
|
+
isAborted = true;
|
|
399
|
+
clearTimeout(timer);
|
|
400
|
+
subprocess.kill("SIGTERM");
|
|
401
|
+
setTimeout(() => {
|
|
402
|
+
if (!subprocess.killed) subprocess.kill("SIGKILL");
|
|
403
|
+
}, 1e3);
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
return {
|
|
407
|
+
promise: (async () => {
|
|
408
|
+
try {
|
|
409
|
+
await subprocess;
|
|
410
|
+
clearTimeout(timer);
|
|
411
|
+
return {
|
|
412
|
+
stdout: stdout.trimEnd(),
|
|
413
|
+
stderr: stderr.trimEnd()
|
|
414
|
+
};
|
|
415
|
+
} catch (error) {
|
|
416
|
+
clearTimeout(timer);
|
|
417
|
+
if (isAborted) throw new Error("Process aborted by user");
|
|
418
|
+
if (idleTimedOut) throw new IdleTimeoutError(timeout, stdout, stderr);
|
|
419
|
+
throw error;
|
|
420
|
+
}
|
|
421
|
+
})(),
|
|
422
|
+
abort
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Error thrown when a process is killed due to idle timeout
|
|
427
|
+
*/
|
|
428
|
+
var IdleTimeoutError = class extends Error {
|
|
429
|
+
timeout;
|
|
430
|
+
stdout;
|
|
431
|
+
stderr;
|
|
432
|
+
constructor(timeout, stdout, stderr) {
|
|
433
|
+
super(`Process idle timed out after ${timeout}ms of inactivity`);
|
|
434
|
+
this.name = "IdleTimeoutError";
|
|
435
|
+
this.timeout = timeout;
|
|
436
|
+
this.stdout = stdout;
|
|
437
|
+
this.stderr = stderr;
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
//#endregion
|
|
442
|
+
//#region src/backends/stream-json.ts
|
|
443
|
+
/**
|
|
444
|
+
* Format a standard StreamEvent into a human-readable progress message.
|
|
445
|
+
* Returns null if the event doesn't need display.
|
|
446
|
+
*
|
|
447
|
+
* This function only knows about StreamEvent — it never touches
|
|
448
|
+
* backend-specific raw JSON. Format-specific conversion is handled
|
|
449
|
+
* by the EventAdapter.
|
|
450
|
+
*/
|
|
451
|
+
function formatEvent(event, backendName) {
|
|
452
|
+
switch (event.kind) {
|
|
453
|
+
case "init": {
|
|
454
|
+
const details = [];
|
|
455
|
+
if (event.model) details.push(`model: ${event.model}`);
|
|
456
|
+
if (event.sessionId) details.push(`session: ${event.sessionId}`);
|
|
457
|
+
return `${backendName} initialized${details.length > 0 ? ` (${details.join(", ")})` : ""}`;
|
|
458
|
+
}
|
|
459
|
+
case "tool_call": {
|
|
460
|
+
const truncated = event.args.length > 100 ? event.args.slice(0, 100) + "..." : event.args;
|
|
461
|
+
return `CALL ${event.name}(${truncated})`;
|
|
462
|
+
}
|
|
463
|
+
case "completed": {
|
|
464
|
+
const parts = [backendName, "completed"];
|
|
465
|
+
const details = [];
|
|
466
|
+
if (event.durationMs) details.push(`${(event.durationMs / 1e3).toFixed(1)}s`);
|
|
467
|
+
if (event.costUsd) details.push(`$${event.costUsd.toFixed(4)}`);
|
|
468
|
+
if (event.usage) details.push(`${event.usage.input} in, ${event.usage.output} out`);
|
|
469
|
+
if (details.length > 0) parts.push(`(${details.join(", ")})`);
|
|
470
|
+
return parts.join(" ");
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Adapter for Claude/Cursor stream-json format.
|
|
476
|
+
*
|
|
477
|
+
* Events:
|
|
478
|
+
* { type: "system", subtype: "init", model: "..." }
|
|
479
|
+
* { type: "assistant", message: { content: [{ type: "tool_use", name, input }] } }
|
|
480
|
+
* { type: "result", duration_ms: N, total_cost_usd: N }
|
|
481
|
+
*/
|
|
482
|
+
const claudeAdapter = (raw) => {
|
|
483
|
+
const type = raw.type;
|
|
484
|
+
if (type === "system" && raw.subtype === "init") return {
|
|
485
|
+
kind: "init",
|
|
486
|
+
model: raw.model || void 0,
|
|
487
|
+
sessionId: raw.session_id
|
|
488
|
+
};
|
|
489
|
+
if (type === "assistant") {
|
|
490
|
+
const message = raw.message;
|
|
491
|
+
if (!message?.content) return null;
|
|
492
|
+
const toolCalls = message.content.filter((c) => c.type === "tool_use");
|
|
493
|
+
if (toolCalls.length > 0) {
|
|
494
|
+
const tc = toolCalls[0];
|
|
495
|
+
return {
|
|
496
|
+
kind: "tool_call",
|
|
497
|
+
name: tc.name || "unknown",
|
|
498
|
+
args: formatToolInput(tc.input)
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
return null;
|
|
502
|
+
}
|
|
503
|
+
if (type === "result") return {
|
|
504
|
+
kind: "completed",
|
|
505
|
+
durationMs: raw.duration_ms,
|
|
506
|
+
costUsd: raw.total_cost_usd
|
|
507
|
+
};
|
|
508
|
+
return null;
|
|
509
|
+
};
|
|
510
|
+
/**
|
|
511
|
+
* Extract final result from Claude/Cursor stream-json output.
|
|
512
|
+
*
|
|
513
|
+
* Priority:
|
|
514
|
+
* 1. type=result with result field
|
|
515
|
+
* 2. Last assistant message with text content
|
|
516
|
+
* 3. Raw stdout fallback
|
|
517
|
+
*/
|
|
518
|
+
function extractClaudeResult(stdout) {
|
|
519
|
+
const lines = stdout.trim().split("\n");
|
|
520
|
+
for (let i = lines.length - 1; i >= 0; i--) try {
|
|
521
|
+
const event = JSON.parse(lines[i]);
|
|
522
|
+
if (event.type === "result" && event.result) return { content: event.result };
|
|
523
|
+
} catch {}
|
|
524
|
+
for (let i = lines.length - 1; i >= 0; i--) try {
|
|
525
|
+
const event = JSON.parse(lines[i]);
|
|
526
|
+
if (event.type === "assistant" && event.message?.content) {
|
|
527
|
+
const textParts = event.message.content.filter((c) => c.type === "text").map((c) => c.text);
|
|
528
|
+
if (textParts.length > 0) return { content: textParts.join("\n") };
|
|
529
|
+
}
|
|
530
|
+
} catch {}
|
|
531
|
+
return { content: stdout.trim() };
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Adapter for Codex --json format.
|
|
535
|
+
*
|
|
536
|
+
* Events:
|
|
537
|
+
* { type: "thread.started", thread_id: "..." }
|
|
538
|
+
* { type: "item.completed", item: { type: "function_call", name, arguments } }
|
|
539
|
+
* { type: "item.completed", item: { type: "agent_message", text } } → skipped (result only)
|
|
540
|
+
* { type: "turn.completed", usage: { input_tokens, output_tokens } }
|
|
541
|
+
*/
|
|
542
|
+
const codexAdapter = (raw) => {
|
|
543
|
+
const type = raw.type;
|
|
544
|
+
if (type === "thread.started") {
|
|
545
|
+
const threadId = raw.thread_id;
|
|
546
|
+
return {
|
|
547
|
+
kind: "init",
|
|
548
|
+
sessionId: threadId ? `${threadId.slice(0, 8)}...` : void 0
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
if (type === "item.completed") {
|
|
552
|
+
const item = raw.item;
|
|
553
|
+
if (!item) return null;
|
|
554
|
+
if (item.type === "function_call") return {
|
|
555
|
+
kind: "tool_call",
|
|
556
|
+
name: item.name || "unknown",
|
|
557
|
+
args: item.arguments ?? ""
|
|
558
|
+
};
|
|
559
|
+
return null;
|
|
560
|
+
}
|
|
561
|
+
if (type === "turn.completed") {
|
|
562
|
+
const usage = raw.usage;
|
|
563
|
+
return {
|
|
564
|
+
kind: "completed",
|
|
565
|
+
usage: usage ? {
|
|
566
|
+
input: usage.input_tokens ?? 0,
|
|
567
|
+
output: usage.output_tokens ?? 0
|
|
568
|
+
} : void 0
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
return null;
|
|
572
|
+
};
|
|
573
|
+
/**
|
|
574
|
+
* Extract final result from Codex --json output.
|
|
575
|
+
*
|
|
576
|
+
* Priority:
|
|
577
|
+
* 1. Last item.completed with item.type=agent_message
|
|
578
|
+
* 2. Raw stdout fallback
|
|
579
|
+
*/
|
|
580
|
+
function extractCodexResult(stdout) {
|
|
581
|
+
const lines = stdout.trim().split("\n");
|
|
582
|
+
for (let i = lines.length - 1; i >= 0; i--) try {
|
|
583
|
+
const event = JSON.parse(lines[i]);
|
|
584
|
+
if (event.type === "item.completed" && event.item?.type === "agent_message" && event.item?.text) return { content: event.item.text };
|
|
585
|
+
} catch {}
|
|
586
|
+
return { content: stdout.trim() };
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Create a line-buffered stream parser.
|
|
590
|
+
*
|
|
591
|
+
* Accumulates stdout chunks, parses each line through the given adapter,
|
|
592
|
+
* and emits formatted progress messages via debugLog.
|
|
593
|
+
*
|
|
594
|
+
* @param debugLog - Callback for progress messages
|
|
595
|
+
* @param backendName - Display name (e.g., "Cursor", "Claude", "Codex")
|
|
596
|
+
* @param adapter - Format-specific adapter to convert raw JSON → StreamEvent
|
|
597
|
+
*/
|
|
598
|
+
function createStreamParser(debugLog, backendName, adapter) {
|
|
599
|
+
let lineBuf = "";
|
|
600
|
+
return (chunk) => {
|
|
601
|
+
lineBuf += chunk;
|
|
602
|
+
const lines = lineBuf.split("\n");
|
|
603
|
+
lineBuf = lines.pop() ?? "";
|
|
604
|
+
for (const line of lines) {
|
|
605
|
+
if (!line.trim()) continue;
|
|
606
|
+
try {
|
|
607
|
+
const event = adapter(JSON.parse(line));
|
|
608
|
+
if (event) {
|
|
609
|
+
const progress = formatEvent(event, backendName);
|
|
610
|
+
if (progress) debugLog(progress);
|
|
611
|
+
}
|
|
612
|
+
} catch {}
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Format tool call input for display (truncated JSON string)
|
|
618
|
+
*/
|
|
619
|
+
function formatToolInput(input) {
|
|
620
|
+
if (!input || typeof input !== "object") return "";
|
|
621
|
+
try {
|
|
622
|
+
const str = JSON.stringify(input);
|
|
623
|
+
return str.length > 100 ? str.slice(0, 100) + "..." : str;
|
|
624
|
+
} catch {
|
|
625
|
+
return "";
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
300
629
|
//#endregion
|
|
301
630
|
//#region src/backends/claude-code.ts
|
|
302
631
|
/**
|
|
@@ -312,6 +641,7 @@ function parseModel(model) {
|
|
|
312
641
|
var ClaudeCodeBackend = class {
|
|
313
642
|
type = "claude";
|
|
314
643
|
options;
|
|
644
|
+
currentAbort;
|
|
315
645
|
constructor(options = {}) {
|
|
316
646
|
this.options = {
|
|
317
647
|
timeout: 3e5,
|
|
@@ -332,13 +662,22 @@ var ClaudeCodeBackend = class {
|
|
|
332
662
|
async send(message, options) {
|
|
333
663
|
const args = this.buildArgs(message, options);
|
|
334
664
|
const cwd = this.options.workspace || this.options.cwd;
|
|
665
|
+
const debugLog = this.options.debugLog;
|
|
666
|
+
const outputFormat = this.options.outputFormat ?? "stream-json";
|
|
667
|
+
const timeout = this.options.timeout ?? 3e5;
|
|
335
668
|
try {
|
|
336
|
-
const {
|
|
669
|
+
const { promise, abort } = execWithIdleTimeoutAbortable({
|
|
670
|
+
command: "claude",
|
|
671
|
+
args,
|
|
337
672
|
cwd,
|
|
338
|
-
|
|
339
|
-
|
|
673
|
+
timeout,
|
|
674
|
+
onStdout: outputFormat === "stream-json" && debugLog ? createStreamParser(debugLog, "Claude", claudeAdapter) : void 0
|
|
340
675
|
});
|
|
341
|
-
|
|
676
|
+
this.currentAbort = abort;
|
|
677
|
+
const { stdout } = await promise;
|
|
678
|
+
this.currentAbort = void 0;
|
|
679
|
+
if (outputFormat === "stream-json") return extractClaudeResult(stdout);
|
|
680
|
+
if (outputFormat === "json") try {
|
|
342
681
|
const parsed = JSON.parse(stdout);
|
|
343
682
|
return {
|
|
344
683
|
content: parsed.content || parsed.result || stdout,
|
|
@@ -350,7 +689,12 @@ var ClaudeCodeBackend = class {
|
|
|
350
689
|
}
|
|
351
690
|
return { content: stdout.trim() };
|
|
352
691
|
} catch (error) {
|
|
353
|
-
|
|
692
|
+
this.currentAbort = void 0;
|
|
693
|
+
if (error instanceof IdleTimeoutError) throw new Error(`claude timed out after ${timeout}ms of inactivity`);
|
|
694
|
+
if (error && typeof error === "object" && "exitCode" in error) {
|
|
695
|
+
const execError = error;
|
|
696
|
+
throw new Error(`claude failed (exit ${execError.exitCode}): ${execError.stderr || execError.shortMessage}`);
|
|
697
|
+
}
|
|
354
698
|
throw error;
|
|
355
699
|
}
|
|
356
700
|
}
|
|
@@ -383,7 +727,9 @@ var ClaudeCodeBackend = class {
|
|
|
383
727
|
args.push("--append-system-prompt", system);
|
|
384
728
|
}
|
|
385
729
|
if (this.options.allowedTools?.length) args.push("--allowed-tools", this.options.allowedTools.join(","));
|
|
386
|
-
|
|
730
|
+
const outputFormat = this.options.outputFormat ?? "stream-json";
|
|
731
|
+
args.push("--output-format", outputFormat);
|
|
732
|
+
if (outputFormat === "stream-json") args.push("--verbose");
|
|
387
733
|
if (this.options.continue) args.push("--continue");
|
|
388
734
|
if (this.options.resume) args.push("--resume", this.options.resume);
|
|
389
735
|
if (this.options.mcpConfigPath) args.push("--mcp-config", this.options.mcpConfigPath);
|
|
@@ -395,13 +741,22 @@ var ClaudeCodeBackend = class {
|
|
|
395
741
|
setMcpConfigPath(path) {
|
|
396
742
|
this.options.mcpConfigPath = path;
|
|
397
743
|
}
|
|
744
|
+
/**
|
|
745
|
+
* Abort any running claude process
|
|
746
|
+
*/
|
|
747
|
+
abort() {
|
|
748
|
+
if (this.currentAbort) {
|
|
749
|
+
this.currentAbort();
|
|
750
|
+
this.currentAbort = void 0;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
398
753
|
};
|
|
399
754
|
|
|
400
755
|
//#endregion
|
|
401
756
|
//#region src/backends/codex.ts
|
|
402
757
|
/**
|
|
403
758
|
* OpenAI Codex CLI backend
|
|
404
|
-
* Uses `codex exec` for non-interactive mode
|
|
759
|
+
* Uses `codex exec` for non-interactive mode with JSON event output
|
|
405
760
|
*
|
|
406
761
|
* MCP Configuration:
|
|
407
762
|
* Codex uses project-level MCP config. Use setWorkspace() to set up
|
|
@@ -432,28 +787,23 @@ var CodexBackend = class {
|
|
|
432
787
|
async send(message, _options) {
|
|
433
788
|
const args = this.buildArgs(message);
|
|
434
789
|
const cwd = this.options.workspace || this.options.cwd;
|
|
790
|
+
const debugLog = this.options.debugLog;
|
|
791
|
+
const timeout = this.options.timeout ?? 3e5;
|
|
435
792
|
try {
|
|
436
|
-
const { stdout } = await
|
|
793
|
+
const { stdout } = await execWithIdleTimeout({
|
|
794
|
+
command: "codex",
|
|
795
|
+
args,
|
|
437
796
|
cwd,
|
|
438
|
-
|
|
439
|
-
|
|
797
|
+
timeout,
|
|
798
|
+
onStdout: debugLog ? createStreamParser(debugLog, "Codex", codexAdapter) : void 0
|
|
440
799
|
});
|
|
441
|
-
|
|
442
|
-
const lines = stdout.trim().split("\n");
|
|
443
|
-
const lastLine = lines[lines.length - 1];
|
|
444
|
-
if (!lastLine) return { content: stdout.trim() };
|
|
445
|
-
const lastEvent = JSON.parse(lastLine);
|
|
446
|
-
return {
|
|
447
|
-
content: lastEvent.message || lastEvent.content || stdout,
|
|
448
|
-
toolCalls: lastEvent.toolCalls,
|
|
449
|
-
usage: lastEvent.usage
|
|
450
|
-
};
|
|
451
|
-
} catch {
|
|
452
|
-
return { content: stdout.trim() };
|
|
453
|
-
}
|
|
454
|
-
return { content: stdout.trim() };
|
|
800
|
+
return extractCodexResult(stdout);
|
|
455
801
|
} catch (error) {
|
|
456
|
-
if (error instanceof
|
|
802
|
+
if (error instanceof IdleTimeoutError) throw new Error(`codex timed out after ${timeout}ms of inactivity`);
|
|
803
|
+
if (error && typeof error === "object" && "exitCode" in error) {
|
|
804
|
+
const execError = error;
|
|
805
|
+
throw new Error(`codex failed (exit ${execError.exitCode}): ${execError.stderr || execError.shortMessage}`);
|
|
806
|
+
}
|
|
457
807
|
throw error;
|
|
458
808
|
}
|
|
459
809
|
}
|
|
@@ -477,13 +827,12 @@ var CodexBackend = class {
|
|
|
477
827
|
buildArgs(message) {
|
|
478
828
|
const args = [
|
|
479
829
|
"exec",
|
|
480
|
-
"--
|
|
830
|
+
"--full-auto",
|
|
831
|
+
"--json",
|
|
832
|
+
"--skip-git-repo-check",
|
|
481
833
|
message
|
|
482
834
|
];
|
|
483
835
|
if (this.options.model) args.push("--model", this.options.model);
|
|
484
|
-
if (this.options.json) args.push("--json");
|
|
485
|
-
if (this.options.skipGitRepoCheck) args.push("--skip-git-repo-check");
|
|
486
|
-
if (this.options.approvalMode) args.push("--approval-mode", this.options.approvalMode);
|
|
487
836
|
if (this.options.resume) args.push("--resume", this.options.resume);
|
|
488
837
|
return args;
|
|
489
838
|
}
|
|
@@ -493,7 +842,8 @@ var CodexBackend = class {
|
|
|
493
842
|
//#region src/backends/cursor.ts
|
|
494
843
|
/**
|
|
495
844
|
* Cursor CLI backend
|
|
496
|
-
* Uses `cursor
|
|
845
|
+
* Uses `cursor agent -p` (preferred) or `cursor-agent -p` (fallback)
|
|
846
|
+
* for non-interactive mode with stream-json output
|
|
497
847
|
*
|
|
498
848
|
* MCP Configuration:
|
|
499
849
|
* Cursor uses project-level MCP config via .cursor/mcp.json in the workspace.
|
|
@@ -504,9 +854,11 @@ var CodexBackend = class {
|
|
|
504
854
|
var CursorBackend = class {
|
|
505
855
|
type = "cursor";
|
|
506
856
|
options;
|
|
857
|
+
/** Resolved command: "cursor" (subcommand style) or "cursor-agent" (standalone) */
|
|
858
|
+
resolvedCommand = null;
|
|
507
859
|
constructor(options = {}) {
|
|
508
860
|
this.options = {
|
|
509
|
-
timeout:
|
|
861
|
+
timeout: 3e5,
|
|
510
862
|
...options
|
|
511
863
|
};
|
|
512
864
|
}
|
|
@@ -521,32 +873,30 @@ var CursorBackend = class {
|
|
|
521
873
|
writeFileSync(join(cursorDir, "mcp.json"), JSON.stringify(mcpConfig, null, 2));
|
|
522
874
|
}
|
|
523
875
|
async send(message, _options) {
|
|
524
|
-
const { command, args } = this.buildCommand(message);
|
|
876
|
+
const { command, args } = await this.buildCommand(message);
|
|
525
877
|
const cwd = this.options.workspace || this.options.cwd;
|
|
878
|
+
const debugLog = this.options.debugLog;
|
|
879
|
+
const timeout = this.options.timeout ?? 3e5;
|
|
526
880
|
try {
|
|
527
|
-
const { stdout } = await
|
|
881
|
+
const { stdout } = await execWithIdleTimeout({
|
|
882
|
+
command,
|
|
883
|
+
args,
|
|
528
884
|
cwd,
|
|
529
|
-
|
|
530
|
-
|
|
885
|
+
timeout,
|
|
886
|
+
onStdout: debugLog ? createStreamParser(debugLog, "Cursor", claudeAdapter) : void 0
|
|
531
887
|
});
|
|
532
|
-
return
|
|
888
|
+
return extractClaudeResult(stdout);
|
|
533
889
|
} catch (error) {
|
|
534
|
-
if (error instanceof
|
|
535
|
-
|
|
536
|
-
|
|
890
|
+
if (error instanceof IdleTimeoutError) throw new Error(`cursor agent timed out after ${timeout}ms of inactivity`);
|
|
891
|
+
if (error && typeof error === "object" && "exitCode" in error) {
|
|
892
|
+
const execError = error;
|
|
893
|
+
throw new Error(`cursor agent failed (exit ${execError.exitCode}): ${execError.stderr || execError.shortMessage}`);
|
|
537
894
|
}
|
|
538
895
|
throw error;
|
|
539
896
|
}
|
|
540
897
|
}
|
|
541
898
|
async isAvailable() {
|
|
542
|
-
|
|
543
|
-
await execa(cmd, ["--version"], {
|
|
544
|
-
stdin: "ignore",
|
|
545
|
-
timeout: 2e3
|
|
546
|
-
});
|
|
547
|
-
return true;
|
|
548
|
-
} catch {}
|
|
549
|
-
return false;
|
|
899
|
+
return await this.resolveCommand() !== null;
|
|
550
900
|
}
|
|
551
901
|
getInfo() {
|
|
552
902
|
return {
|
|
@@ -554,17 +904,48 @@ var CursorBackend = class {
|
|
|
554
904
|
model: this.options.model
|
|
555
905
|
};
|
|
556
906
|
}
|
|
557
|
-
|
|
558
|
-
|
|
907
|
+
/**
|
|
908
|
+
* Resolve which cursor command is available.
|
|
909
|
+
* Prefers `cursor agent` (subcommand), falls back to `cursor-agent` (standalone).
|
|
910
|
+
* Result is cached after first resolution.
|
|
911
|
+
*/
|
|
912
|
+
async resolveCommand() {
|
|
913
|
+
if (this.resolvedCommand !== null) return this.resolvedCommand;
|
|
914
|
+
try {
|
|
915
|
+
await execa("cursor", ["agent", "--version"], {
|
|
916
|
+
stdin: "ignore",
|
|
917
|
+
timeout: 2e3
|
|
918
|
+
});
|
|
919
|
+
this.resolvedCommand = "cursor";
|
|
920
|
+
return "cursor";
|
|
921
|
+
} catch {}
|
|
922
|
+
try {
|
|
923
|
+
await execa("cursor-agent", ["--version"], {
|
|
924
|
+
stdin: "ignore",
|
|
925
|
+
timeout: 2e3
|
|
926
|
+
});
|
|
927
|
+
this.resolvedCommand = "cursor-agent";
|
|
928
|
+
return "cursor-agent";
|
|
929
|
+
} catch {}
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
async buildCommand(message) {
|
|
933
|
+
const cmd = await this.resolveCommand();
|
|
934
|
+
const agentArgs = [
|
|
559
935
|
"-p",
|
|
560
936
|
"--force",
|
|
561
937
|
"--approve-mcps",
|
|
938
|
+
"--output-format=stream-json",
|
|
562
939
|
message
|
|
563
940
|
];
|
|
564
|
-
if (this.options.model)
|
|
941
|
+
if (this.options.model) agentArgs.push("--model", this.options.model);
|
|
942
|
+
if (cmd === "cursor") return {
|
|
943
|
+
command: "cursor",
|
|
944
|
+
args: ["agent", ...agentArgs]
|
|
945
|
+
};
|
|
565
946
|
return {
|
|
566
947
|
command: "cursor-agent",
|
|
567
|
-
args
|
|
948
|
+
args: agentArgs
|
|
568
949
|
};
|
|
569
950
|
}
|
|
570
951
|
};
|
|
@@ -732,4 +1113,4 @@ async function listBackends() {
|
|
|
732
1113
|
}
|
|
733
1114
|
|
|
734
1115
|
//#endregion
|
|
735
|
-
export { FRONTIER_MODELS as _, createMockBackend as a,
|
|
1116
|
+
export { getModelForBackend as C, createModel as D, SUPPORTED_PROVIDERS as E, createModelAsync as O, SDK_MODEL_ALIASES as S, FRONTIER_MODELS as T, execWithIdleTimeout as _, createMockBackend as a, CODEX_MODEL_MAP as b, CodexBackend as c, codexAdapter as d, createStreamParser as f, IdleTimeoutError as g, formatEvent as h, MockAIBackend as i, getDefaultModel as k, ClaudeCodeBackend as l, extractCodexResult as m, createBackend as n, SdkBackend as o, extractClaudeResult as p, listBackends as r, CursorBackend as s, checkBackends as t, claudeAdapter as u, BACKEND_DEFAULT_MODELS as v, parseModel as w, CURSOR_MODEL_MAP as x, CLAUDE_MODEL_MAP as y };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { C as getModelForBackend, S as SDK_MODEL_ALIASES, _ as execWithIdleTimeout, a as createMockBackend, b as CODEX_MODEL_MAP, c as CodexBackend, d as codexAdapter, f as createStreamParser, g as IdleTimeoutError, h as formatEvent, i as MockAIBackend, l as ClaudeCodeBackend, m as extractCodexResult, n as createBackend, o as SdkBackend, p as extractClaudeResult, r as listBackends, s as CursorBackend, t as checkBackends, u as claudeAdapter, v as BACKEND_DEFAULT_MODELS, x as CURSOR_MODEL_MAP, y as CLAUDE_MODEL_MAP } from "./backends-BJyk6zvs.mjs";
|
|
2
|
+
|
|
3
|
+
export { listBackends };
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { a as createSkillsTool, c as createFeedbackTool, l as AgentSession, o as SkillsProvider, s as FEEDBACK_PROMPT, t as SkillImporter } from "../skills-
|
|
2
|
+
import { T as FRONTIER_MODELS, k as getDefaultModel, n as createBackend } from "../backends-BJyk6zvs.mjs";
|
|
3
|
+
import { a as createSkillsTool, c as createFeedbackTool, l as AgentSession, o as SkillsProvider, s as FEEDBACK_PROMPT, t as SkillImporter } from "../skills-CuAfAkHU.mjs";
|
|
4
4
|
import { jsonSchema, tool } from "ai";
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
@@ -541,6 +541,8 @@ async function handleRequest(getState, req, resetIdleTimer, gracefulShutdown, re
|
|
|
541
541
|
const RESOURCE_PREFIX = "res_";
|
|
542
542
|
/** Resource URI scheme */
|
|
543
543
|
const RESOURCE_SCHEME = "resource:";
|
|
544
|
+
/** Message length threshold for channel messages - content longer than this should use resources or documents */
|
|
545
|
+
const MESSAGE_LENGTH_THRESHOLD = 1200;
|
|
544
546
|
/**
|
|
545
547
|
* Generate a unique resource ID
|
|
546
548
|
*/
|
|
@@ -554,6 +556,12 @@ function generateResourceId() {
|
|
|
554
556
|
function createResourceRef(id) {
|
|
555
557
|
return `${RESOURCE_SCHEME}${id}`;
|
|
556
558
|
}
|
|
559
|
+
/**
|
|
560
|
+
* Check if content should be stored as a resource instead of inline
|
|
561
|
+
*/
|
|
562
|
+
function shouldUseResource(content) {
|
|
563
|
+
return content.length > MESSAGE_LENGTH_THRESHOLD;
|
|
564
|
+
}
|
|
557
565
|
/** Default context configuration values */
|
|
558
566
|
const CONTEXT_DEFAULTS = {
|
|
559
567
|
dir: "~/.agent-worker/workflows/${{ workflow.name }}/${{ workflow.tag }}/",
|
|
@@ -679,6 +687,23 @@ var ContextProviderImpl = class {
|
|
|
679
687
|
cursor: entries.length
|
|
680
688
|
};
|
|
681
689
|
}
|
|
690
|
+
/**
|
|
691
|
+
* Smart send: automatically converts long messages to resources
|
|
692
|
+
*
|
|
693
|
+
* If content exceeds MESSAGE_LENGTH_THRESHOLD:
|
|
694
|
+
* 1. Creates a resource with the full content
|
|
695
|
+
* 2. Sends a short message referencing the resource
|
|
696
|
+
* 3. Logs the full content in debug channel for visibility
|
|
697
|
+
*/
|
|
698
|
+
async smartSend(from, content, options) {
|
|
699
|
+
if (!shouldUseResource(content)) return this.appendChannel(from, content, options);
|
|
700
|
+
const resourceType = content.startsWith("```") || content.includes("\n```") ? "markdown" : "text";
|
|
701
|
+
const resource = await this.createResource(content, from, resourceType);
|
|
702
|
+
await this.appendChannel("system", `Created resource ${resource.id} (${content.length} chars) for @${from}:\n${content}`, { kind: "debug" });
|
|
703
|
+
const mentions = extractMentions(content, this.validAgents);
|
|
704
|
+
const shortMessage = `${mentions.length > 0 ? mentions.map((m) => `@${m}`).join(" ") + " " : ""}[Long content stored as resource]\n\nRead the full content: resource_read("${resource.id}")\n\nReference: ${resource.ref}`;
|
|
705
|
+
return this.appendChannel(from, shortMessage, options);
|
|
706
|
+
}
|
|
682
707
|
async getInbox(agent) {
|
|
683
708
|
const state = await this.loadInboxState();
|
|
684
709
|
const lastAckId = state.readCursors[agent];
|
|
@@ -2094,10 +2119,25 @@ Examples:
|
|
|
2094
2119
|
|
|
2095
2120
|
Note: Workflow name is inferred from YAML 'name' field or filename
|
|
2096
2121
|
`).action(async (file, options) => {
|
|
2097
|
-
const { parseWorkflowFile, runWorkflowWithControllers } = await import("../workflow-
|
|
2122
|
+
const { parseWorkflowFile, runWorkflowWithControllers } = await import("../workflow-C26F4PpH.mjs");
|
|
2098
2123
|
const tag = options.tag || DEFAULT_TAG;
|
|
2099
2124
|
const parsedWorkflow = await parseWorkflowFile(file, { tag });
|
|
2100
2125
|
const workflowName = parsedWorkflow.name;
|
|
2126
|
+
let controllers;
|
|
2127
|
+
let isCleaningUp = false;
|
|
2128
|
+
const cleanup = async () => {
|
|
2129
|
+
if (isCleaningUp) return;
|
|
2130
|
+
isCleaningUp = true;
|
|
2131
|
+
console.log("\nInterrupted, cleaning up...");
|
|
2132
|
+
if (controllers) {
|
|
2133
|
+
const { shutdownControllers } = await import("../workflow-C26F4PpH.mjs");
|
|
2134
|
+
const { createSilentLogger } = await import("../logger-L9AtbIPS.mjs");
|
|
2135
|
+
await shutdownControllers(controllers, createSilentLogger());
|
|
2136
|
+
}
|
|
2137
|
+
process.exit(130);
|
|
2138
|
+
};
|
|
2139
|
+
process.on("SIGINT", cleanup);
|
|
2140
|
+
process.on("SIGTERM", cleanup);
|
|
2101
2141
|
try {
|
|
2102
2142
|
const log = options.json ? console.error : console.log;
|
|
2103
2143
|
const result = await runWorkflowWithControllers({
|
|
@@ -2110,6 +2150,9 @@ Note: Workflow name is inferred from YAML 'name' field or filename
|
|
|
2110
2150
|
mode: "run",
|
|
2111
2151
|
feedback: options.feedback
|
|
2112
2152
|
});
|
|
2153
|
+
controllers = result.controllers;
|
|
2154
|
+
process.off("SIGINT", cleanup);
|
|
2155
|
+
process.off("SIGTERM", cleanup);
|
|
2113
2156
|
if (!result.success) {
|
|
2114
2157
|
console.error("Workflow failed:", result.error);
|
|
2115
2158
|
process.exit(1);
|
|
@@ -2132,6 +2175,8 @@ Note: Workflow name is inferred from YAML 'name' field or filename
|
|
|
2132
2175
|
for (const entry of result.feedback) console.log(` [${entry.type}] ${entry.target}: ${entry.description}`);
|
|
2133
2176
|
}
|
|
2134
2177
|
} catch (error) {
|
|
2178
|
+
process.off("SIGINT", cleanup);
|
|
2179
|
+
process.off("SIGTERM", cleanup);
|
|
2135
2180
|
console.error("Error:", error instanceof Error ? error.message : String(error));
|
|
2136
2181
|
process.exit(1);
|
|
2137
2182
|
}
|
|
@@ -2144,7 +2189,7 @@ Examples:
|
|
|
2144
2189
|
|
|
2145
2190
|
Note: Workflow name is inferred from YAML 'name' field or filename
|
|
2146
2191
|
`).action(async (file, options) => {
|
|
2147
|
-
const { parseWorkflowFile, runWorkflowWithControllers } = await import("../workflow-
|
|
2192
|
+
const { parseWorkflowFile, runWorkflowWithControllers } = await import("../workflow-C26F4PpH.mjs");
|
|
2148
2193
|
const tag = options.tag || DEFAULT_TAG;
|
|
2149
2194
|
const parsedWorkflow = await parseWorkflowFile(file, { tag });
|
|
2150
2195
|
const workflowName = parsedWorkflow.name;
|
|
@@ -2339,7 +2384,7 @@ function registerInfoCommands(program) {
|
|
|
2339
2384
|
console.log(`\nDefault: ${defaultModel} (when no model specified)`);
|
|
2340
2385
|
});
|
|
2341
2386
|
program.command("backends").description("Check available backends (SDK, CLI tools)").action(async () => {
|
|
2342
|
-
const { listBackends } = await import("../backends-
|
|
2387
|
+
const { listBackends } = await import("../backends-fLwD_6G_.mjs");
|
|
2343
2388
|
const backends = await listBackends();
|
|
2344
2389
|
console.log("Backend Status:\n");
|
|
2345
2390
|
for (const backend of backends) {
|
|
@@ -2369,7 +2414,7 @@ Examples:
|
|
|
2369
2414
|
$ agent-worker doc read @review:pr-123 # Read specific workflow:tag document
|
|
2370
2415
|
`).action(async (targetInput) => {
|
|
2371
2416
|
const dir = await resolveDir(targetInput);
|
|
2372
|
-
const { createFileContextProvider } = await import("../context-
|
|
2417
|
+
const { createFileContextProvider } = await import("../context-DW7xrslO.mjs");
|
|
2373
2418
|
const content = await createFileContextProvider(dir, []).readDocument();
|
|
2374
2419
|
console.log(content || "(empty document)");
|
|
2375
2420
|
});
|
|
@@ -2387,7 +2432,7 @@ Examples:
|
|
|
2387
2432
|
process.exit(1);
|
|
2388
2433
|
}
|
|
2389
2434
|
const dir = await resolveDir(targetInput);
|
|
2390
|
-
const { createFileContextProvider } = await import("../context-
|
|
2435
|
+
const { createFileContextProvider } = await import("../context-DW7xrslO.mjs");
|
|
2391
2436
|
await createFileContextProvider(dir, []).writeDocument(content);
|
|
2392
2437
|
console.log("Document written");
|
|
2393
2438
|
});
|
|
@@ -2405,7 +2450,7 @@ Examples:
|
|
|
2405
2450
|
process.exit(1);
|
|
2406
2451
|
}
|
|
2407
2452
|
const dir = await resolveDir(targetInput);
|
|
2408
|
-
const { createFileContextProvider } = await import("../context-
|
|
2453
|
+
const { createFileContextProvider } = await import("../context-DW7xrslO.mjs");
|
|
2409
2454
|
await createFileContextProvider(dir, []).appendDocument(content);
|
|
2410
2455
|
console.log("Content appended");
|
|
2411
2456
|
});
|
|
@@ -2485,16 +2530,23 @@ Note: Requires agent to be created with --feedback flag
|
|
|
2485
2530
|
});
|
|
2486
2531
|
}
|
|
2487
2532
|
|
|
2533
|
+
//#endregion
|
|
2534
|
+
//#region package.json
|
|
2535
|
+
var version = "0.6.0";
|
|
2536
|
+
|
|
2488
2537
|
//#endregion
|
|
2489
2538
|
//#region src/cli/index.ts
|
|
2490
2539
|
globalThis.AI_SDK_LOG_WARNINGS = false;
|
|
2491
2540
|
const originalStderrWrite = process.stderr.write.bind(process.stderr);
|
|
2492
|
-
process.stderr.write = function(chunk, ...
|
|
2493
|
-
if (process.argv.includes("--debug") || process.argv.includes("-d"))
|
|
2541
|
+
process.stderr.write = function(chunk, ...rest) {
|
|
2542
|
+
if (process.argv.includes("--debug") || process.argv.includes("-d")) {
|
|
2543
|
+
const message = typeof chunk === "string" ? chunk : chunk.toString();
|
|
2544
|
+
return originalStderrWrite.call(process.stderr, message, ...rest);
|
|
2545
|
+
}
|
|
2494
2546
|
return true;
|
|
2495
2547
|
};
|
|
2496
2548
|
const program = new Command();
|
|
2497
|
-
program.name("agent-worker").description("CLI for creating and managing AI agents").version(
|
|
2549
|
+
program.name("agent-worker").description("CLI for creating and managing AI agents").version(version);
|
|
2498
2550
|
registerAgentCommands(program);
|
|
2499
2551
|
registerSendCommands(program);
|
|
2500
2552
|
registerMockCommands(program);
|
|
@@ -2506,4 +2558,4 @@ registerDocCommands(program);
|
|
|
2506
2558
|
program.parse();
|
|
2507
2559
|
|
|
2508
2560
|
//#endregion
|
|
2509
|
-
export { FileStorage as a, CONTEXT_DEFAULTS as c,
|
|
2561
|
+
export { shouldUseResource as _, FileStorage as a, CONTEXT_DEFAULTS as c, RESOURCE_PREFIX as d, RESOURCE_SCHEME as f, generateResourceId as g, extractMentions as h, resolveContextDir as i, MENTION_PATTERN as l, createResourceRef as m, createFileContextProvider as n, MemoryStorage as o, calculatePriority as p, getDefaultContextDir as r, ContextProviderImpl as s, FileContextProvider as t, MESSAGE_LENGTH_THRESHOLD as u };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { _ as shouldUseResource, a as FileStorage, c as CONTEXT_DEFAULTS, d as RESOURCE_PREFIX, f as RESOURCE_SCHEME, g as generateResourceId, h as extractMentions, i as resolveContextDir, l as MENTION_PATTERN, m as createResourceRef, n as createFileContextProvider, o as MemoryStorage, p as calculatePriority, r as getDefaultContextDir, s as ContextProviderImpl, t as FileContextProvider, u as MESSAGE_LENGTH_THRESHOLD } from "./cli/index.mjs";
|
|
2
|
+
import { a as createMemoryContextProvider, i as MemoryContextProvider, n as formatProposal, r as formatProposalList, t as createContextMCPServer } from "./mcp-server-ONSDOpt5.mjs";
|
|
3
|
+
|
|
4
|
+
export { createFileContextProvider };
|
package/dist/index.d.mts
CHANGED
|
@@ -175,6 +175,8 @@ interface Backend {
|
|
|
175
175
|
setWorkspace?(workspaceDir: string, mcpConfig: {
|
|
176
176
|
mcpServers: Record<string, unknown>;
|
|
177
177
|
}): void;
|
|
178
|
+
/** Abort any running operations and cleanup resources */
|
|
179
|
+
abort?(): void;
|
|
178
180
|
}
|
|
179
181
|
//#endregion
|
|
180
182
|
//#region src/agent/session.d.ts
|
|
@@ -467,7 +469,7 @@ interface ClaudeCodeOptions {
|
|
|
467
469
|
cwd?: string;
|
|
468
470
|
/** Workspace directory for agent isolation */
|
|
469
471
|
workspace?: string;
|
|
470
|
-
/**
|
|
472
|
+
/** Idle timeout in milliseconds — kills process if no output for this duration */
|
|
471
473
|
timeout?: number;
|
|
472
474
|
/** MCP config file path (for workflow context) */
|
|
473
475
|
mcpConfigPath?: string;
|
|
@@ -477,6 +479,7 @@ interface ClaudeCodeOptions {
|
|
|
477
479
|
declare class ClaudeCodeBackend implements Backend {
|
|
478
480
|
readonly type: "claude";
|
|
479
481
|
private options;
|
|
482
|
+
private currentAbort?;
|
|
480
483
|
constructor(options?: ClaudeCodeOptions);
|
|
481
484
|
/**
|
|
482
485
|
* Set up workspace directory with MCP config
|
|
@@ -499,25 +502,23 @@ declare class ClaudeCodeBackend implements Backend {
|
|
|
499
502
|
* Set MCP config path (for workflow integration)
|
|
500
503
|
*/
|
|
501
504
|
setMcpConfigPath(path: string): void;
|
|
505
|
+
/**
|
|
506
|
+
* Abort any running claude process
|
|
507
|
+
*/
|
|
508
|
+
abort(): void;
|
|
502
509
|
}
|
|
503
510
|
//#endregion
|
|
504
511
|
//#region src/backends/codex.d.ts
|
|
505
512
|
interface CodexOptions {
|
|
506
513
|
/** Model to use (e.g., 'gpt-5.2-codex') */
|
|
507
514
|
model?: string;
|
|
508
|
-
/** Output as JSON events */
|
|
509
|
-
json?: boolean;
|
|
510
515
|
/** Working directory (defaults to workspace if set) */
|
|
511
516
|
cwd?: string;
|
|
512
517
|
/** Workspace directory for agent isolation */
|
|
513
518
|
workspace?: string;
|
|
514
|
-
/** Skip git repo check */
|
|
515
|
-
skipGitRepoCheck?: boolean;
|
|
516
|
-
/** Approval mode: 'suggest' | 'auto-edit' | 'full-auto' */
|
|
517
|
-
approvalMode?: "suggest" | "auto-edit" | "full-auto";
|
|
518
519
|
/** Resume a previous session */
|
|
519
520
|
resume?: string;
|
|
520
|
-
/**
|
|
521
|
+
/** Idle timeout in milliseconds — kills process if no output for this duration */
|
|
521
522
|
timeout?: number;
|
|
522
523
|
/** Debug log function (for workflow diagnostics) */
|
|
523
524
|
debugLog?: (message: string) => void;
|
|
@@ -553,7 +554,7 @@ interface CursorOptions {
|
|
|
553
554
|
cwd?: string;
|
|
554
555
|
/** Workspace directory for agent isolation (contains .cursor/mcp.json) */
|
|
555
556
|
workspace?: string;
|
|
556
|
-
/**
|
|
557
|
+
/** Idle timeout in milliseconds — kills process if no output for this duration */
|
|
557
558
|
timeout?: number;
|
|
558
559
|
/** Debug log function (for workflow diagnostics) */
|
|
559
560
|
debugLog?: (message: string) => void;
|
|
@@ -561,6 +562,8 @@ interface CursorOptions {
|
|
|
561
562
|
declare class CursorBackend implements Backend {
|
|
562
563
|
readonly type: "cursor";
|
|
563
564
|
private options;
|
|
565
|
+
/** Resolved command: "cursor" (subcommand style) or "cursor-agent" (standalone) */
|
|
566
|
+
private resolvedCommand;
|
|
564
567
|
constructor(options?: CursorOptions);
|
|
565
568
|
/**
|
|
566
569
|
* Set up workspace directory with MCP config
|
|
@@ -578,10 +581,16 @@ declare class CursorBackend implements Backend {
|
|
|
578
581
|
version?: string;
|
|
579
582
|
model?: string;
|
|
580
583
|
};
|
|
581
|
-
|
|
584
|
+
/**
|
|
585
|
+
* Resolve which cursor command is available.
|
|
586
|
+
* Prefers `cursor agent` (subcommand), falls back to `cursor-agent` (standalone).
|
|
587
|
+
* Result is cached after first resolution.
|
|
588
|
+
*/
|
|
589
|
+
private resolveCommand;
|
|
590
|
+
protected buildCommand(message: string): Promise<{
|
|
582
591
|
command: string;
|
|
583
592
|
args: string[];
|
|
584
|
-
}
|
|
593
|
+
}>;
|
|
585
594
|
}
|
|
586
595
|
//#endregion
|
|
587
596
|
//#region src/backends/sdk.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as createSkillsTool, c as createFeedbackTool, i as parseImportSpec, l as AgentSession, n as buildGitUrl, o as SkillsProvider, r as getSpecDisplayName, s as FEEDBACK_PROMPT, t as SkillImporter } from "./skills-
|
|
1
|
+
import { D as createModel, E as SUPPORTED_PROVIDERS, O as createModelAsync, T as FRONTIER_MODELS, a as createMockBackend, c as CodexBackend, i as MockAIBackend, l as ClaudeCodeBackend, n as createBackend, o as SdkBackend, r as listBackends, s as CursorBackend, t as checkBackends } from "./backends-BJyk6zvs.mjs";
|
|
2
|
+
import { a as createSkillsTool, c as createFeedbackTool, i as parseImportSpec, l as AgentSession, n as buildGitUrl, o as SkillsProvider, r as getSpecDisplayName, s as FEEDBACK_PROMPT, t as SkillImporter } from "./skills-CuAfAkHU.mjs";
|
|
3
3
|
import { jsonSchema, tool } from "ai";
|
|
4
4
|
import { createBashTool } from "bash-tool";
|
|
5
5
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//#region src/workflow/logger.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create a silent logger (no output)
|
|
4
|
+
*/
|
|
5
|
+
function createSilentLogger() {
|
|
6
|
+
const noop = () => {};
|
|
7
|
+
return {
|
|
8
|
+
debug: noop,
|
|
9
|
+
info: noop,
|
|
10
|
+
warn: noop,
|
|
11
|
+
error: noop,
|
|
12
|
+
isDebug: () => false,
|
|
13
|
+
child: () => createSilentLogger()
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create a logger that writes to the channel.
|
|
18
|
+
*
|
|
19
|
+
* - info/warn/error → channel entry with kind="log" (always shown to user)
|
|
20
|
+
* - debug → channel entry with kind="debug" (only shown with --debug)
|
|
21
|
+
*
|
|
22
|
+
* The display layer handles formatting and filtering.
|
|
23
|
+
*/
|
|
24
|
+
function createChannelLogger(config) {
|
|
25
|
+
const { provider, from = "system" } = config;
|
|
26
|
+
const formatContent = (level, message, args) => {
|
|
27
|
+
const argsStr = args.length > 0 ? " " + args.map(formatArg).join(" ") : "";
|
|
28
|
+
if (level === "warn") return `[WARN] ${message}${argsStr}`;
|
|
29
|
+
if (level === "error") return `[ERROR] ${message}${argsStr}`;
|
|
30
|
+
return `${message}${argsStr}`;
|
|
31
|
+
};
|
|
32
|
+
const write = (level, message, args) => {
|
|
33
|
+
const content = formatContent(level, message, args);
|
|
34
|
+
const kind = level === "debug" ? "debug" : "log";
|
|
35
|
+
provider.appendChannel(from, content, { kind }).catch(() => {});
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
debug: (message, ...args) => write("debug", message, args),
|
|
39
|
+
info: (message, ...args) => write("info", message, args),
|
|
40
|
+
warn: (message, ...args) => write("warn", message, args),
|
|
41
|
+
error: (message, ...args) => write("error", message, args),
|
|
42
|
+
isDebug: () => true,
|
|
43
|
+
child: (childPrefix) => {
|
|
44
|
+
return createChannelLogger({
|
|
45
|
+
provider,
|
|
46
|
+
from: from ? `${from}:${childPrefix}` : childPrefix
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Format an argument for logging */
|
|
52
|
+
function formatArg(arg) {
|
|
53
|
+
if (arg === null || arg === void 0) return String(arg);
|
|
54
|
+
if (typeof arg === "object") try {
|
|
55
|
+
return JSON.stringify(arg);
|
|
56
|
+
} catch {
|
|
57
|
+
return String(arg);
|
|
58
|
+
}
|
|
59
|
+
return String(arg);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//#endregion
|
|
63
|
+
export { createChannelLogger, createSilentLogger };
|
|
@@ -169,9 +169,8 @@ function createContextMCPServer(options) {
|
|
|
169
169
|
version
|
|
170
170
|
});
|
|
171
171
|
const agentConnections = /* @__PURE__ */ new Map();
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
message: z.string().describe("Message content, can include @mentions like @reviewer or @coder"),
|
|
172
|
+
server.tool("channel_send", `Send a message to the shared channel. Use @agent to mention/notify. Use "to" for private DMs. Long messages (> 2000 chars) are automatically converted to resources.`, {
|
|
173
|
+
message: z.string().describe("Message content, can include @mentions like @reviewer or @coder. Long messages are auto-converted to resources."),
|
|
175
174
|
to: z.string().optional().describe("Send as DM to a specific agent (private, only you and recipient see it)")
|
|
176
175
|
}, async ({ message, to }, extra) => {
|
|
177
176
|
const from = getAgentId(extra) || "anonymous";
|
|
@@ -179,15 +178,8 @@ function createContextMCPServer(options) {
|
|
|
179
178
|
message,
|
|
180
179
|
to
|
|
181
180
|
});
|
|
182
|
-
if (message.length > CHANNEL_MSG_LIMIT) return {
|
|
183
|
-
isError: true,
|
|
184
|
-
content: [{
|
|
185
|
-
type: "text",
|
|
186
|
-
text: `Message too long (${message.length} chars, max ${CHANNEL_MSG_LIMIT}). Use resource_create to store the full content, then send a short message referencing the resource ID.`
|
|
187
|
-
}]
|
|
188
|
-
};
|
|
189
181
|
const sendOpts = to ? { to } : void 0;
|
|
190
|
-
const msg = await provider.
|
|
182
|
+
const msg = await provider.smartSend(from, message, sendOpts);
|
|
191
183
|
for (const target of msg.mentions) if (onMention) onMention(from, target, msg);
|
|
192
184
|
if (to && !msg.mentions.includes(to) && onMention) onMention(from, to, msg);
|
|
193
185
|
return { content: [{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { O as createModelAsync } from "./backends-BJyk6zvs.mjs";
|
|
2
2
|
import { ToolLoopAgent, jsonSchema, stepCountIs, tool } from "ai";
|
|
3
3
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
4
4
|
import { join, normalize } from "node:path";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { O as createModelAsync, a as createMockBackend, n as createBackend, w as parseModel } from "./backends-BJyk6zvs.mjs";
|
|
2
2
|
import { c as CONTEXT_DEFAULTS, i as resolveContextDir, n as createFileContextProvider, t as FileContextProvider } from "./cli/index.mjs";
|
|
3
|
-
import { a as createMemoryContextProvider, t as createContextMCPServer } from "./mcp-server-
|
|
3
|
+
import { a as createMemoryContextProvider, t as createContextMCPServer } from "./mcp-server-ONSDOpt5.mjs";
|
|
4
|
+
import { createChannelLogger, createSilentLogger } from "./logger-L9AtbIPS.mjs";
|
|
4
5
|
import { generateText, jsonSchema, stepCountIs, tool } from "ai";
|
|
5
6
|
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
6
7
|
import { basename, dirname, join, resolve } from "node:path";
|
|
@@ -459,16 +460,6 @@ function formatInbox(inbox) {
|
|
|
459
460
|
}).join("\n");
|
|
460
461
|
}
|
|
461
462
|
/**
|
|
462
|
-
* Format channel messages for display
|
|
463
|
-
*/
|
|
464
|
-
function formatChannel(entries) {
|
|
465
|
-
if (entries.length === 0) return "(no messages)";
|
|
466
|
-
return entries.map((e) => {
|
|
467
|
-
const dm = e.to ? ` [DM→@${e.to}]` : "";
|
|
468
|
-
return `[${e.timestamp.slice(11, 19)}] @${e.from}${dm}: ${e.content}`;
|
|
469
|
-
}).join("\n");
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
463
|
* Build the complete agent prompt from run context
|
|
473
464
|
*/
|
|
474
465
|
function buildAgentPrompt(ctx) {
|
|
@@ -479,8 +470,8 @@ function buildAgentPrompt(ctx) {
|
|
|
479
470
|
sections.push(`## Inbox (${ctx.inbox.length} message${ctx.inbox.length === 1 ? "" : "s"} for you)`);
|
|
480
471
|
sections.push(formatInbox(ctx.inbox));
|
|
481
472
|
sections.push("");
|
|
482
|
-
sections.push(
|
|
483
|
-
sections.push(
|
|
473
|
+
sections.push("## Recent Activity");
|
|
474
|
+
sections.push("Use channel_read tool to view recent channel messages and conversation context if needed.");
|
|
484
475
|
if (ctx.documentContent) {
|
|
485
476
|
sections.push("");
|
|
486
477
|
sections.push("## Shared Document");
|
|
@@ -860,6 +851,7 @@ function shouldContinue(state) {
|
|
|
860
851
|
*/
|
|
861
852
|
function createAgentController(config) {
|
|
862
853
|
const { name, agent, contextProvider, mcpUrl, workspaceDir, projectDir, backend, onRunComplete, log = () => {}, feedback } = config;
|
|
854
|
+
const infoLog = config.infoLog ?? log;
|
|
863
855
|
const errorLog = config.errorLog ?? log;
|
|
864
856
|
const pollInterval = config.pollInterval ?? CONTROLLER_DEFAULTS.pollInterval;
|
|
865
857
|
const retryConfig = {
|
|
@@ -895,7 +887,7 @@ function createAgentController(config) {
|
|
|
895
887
|
continue;
|
|
896
888
|
}
|
|
897
889
|
const senders = inbox.map((m) => m.entry.from);
|
|
898
|
-
|
|
890
|
+
infoLog(`Inbox: ${inbox.length} message(s) from [${senders.join(", ")}]`);
|
|
899
891
|
for (const msg of inbox) {
|
|
900
892
|
const preview = msg.entry.content.length > 120 ? msg.entry.content.slice(0, 120) + "..." : msg.entry.content;
|
|
901
893
|
log(` from @${msg.entry.from}: ${preview}`);
|
|
@@ -907,7 +899,7 @@ function createAgentController(config) {
|
|
|
907
899
|
while (attempt < retryConfig.maxAttempts && shouldContinue(state)) {
|
|
908
900
|
attempt++;
|
|
909
901
|
state = "running";
|
|
910
|
-
|
|
902
|
+
infoLog(`Running (attempt ${attempt}/${retryConfig.maxAttempts})`);
|
|
911
903
|
lastResult = await runAgent(backend, {
|
|
912
904
|
name,
|
|
913
905
|
agent,
|
|
@@ -922,9 +914,9 @@ function createAgentController(config) {
|
|
|
922
914
|
projectDir,
|
|
923
915
|
retryAttempt: attempt,
|
|
924
916
|
feedback
|
|
925
|
-
}, log);
|
|
917
|
+
}, log, infoLog);
|
|
926
918
|
if (lastResult.success) {
|
|
927
|
-
|
|
919
|
+
infoLog(`DONE ${lastResult.steps ? `${lastResult.steps} steps, ${lastResult.toolCalls} tool calls, ${lastResult.duration}ms` : `${lastResult.duration}ms`}`);
|
|
928
920
|
if (lastResult.content) await contextProvider.appendChannel(name, lastResult.content);
|
|
929
921
|
await contextProvider.ackInbox(name, latestId);
|
|
930
922
|
break;
|
|
@@ -954,7 +946,7 @@ function createAgentController(config) {
|
|
|
954
946
|
async start() {
|
|
955
947
|
if (state !== "stopped") throw new Error(`Controller ${name} is already running`);
|
|
956
948
|
state = "idle";
|
|
957
|
-
|
|
949
|
+
infoLog(`Starting`);
|
|
958
950
|
runLoop().catch((error) => {
|
|
959
951
|
errorLog(`ERROR ${error instanceof Error ? error.message : String(error)}`);
|
|
960
952
|
state = "stopped";
|
|
@@ -963,6 +955,7 @@ function createAgentController(config) {
|
|
|
963
955
|
async stop() {
|
|
964
956
|
log(`Stopping`);
|
|
965
957
|
state = "stopped";
|
|
958
|
+
if (backend.abort) backend.abort();
|
|
966
959
|
if (pollTimeout) {
|
|
967
960
|
clearTimeout(pollTimeout);
|
|
968
961
|
pollTimeout = null;
|
|
@@ -994,7 +987,8 @@ function createAgentController(config) {
|
|
|
994
987
|
* SDK and mock backends get special runners with MCP tool bridge + bash,
|
|
995
988
|
* because they can't manage tools on their own (unlike CLI backends).
|
|
996
989
|
*/
|
|
997
|
-
async function runAgent(backend, ctx, log) {
|
|
990
|
+
async function runAgent(backend, ctx, log, infoLog) {
|
|
991
|
+
const info = infoLog ?? log;
|
|
998
992
|
if (backend.type === "mock") return runMockAgent(ctx, (msg) => log(msg));
|
|
999
993
|
if (backend.type === "sdk") return runSdkAgent(ctx, (msg) => log(msg));
|
|
1000
994
|
const startTime = Date.now();
|
|
@@ -1004,7 +998,7 @@ async function runAgent(backend, ctx, log) {
|
|
|
1004
998
|
backend.setWorkspace(ctx.workspaceDir, mcpConfig);
|
|
1005
999
|
}
|
|
1006
1000
|
const prompt = buildAgentPrompt(ctx);
|
|
1007
|
-
|
|
1001
|
+
info(`Prompt (${prompt.length} chars) → ${backend.type} backend`);
|
|
1008
1002
|
await backend.send(prompt, { system: ctx.agent.resolvedSystemPrompt });
|
|
1009
1003
|
return {
|
|
1010
1004
|
success: true,
|
|
@@ -1044,9 +1038,13 @@ async function checkWorkflowIdle(controllers, provider, debounceMs = CONTROLLER_
|
|
|
1044
1038
|
*/
|
|
1045
1039
|
function getBackendByType(backendType, options) {
|
|
1046
1040
|
if (backendType === "mock") return createMockBackend(options?.debugLog);
|
|
1041
|
+
const backendOptions = {};
|
|
1042
|
+
if (options?.timeout) backendOptions.timeout = options.timeout;
|
|
1043
|
+
if (options?.debugLog) backendOptions.debugLog = options.debugLog;
|
|
1047
1044
|
return createBackend({
|
|
1048
1045
|
type: backendType,
|
|
1049
|
-
model: options?.model
|
|
1046
|
+
model: options?.model,
|
|
1047
|
+
...Object.keys(backendOptions).length > 0 ? { options: backendOptions } : {}
|
|
1050
1048
|
});
|
|
1051
1049
|
}
|
|
1052
1050
|
/**
|
|
@@ -1362,68 +1360,6 @@ function startChannelWatcher(config) {
|
|
|
1362
1360
|
} };
|
|
1363
1361
|
}
|
|
1364
1362
|
|
|
1365
|
-
//#endregion
|
|
1366
|
-
//#region src/workflow/logger.ts
|
|
1367
|
-
/**
|
|
1368
|
-
* Create a silent logger (no output)
|
|
1369
|
-
*/
|
|
1370
|
-
function createSilentLogger() {
|
|
1371
|
-
const noop = () => {};
|
|
1372
|
-
return {
|
|
1373
|
-
debug: noop,
|
|
1374
|
-
info: noop,
|
|
1375
|
-
warn: noop,
|
|
1376
|
-
error: noop,
|
|
1377
|
-
isDebug: () => false,
|
|
1378
|
-
child: () => createSilentLogger()
|
|
1379
|
-
};
|
|
1380
|
-
}
|
|
1381
|
-
/**
|
|
1382
|
-
* Create a logger that writes to the channel.
|
|
1383
|
-
*
|
|
1384
|
-
* - info/warn/error → channel entry with kind="log" (always shown to user)
|
|
1385
|
-
* - debug → channel entry with kind="debug" (only shown with --debug)
|
|
1386
|
-
*
|
|
1387
|
-
* The display layer handles formatting and filtering.
|
|
1388
|
-
*/
|
|
1389
|
-
function createChannelLogger(config) {
|
|
1390
|
-
const { provider, from = "system" } = config;
|
|
1391
|
-
const formatContent = (level, message, args) => {
|
|
1392
|
-
const argsStr = args.length > 0 ? " " + args.map(formatArg).join(" ") : "";
|
|
1393
|
-
if (level === "warn") return `[WARN] ${message}${argsStr}`;
|
|
1394
|
-
if (level === "error") return `[ERROR] ${message}${argsStr}`;
|
|
1395
|
-
return `${message}${argsStr}`;
|
|
1396
|
-
};
|
|
1397
|
-
const write = (level, message, args) => {
|
|
1398
|
-
const content = formatContent(level, message, args);
|
|
1399
|
-
const kind = level === "debug" ? "debug" : "log";
|
|
1400
|
-
provider.appendChannel(from, content, { kind }).catch(() => {});
|
|
1401
|
-
};
|
|
1402
|
-
return {
|
|
1403
|
-
debug: (message, ...args) => write("debug", message, args),
|
|
1404
|
-
info: (message, ...args) => write("info", message, args),
|
|
1405
|
-
warn: (message, ...args) => write("warn", message, args),
|
|
1406
|
-
error: (message, ...args) => write("error", message, args),
|
|
1407
|
-
isDebug: () => true,
|
|
1408
|
-
child: (childPrefix) => {
|
|
1409
|
-
return createChannelLogger({
|
|
1410
|
-
provider,
|
|
1411
|
-
from: from ? `${from}:${childPrefix}` : childPrefix
|
|
1412
|
-
});
|
|
1413
|
-
}
|
|
1414
|
-
};
|
|
1415
|
-
}
|
|
1416
|
-
/** Format an argument for logging */
|
|
1417
|
-
function formatArg(arg) {
|
|
1418
|
-
if (arg === null || arg === void 0) return String(arg);
|
|
1419
|
-
if (typeof arg === "object") try {
|
|
1420
|
-
return JSON.stringify(arg);
|
|
1421
|
-
} catch {
|
|
1422
|
-
return String(arg);
|
|
1423
|
-
}
|
|
1424
|
-
return String(arg);
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
1363
|
//#endregion
|
|
1428
1364
|
//#region src/workflow/runner.ts
|
|
1429
1365
|
/**
|
|
@@ -1554,7 +1490,7 @@ async function initWorkflow(config) {
|
|
|
1554
1490
|
return;
|
|
1555
1491
|
}
|
|
1556
1492
|
logger.debug(`Kickoff: ${interpolatedKickoff.slice(0, 100)}...`);
|
|
1557
|
-
await contextProvider.
|
|
1493
|
+
await contextProvider.smartSend("system", interpolatedKickoff);
|
|
1558
1494
|
},
|
|
1559
1495
|
async shutdown() {
|
|
1560
1496
|
logger.debug("Shutting down...");
|
|
@@ -1658,7 +1594,8 @@ async function runWorkflowWithControllers(config) {
|
|
|
1658
1594
|
if (createBackend) backend = createBackend(agentName, agentDef);
|
|
1659
1595
|
else if (agentDef.backend) backend = getBackendByType(agentDef.backend, {
|
|
1660
1596
|
model: agentDef.model,
|
|
1661
|
-
debugLog: backendDebugLog
|
|
1597
|
+
debugLog: backendDebugLog,
|
|
1598
|
+
timeout: agentDef.timeout
|
|
1662
1599
|
});
|
|
1663
1600
|
else if (agentDef.model) backend = getBackendForModel(agentDef.model, { debugLog: backendDebugLog });
|
|
1664
1601
|
else throw new Error(`Agent "${agentName}" requires either a backend or model field`);
|
|
@@ -1676,6 +1613,7 @@ async function runWorkflowWithControllers(config) {
|
|
|
1676
1613
|
backend,
|
|
1677
1614
|
pollInterval,
|
|
1678
1615
|
log: (msg) => controllerLogger.debug(msg),
|
|
1616
|
+
infoLog: (msg) => controllerLogger.info(msg),
|
|
1679
1617
|
errorLog: (msg) => controllerLogger.error(msg),
|
|
1680
1618
|
feedback: feedbackEnabled
|
|
1681
1619
|
});
|
|
@@ -1781,4 +1719,4 @@ function sleep(ms) {
|
|
|
1781
1719
|
}
|
|
1782
1720
|
|
|
1783
1721
|
//#endregion
|
|
1784
|
-
export { parseWorkflowFile, runWorkflowWithControllers };
|
|
1722
|
+
export { parseWorkflowFile, runWorkflowWithControllers, shutdownControllers };
|
package/package.json
CHANGED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { a as createMockBackend, c as CodexBackend, d as CLAUDE_MODEL_MAP, f as CODEX_MODEL_MAP, h as getModelForBackend, i as MockAIBackend, l as ClaudeCodeBackend, m as SDK_MODEL_ALIASES, n as createBackend, o as SdkBackend, p as CURSOR_MODEL_MAP, r as listBackends, s as CursorBackend, t as checkBackends, u as BACKEND_DEFAULT_MODELS } from "./backends-DenGdkrj.mjs";
|
|
2
|
-
|
|
3
|
-
export { listBackends };
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { a as FileStorage, c as CONTEXT_DEFAULTS, d as RESOURCE_SCHEME, f as calculatePriority, h as generateResourceId, i as resolveContextDir, l as MENTION_PATTERN, m as extractMentions, n as createFileContextProvider, o as MemoryStorage, p as createResourceRef, r as getDefaultContextDir, s as ContextProviderImpl, t as FileContextProvider, u as RESOURCE_PREFIX } from "./cli/index.mjs";
|
|
2
|
-
import { a as createMemoryContextProvider, i as MemoryContextProvider, n as formatProposal, r as formatProposalList, t as createContextMCPServer } from "./mcp-server-DtIApaBD.mjs";
|
|
3
|
-
|
|
4
|
-
export { createFileContextProvider };
|