@corbat-tech/coco 2.38.0 → 2.39.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/adapters/index.d.ts +1 -1
- package/dist/{agent-runtime-DeLcB0Ie.d.ts → agent-runtime-DJY9FzL_.d.ts} +266 -53
- package/dist/{blueprints-BWcCJfnN.d.ts → blueprints-DYgm3K65.d.ts} +1 -1
- package/dist/cli/index.js +633 -168
- package/dist/cli/index.js.map +1 -1
- package/dist/{extension-manifests-DcvOnrp3.d.ts → extension-manifests-CAQQILhE.d.ts} +36 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +841 -112
- package/dist/index.js.map +1 -1
- package/dist/presets/index.d.ts +2 -2
- package/dist/presets/index.js +572 -107
- package/dist/presets/index.js.map +1 -1
- package/dist/runtime/index.d.ts +4 -4
- package/dist/runtime/index.js +841 -112
- package/dist/runtime/index.js.map +1 -1
- package/dist/tools/index.js +27 -2
- package/dist/tools/index.js.map +1 -1
- package/package.json +1 -1
package/dist/presets/index.js
CHANGED
|
@@ -3362,8 +3362,330 @@ function defineTool(definition) {
|
|
|
3362
3362
|
|
|
3363
3363
|
// src/cli/repl/agents/manager.ts
|
|
3364
3364
|
init_logger();
|
|
3365
|
-
|
|
3366
|
-
|
|
3365
|
+
var LEGACY_ROLE_MAPPINGS = [
|
|
3366
|
+
{ legacy: "explore", role: "researcher", reason: "read-only codebase exploration" },
|
|
3367
|
+
{ legacy: "researcher", role: "researcher", reason: "legacy executor role" },
|
|
3368
|
+
{ legacy: "plan", role: "planner", reason: "task planning" },
|
|
3369
|
+
{ legacy: "planner", role: "planner", reason: "legacy executor role" },
|
|
3370
|
+
{ legacy: "architect", role: "architect", reason: "architecture design" },
|
|
3371
|
+
{ legacy: "editor", role: "editor", reason: "implementation edits" },
|
|
3372
|
+
{ legacy: "debug", role: "coder", reason: "debugging maps to coding capability" },
|
|
3373
|
+
{ legacy: "coder", role: "coder", reason: "legacy executor role" },
|
|
3374
|
+
{ legacy: "test", role: "tester", reason: "test authoring/execution" },
|
|
3375
|
+
{ legacy: "tester", role: "tester", reason: "legacy executor role" },
|
|
3376
|
+
{ legacy: "tdd", role: "tester", reason: "test-first implementation" },
|
|
3377
|
+
{ legacy: "e2e", role: "tester", reason: "end-to-end testing" },
|
|
3378
|
+
{ legacy: "review", role: "reviewer", reason: "code review" },
|
|
3379
|
+
{ legacy: "reviewer", role: "reviewer", reason: "legacy executor role" },
|
|
3380
|
+
{ legacy: "refactor", role: "optimizer", reason: "structure optimization" },
|
|
3381
|
+
{ legacy: "optimizer", role: "optimizer", reason: "legacy executor role" },
|
|
3382
|
+
{ legacy: "security", role: "security", reason: "security analysis" },
|
|
3383
|
+
{ legacy: "qa", role: "qa", reason: "quality assurance" },
|
|
3384
|
+
{ legacy: "integrator", role: "integrator", reason: "integration coordination" },
|
|
3385
|
+
{ legacy: "pm", role: "pm", reason: "product/project coordination" },
|
|
3386
|
+
{ legacy: "docs", role: "docs", reason: "documentation" },
|
|
3387
|
+
{ legacy: "database", role: "database", reason: "database work" }
|
|
3388
|
+
];
|
|
3389
|
+
var LEGACY_ROLE_MAP = new Map(LEGACY_ROLE_MAPPINGS.map((mapping) => [mapping.legacy, mapping]));
|
|
3390
|
+
function mapLegacyAgentRole(legacyRole, fallback = "coder") {
|
|
3391
|
+
return LEGACY_ROLE_MAP.get(legacyRole)?.role ?? fallback;
|
|
3392
|
+
}
|
|
3393
|
+
function assertProvenance(provenance) {
|
|
3394
|
+
if (!provenance.workflowRunId) {
|
|
3395
|
+
throw new Error("Shared workspace writes require workflowRunId provenance.");
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
function snapshotFromRecords(records, role) {
|
|
3399
|
+
const includeSensitive = role === void 0 || role === "security" || role === "integrator" || role === "pm";
|
|
3400
|
+
const facts = /* @__PURE__ */ new Map();
|
|
3401
|
+
const decisions = /* @__PURE__ */ new Map();
|
|
3402
|
+
const risks = /* @__PURE__ */ new Map();
|
|
3403
|
+
const files = /* @__PURE__ */ new Map();
|
|
3404
|
+
const testResults = /* @__PURE__ */ new Map();
|
|
3405
|
+
const artifacts = [];
|
|
3406
|
+
for (const record of records) {
|
|
3407
|
+
if (!includeSensitive && (record.kind === "risk" || record.provenance.risk === "secrets-sensitive")) {
|
|
3408
|
+
continue;
|
|
3409
|
+
}
|
|
3410
|
+
switch (record.kind) {
|
|
3411
|
+
case "fact":
|
|
3412
|
+
facts.set(record.key, record.value);
|
|
3413
|
+
break;
|
|
3414
|
+
case "decision":
|
|
3415
|
+
decisions.set(record.key, record.value);
|
|
3416
|
+
break;
|
|
3417
|
+
case "risk":
|
|
3418
|
+
risks.set(record.key, record.value);
|
|
3419
|
+
break;
|
|
3420
|
+
case "file":
|
|
3421
|
+
files.set(record.key, record.value);
|
|
3422
|
+
break;
|
|
3423
|
+
case "testResult":
|
|
3424
|
+
testResults.set(record.key, record.value);
|
|
3425
|
+
break;
|
|
3426
|
+
case "artifact":
|
|
3427
|
+
if (isAgentArtifact(record.value)) {
|
|
3428
|
+
if (includeSensitive || record.value.kind !== "riskReport") {
|
|
3429
|
+
artifacts.push(cloneArtifact(record.value));
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
break;
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3435
|
+
return {
|
|
3436
|
+
facts: Object.fromEntries(facts),
|
|
3437
|
+
decisions: Object.fromEntries(decisions),
|
|
3438
|
+
risks: Object.fromEntries(risks),
|
|
3439
|
+
files: Object.fromEntries(files),
|
|
3440
|
+
testResults: Object.fromEntries(testResults),
|
|
3441
|
+
artifacts
|
|
3442
|
+
};
|
|
3443
|
+
}
|
|
3444
|
+
var InMemorySharedWorkspaceStore = class {
|
|
3445
|
+
records = [];
|
|
3446
|
+
write(input) {
|
|
3447
|
+
assertProvenance(input.provenance);
|
|
3448
|
+
const record = {
|
|
3449
|
+
id: `state-${randomUUID()}`,
|
|
3450
|
+
kind: input.kind,
|
|
3451
|
+
key: input.key,
|
|
3452
|
+
value: cloneUnknown(input.value),
|
|
3453
|
+
provenance: { ...input.provenance },
|
|
3454
|
+
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
3455
|
+
};
|
|
3456
|
+
this.records.push(record);
|
|
3457
|
+
return cloneRecord(record);
|
|
3458
|
+
}
|
|
3459
|
+
list() {
|
|
3460
|
+
return this.records.map(cloneRecord);
|
|
3461
|
+
}
|
|
3462
|
+
snapshot() {
|
|
3463
|
+
return snapshotFromRecords(this.records);
|
|
3464
|
+
}
|
|
3465
|
+
readForRole(role) {
|
|
3466
|
+
return snapshotFromRecords(this.records, role);
|
|
3467
|
+
}
|
|
3468
|
+
clear() {
|
|
3469
|
+
this.records = [];
|
|
3470
|
+
}
|
|
3471
|
+
};
|
|
3472
|
+
function createAgentTraceContext(input = {}) {
|
|
3473
|
+
return {
|
|
3474
|
+
traceId: input.traceId ?? `trace-${randomUUID()}`,
|
|
3475
|
+
spanId: input.spanId ?? `span-${randomUUID()}`,
|
|
3476
|
+
parentSpanId: input.parentSpanId,
|
|
3477
|
+
workflowRunId: input.workflowRunId,
|
|
3478
|
+
agentRunId: input.agentRunId,
|
|
3479
|
+
taskId: input.taskId,
|
|
3480
|
+
toolCallId: input.toolCallId
|
|
3481
|
+
};
|
|
3482
|
+
}
|
|
3483
|
+
var AgentGraphEngine = class {
|
|
3484
|
+
eventLog;
|
|
3485
|
+
sharedState;
|
|
3486
|
+
nodeExecutor;
|
|
3487
|
+
gateEvaluator;
|
|
3488
|
+
trace;
|
|
3489
|
+
constructor(options = {}) {
|
|
3490
|
+
this.eventLog = options.eventLog;
|
|
3491
|
+
this.sharedState = options.sharedState ?? new InMemorySharedWorkspaceStore();
|
|
3492
|
+
this.nodeExecutor = options.nodeExecutor ?? defaultAgentGraphNodeExecutor;
|
|
3493
|
+
this.gateEvaluator = options.gateEvaluator ?? defaultAgentGateEvaluator;
|
|
3494
|
+
this.trace = options.trace ?? createAgentTraceContext();
|
|
3495
|
+
}
|
|
3496
|
+
async run(input) {
|
|
3497
|
+
const validation = validateAgentGraph(input.graph);
|
|
3498
|
+
if (!validation.valid) {
|
|
3499
|
+
throw new Error(
|
|
3500
|
+
`Invalid agent graph: ${validation.issues.map((issue) => issue.message).join("; ")}`
|
|
3501
|
+
);
|
|
3502
|
+
}
|
|
3503
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3504
|
+
const nodeResults = /* @__PURE__ */ new Map();
|
|
3505
|
+
const artifacts = [];
|
|
3506
|
+
const graphTrace = createAgentTraceContext({
|
|
3507
|
+
...this.trace,
|
|
3508
|
+
workflowRunId: input.workflowRunId
|
|
3509
|
+
});
|
|
3510
|
+
this.eventLog?.record("agent.graph.started", {
|
|
3511
|
+
workflowRunId: input.workflowRunId,
|
|
3512
|
+
trace: graphTrace,
|
|
3513
|
+
levels: validation.levels
|
|
3514
|
+
});
|
|
3515
|
+
try {
|
|
3516
|
+
for (const level of validation.levels) {
|
|
3517
|
+
const batches = chunk(level, input.graph.parallelism ?? level.length);
|
|
3518
|
+
for (const batch of batches) {
|
|
3519
|
+
const levelResults = await Promise.all(
|
|
3520
|
+
batch.map(
|
|
3521
|
+
(nodeId) => this.executeNode({
|
|
3522
|
+
node: input.graph.nodes.find((candidate) => candidate.id === nodeId),
|
|
3523
|
+
graph: input.graph,
|
|
3524
|
+
workflowRunId: input.workflowRunId,
|
|
3525
|
+
input: input.input,
|
|
3526
|
+
graphTrace,
|
|
3527
|
+
nodeResults
|
|
3528
|
+
})
|
|
3529
|
+
)
|
|
3530
|
+
);
|
|
3531
|
+
for (const result2 of levelResults) {
|
|
3532
|
+
nodeResults.set(result2.taskId, result2);
|
|
3533
|
+
artifacts.push(...result2.artifacts.map(cloneArtifact));
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3537
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3538
|
+
const result = {
|
|
3539
|
+
id: input.workflowRunId,
|
|
3540
|
+
status: "completed",
|
|
3541
|
+
nodeResults: Object.fromEntries(nodeResults),
|
|
3542
|
+
artifacts,
|
|
3543
|
+
stateSnapshot: this.sharedState.snapshot(),
|
|
3544
|
+
trace: graphTrace,
|
|
3545
|
+
startedAt,
|
|
3546
|
+
completedAt
|
|
3547
|
+
};
|
|
3548
|
+
this.eventLog?.record("agent.graph.completed", {
|
|
3549
|
+
workflowRunId: input.workflowRunId,
|
|
3550
|
+
trace: graphTrace,
|
|
3551
|
+
nodeCount: nodeResults.size
|
|
3552
|
+
});
|
|
3553
|
+
return result;
|
|
3554
|
+
} catch (error) {
|
|
3555
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3556
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3557
|
+
this.eventLog?.record("agent.graph.failed", {
|
|
3558
|
+
workflowRunId: input.workflowRunId,
|
|
3559
|
+
trace: graphTrace,
|
|
3560
|
+
error: message
|
|
3561
|
+
});
|
|
3562
|
+
return {
|
|
3563
|
+
id: input.workflowRunId,
|
|
3564
|
+
status: "failed",
|
|
3565
|
+
nodeResults: Object.fromEntries(nodeResults),
|
|
3566
|
+
artifacts,
|
|
3567
|
+
stateSnapshot: this.sharedState.snapshot(),
|
|
3568
|
+
trace: graphTrace,
|
|
3569
|
+
startedAt,
|
|
3570
|
+
completedAt,
|
|
3571
|
+
error: message
|
|
3572
|
+
};
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
async executeNode(input) {
|
|
3576
|
+
const attempts = input.node.retryPolicy?.maxAttempts ?? 1;
|
|
3577
|
+
let lastResult;
|
|
3578
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
3579
|
+
const task = graphNodeToTask(input.node, input.input);
|
|
3580
|
+
const trace = createAgentTraceContext({
|
|
3581
|
+
traceId: input.graphTrace.traceId,
|
|
3582
|
+
parentSpanId: input.graphTrace.spanId,
|
|
3583
|
+
workflowRunId: input.workflowRunId,
|
|
3584
|
+
taskId: task.id
|
|
3585
|
+
});
|
|
3586
|
+
this.eventLog?.record("agent.started", {
|
|
3587
|
+
workflowRunId: input.workflowRunId,
|
|
3588
|
+
nodeId: input.node.id,
|
|
3589
|
+
taskId: task.id,
|
|
3590
|
+
role: task.role,
|
|
3591
|
+
attempt,
|
|
3592
|
+
trace
|
|
3593
|
+
});
|
|
3594
|
+
const result = await this.nodeExecutor({
|
|
3595
|
+
node: input.node,
|
|
3596
|
+
task,
|
|
3597
|
+
attempt,
|
|
3598
|
+
workflowRunId: input.workflowRunId,
|
|
3599
|
+
trace,
|
|
3600
|
+
dependencyResults: input.nodeResults,
|
|
3601
|
+
sharedState: this.sharedState,
|
|
3602
|
+
eventLog: this.eventLog ?? NULL_EVENT_LOG
|
|
3603
|
+
});
|
|
3604
|
+
lastResult = result;
|
|
3605
|
+
for (const artifact of result.artifacts) {
|
|
3606
|
+
this.sharedState.write({
|
|
3607
|
+
kind: "artifact",
|
|
3608
|
+
key: artifact.id,
|
|
3609
|
+
value: artifact,
|
|
3610
|
+
provenance: {
|
|
3611
|
+
workflowRunId: input.workflowRunId,
|
|
3612
|
+
agentRunId: result.id,
|
|
3613
|
+
nodeId: input.node.id,
|
|
3614
|
+
taskId: task.id,
|
|
3615
|
+
risk: input.node.risk
|
|
3616
|
+
}
|
|
3617
|
+
});
|
|
3618
|
+
this.eventLog?.record("agent.artifact.created", {
|
|
3619
|
+
workflowRunId: input.workflowRunId,
|
|
3620
|
+
nodeId: input.node.id,
|
|
3621
|
+
agentRunId: result.id,
|
|
3622
|
+
artifactId: artifact.id,
|
|
3623
|
+
kind: artifact.kind,
|
|
3624
|
+
trace
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
if (result.success) {
|
|
3628
|
+
await this.evaluateNodeGates(input.graph, input.node, result, input.workflowRunId, trace);
|
|
3629
|
+
this.eventLog?.record("agent.completed", {
|
|
3630
|
+
workflowRunId: input.workflowRunId,
|
|
3631
|
+
nodeId: input.node.id,
|
|
3632
|
+
agentRunId: result.id,
|
|
3633
|
+
taskId: task.id,
|
|
3634
|
+
role: result.role,
|
|
3635
|
+
attempt,
|
|
3636
|
+
trace
|
|
3637
|
+
});
|
|
3638
|
+
return result;
|
|
3639
|
+
}
|
|
3640
|
+
this.eventLog?.record("agent.failed", {
|
|
3641
|
+
workflowRunId: input.workflowRunId,
|
|
3642
|
+
nodeId: input.node.id,
|
|
3643
|
+
agentRunId: result.id,
|
|
3644
|
+
taskId: task.id,
|
|
3645
|
+
role: result.role,
|
|
3646
|
+
attempt,
|
|
3647
|
+
error: result.error,
|
|
3648
|
+
trace
|
|
3649
|
+
});
|
|
3650
|
+
if (attempt < attempts && input.node.retryPolicy?.backoffMs) {
|
|
3651
|
+
await new Promise((resolve3) => setTimeout(resolve3, input.node.retryPolicy.backoffMs));
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
throw new Error(
|
|
3655
|
+
`Node '${input.node.id}' failed after ${attempts} attempt(s): ${lastResult?.error ?? "unknown error"}`
|
|
3656
|
+
);
|
|
3657
|
+
}
|
|
3658
|
+
async evaluateNodeGates(graph, node, result, workflowRunId, trace) {
|
|
3659
|
+
for (const gateId of node.gates ?? []) {
|
|
3660
|
+
const gate = graph.gates?.find((candidate) => candidate.id === gateId);
|
|
3661
|
+
if (!gate) continue;
|
|
3662
|
+
const evaluation = await this.gateEvaluator({
|
|
3663
|
+
gate,
|
|
3664
|
+
node,
|
|
3665
|
+
result,
|
|
3666
|
+
workflowRunId,
|
|
3667
|
+
trace,
|
|
3668
|
+
sharedState: this.sharedState,
|
|
3669
|
+
eventLog: this.eventLog ?? NULL_EVENT_LOG
|
|
3670
|
+
});
|
|
3671
|
+
const eventType = evaluation.passed ? "workflow.gate.passed" : "workflow.gate.failed";
|
|
3672
|
+
this.eventLog?.record(eventType, {
|
|
3673
|
+
workflowRunId,
|
|
3674
|
+
nodeId: node.id,
|
|
3675
|
+
gateId: gate.id,
|
|
3676
|
+
kind: gate.kind,
|
|
3677
|
+
required: gate.required,
|
|
3678
|
+
reason: evaluation.reason,
|
|
3679
|
+
trace
|
|
3680
|
+
});
|
|
3681
|
+
if (!evaluation.passed && gate.required) {
|
|
3682
|
+
throw new Error(
|
|
3683
|
+
`Required gate '${gate.id}' failed for node '${node.id}': ${evaluation.reason ?? "no reason"}`
|
|
3684
|
+
);
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
};
|
|
3367
3689
|
function createAgentArtifact(input) {
|
|
3368
3690
|
return {
|
|
3369
3691
|
...input,
|
|
@@ -3495,6 +3817,101 @@ function buildExecutionLevels(graph, issues) {
|
|
|
3495
3817
|
}
|
|
3496
3818
|
return levels;
|
|
3497
3819
|
}
|
|
3820
|
+
var NULL_EVENT_LOG = {
|
|
3821
|
+
record(type, data = {}) {
|
|
3822
|
+
return {
|
|
3823
|
+
id: `event-${randomUUID()}`,
|
|
3824
|
+
type,
|
|
3825
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3826
|
+
data
|
|
3827
|
+
};
|
|
3828
|
+
},
|
|
3829
|
+
list() {
|
|
3830
|
+
return [];
|
|
3831
|
+
},
|
|
3832
|
+
count() {
|
|
3833
|
+
return 0;
|
|
3834
|
+
},
|
|
3835
|
+
clear() {
|
|
3836
|
+
}
|
|
3837
|
+
};
|
|
3838
|
+
function graphNodeToTask(node, workflowInput) {
|
|
3839
|
+
return {
|
|
3840
|
+
id: node.id,
|
|
3841
|
+
role: node.agentRole ?? "coder",
|
|
3842
|
+
objective: node.description,
|
|
3843
|
+
context: {
|
|
3844
|
+
workflowInput,
|
|
3845
|
+
condition: node.condition
|
|
3846
|
+
},
|
|
3847
|
+
dependencies: node.dependsOn,
|
|
3848
|
+
constraints: node.requiredTools?.map((tool) => `Requires tool: ${tool}`)
|
|
3849
|
+
};
|
|
3850
|
+
}
|
|
3851
|
+
async function defaultAgentGraphNodeExecutor(execution) {
|
|
3852
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3853
|
+
const dependencyOutputs = Object.fromEntries(
|
|
3854
|
+
[...execution.dependencyResults.entries()].map(([id, result]) => [
|
|
3855
|
+
id,
|
|
3856
|
+
{ success: result.success, output: result.output }
|
|
3857
|
+
])
|
|
3858
|
+
);
|
|
3859
|
+
const output = [
|
|
3860
|
+
`Node '${execution.node.id}' executed by ${execution.task.role}.`,
|
|
3861
|
+
`Objective: ${execution.task.objective}`,
|
|
3862
|
+
Object.keys(dependencyOutputs).length > 0 ? `Dependencies: ${JSON.stringify(dependencyOutputs)}` : "Dependencies: none"
|
|
3863
|
+
].join("\n");
|
|
3864
|
+
return normalizeAgentRunResult({
|
|
3865
|
+
id: `${execution.workflowRunId}-${execution.node.id}-attempt-${execution.attempt}`,
|
|
3866
|
+
taskId: execution.task.id,
|
|
3867
|
+
role: execution.task.role,
|
|
3868
|
+
success: true,
|
|
3869
|
+
output,
|
|
3870
|
+
startedAt,
|
|
3871
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3872
|
+
turns: 0,
|
|
3873
|
+
toolsUsed: [],
|
|
3874
|
+
durationMs: 0,
|
|
3875
|
+
metadata: {
|
|
3876
|
+
workflowRunId: execution.workflowRunId,
|
|
3877
|
+
nodeId: execution.node.id,
|
|
3878
|
+
trace: execution.trace,
|
|
3879
|
+
simulated: true
|
|
3880
|
+
}
|
|
3881
|
+
});
|
|
3882
|
+
}
|
|
3883
|
+
async function defaultAgentGateEvaluator(input) {
|
|
3884
|
+
if (!input.result.success) {
|
|
3885
|
+
return { passed: false, reason: "Agent result was not successful." };
|
|
3886
|
+
}
|
|
3887
|
+
return { passed: true };
|
|
3888
|
+
}
|
|
3889
|
+
function chunk(items, size) {
|
|
3890
|
+
const safeSize = Math.max(1, size);
|
|
3891
|
+
const result = [];
|
|
3892
|
+
for (let index = 0; index < items.length; index += safeSize) {
|
|
3893
|
+
result.push(items.slice(index, index + safeSize));
|
|
3894
|
+
}
|
|
3895
|
+
return result;
|
|
3896
|
+
}
|
|
3897
|
+
function cloneUnknown(value) {
|
|
3898
|
+
if (value === void 0 || value === null) return value;
|
|
3899
|
+
try {
|
|
3900
|
+
return JSON.parse(JSON.stringify(value));
|
|
3901
|
+
} catch {
|
|
3902
|
+
return value;
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
function cloneRecord(record) {
|
|
3906
|
+
return {
|
|
3907
|
+
...record,
|
|
3908
|
+
value: cloneUnknown(record.value),
|
|
3909
|
+
provenance: { ...record.provenance }
|
|
3910
|
+
};
|
|
3911
|
+
}
|
|
3912
|
+
function isAgentArtifact(value) {
|
|
3913
|
+
return typeof value === "object" && value !== null && "id" in value && "kind" in value && "content" in value && "createdAt" in value;
|
|
3914
|
+
}
|
|
3498
3915
|
function cloneArtifact(artifact) {
|
|
3499
3916
|
return {
|
|
3500
3917
|
...artifact,
|
|
@@ -4433,29 +4850,7 @@ var AgentManager = class extends EventEmitter {
|
|
|
4433
4850
|
}
|
|
4434
4851
|
};
|
|
4435
4852
|
function agentTypeToRuntimeRole(type) {
|
|
4436
|
-
|
|
4437
|
-
case "explore":
|
|
4438
|
-
return "researcher";
|
|
4439
|
-
case "plan":
|
|
4440
|
-
return "planner";
|
|
4441
|
-
case "test":
|
|
4442
|
-
case "e2e":
|
|
4443
|
-
case "tdd":
|
|
4444
|
-
return "tester";
|
|
4445
|
-
case "debug":
|
|
4446
|
-
case "refactor":
|
|
4447
|
-
return "coder";
|
|
4448
|
-
case "review":
|
|
4449
|
-
return "reviewer";
|
|
4450
|
-
case "architect":
|
|
4451
|
-
return "architect";
|
|
4452
|
-
case "security":
|
|
4453
|
-
return "security";
|
|
4454
|
-
case "docs":
|
|
4455
|
-
return "docs";
|
|
4456
|
-
case "database":
|
|
4457
|
-
return "database";
|
|
4458
|
-
}
|
|
4853
|
+
return mapLegacyAgentRole(type);
|
|
4459
4854
|
}
|
|
4460
4855
|
|
|
4461
4856
|
// src/agents/provider-bridge.ts
|
|
@@ -5713,14 +6108,14 @@ ${message}
|
|
|
5713
6108
|
const subprocess = execa(command, options);
|
|
5714
6109
|
let stdoutBuffer = "";
|
|
5715
6110
|
let stderrBuffer = "";
|
|
5716
|
-
subprocess.stdout?.on("data", (
|
|
5717
|
-
const text2 =
|
|
6111
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
6112
|
+
const text2 = chunk2.toString();
|
|
5718
6113
|
stdoutBuffer += text2;
|
|
5719
6114
|
process.stdout.write(text2);
|
|
5720
6115
|
heartbeat.activity();
|
|
5721
6116
|
});
|
|
5722
|
-
subprocess.stderr?.on("data", (
|
|
5723
|
-
const text2 =
|
|
6117
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
6118
|
+
const text2 = chunk2.toString();
|
|
5724
6119
|
stderrBuffer += text2;
|
|
5725
6120
|
process.stderr.write(text2);
|
|
5726
6121
|
heartbeat.activity();
|
|
@@ -6396,7 +6791,7 @@ var AGENT_TYPES = [
|
|
|
6396
6791
|
"docs",
|
|
6397
6792
|
"database"
|
|
6398
6793
|
];
|
|
6399
|
-
var
|
|
6794
|
+
var LEGACY_ROLE_MAP2 = {
|
|
6400
6795
|
researcher: "explore",
|
|
6401
6796
|
coder: "debug",
|
|
6402
6797
|
// "debug" has write + bash + read — closest to general coding
|
|
@@ -6416,7 +6811,7 @@ var SpawnSimpleAgentSchema = z.object({
|
|
|
6416
6811
|
});
|
|
6417
6812
|
function resolveAgentType(input) {
|
|
6418
6813
|
if (input.type) return input.type;
|
|
6419
|
-
if (input.role && input.role in
|
|
6814
|
+
if (input.role && input.role in LEGACY_ROLE_MAP2) return LEGACY_ROLE_MAP2[input.role];
|
|
6420
6815
|
return "explore";
|
|
6421
6816
|
}
|
|
6422
6817
|
var spawnSimpleAgentTool = defineTool({
|
|
@@ -7682,25 +8077,25 @@ var DuplicationAnalyzer = class {
|
|
|
7682
8077
|
const lines = content.split("\n");
|
|
7683
8078
|
totalLines += lines.length;
|
|
7684
8079
|
for (let i = 0; i <= lines.length - this.minLines; i++) {
|
|
7685
|
-
const
|
|
7686
|
-
if (
|
|
7687
|
-
if (!chunks.has(
|
|
7688
|
-
chunks.set(
|
|
8080
|
+
const chunk2 = lines.slice(i, i + this.minLines).join("\n").trim();
|
|
8081
|
+
if (chunk2.length < 20) continue;
|
|
8082
|
+
if (!chunks.has(chunk2)) {
|
|
8083
|
+
chunks.set(chunk2, []);
|
|
7689
8084
|
}
|
|
7690
|
-
chunks.get(
|
|
8085
|
+
chunks.get(chunk2).push({ file, line: i + 1 });
|
|
7691
8086
|
}
|
|
7692
8087
|
} catch {
|
|
7693
8088
|
}
|
|
7694
8089
|
}
|
|
7695
8090
|
const duplicates = [];
|
|
7696
8091
|
let duplicateLines = 0;
|
|
7697
|
-
for (const [
|
|
8092
|
+
for (const [chunk2, locations] of chunks.entries()) {
|
|
7698
8093
|
if (locations.length > 1) {
|
|
7699
8094
|
duplicates.push({
|
|
7700
|
-
lines:
|
|
8095
|
+
lines: chunk2.split("\n"),
|
|
7701
8096
|
files: locations
|
|
7702
8097
|
});
|
|
7703
|
-
duplicateLines +=
|
|
8098
|
+
duplicateLines += chunk2.split("\n").length * (locations.length - 1);
|
|
7704
8099
|
}
|
|
7705
8100
|
}
|
|
7706
8101
|
const percentage = totalLines > 0 ? duplicateLines / totalLines * 100 : 0;
|
|
@@ -11831,14 +12226,14 @@ ${message}
|
|
|
11831
12226
|
const subprocess = execa(pm, cmdArgs, options);
|
|
11832
12227
|
let stdoutBuffer = "";
|
|
11833
12228
|
let stderrBuffer = "";
|
|
11834
|
-
subprocess.stdout?.on("data", (
|
|
11835
|
-
const text2 =
|
|
12229
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
12230
|
+
const text2 = chunk2.toString();
|
|
11836
12231
|
stdoutBuffer += text2;
|
|
11837
12232
|
process.stdout.write(text2);
|
|
11838
12233
|
heartbeat.activity();
|
|
11839
12234
|
});
|
|
11840
|
-
subprocess.stderr?.on("data", (
|
|
11841
|
-
const text2 =
|
|
12235
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
12236
|
+
const text2 = chunk2.toString();
|
|
11842
12237
|
stderrBuffer += text2;
|
|
11843
12238
|
process.stderr.write(text2);
|
|
11844
12239
|
heartbeat.activity();
|
|
@@ -11956,14 +12351,14 @@ ${message}
|
|
|
11956
12351
|
const subprocess = execa(pm, cmdArgs, options);
|
|
11957
12352
|
let stdoutBuffer = "";
|
|
11958
12353
|
let stderrBuffer = "";
|
|
11959
|
-
subprocess.stdout?.on("data", (
|
|
11960
|
-
const text2 =
|
|
12354
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
12355
|
+
const text2 = chunk2.toString();
|
|
11961
12356
|
stdoutBuffer += text2;
|
|
11962
12357
|
process.stdout.write(text2);
|
|
11963
12358
|
heartbeat.activity();
|
|
11964
12359
|
});
|
|
11965
|
-
subprocess.stderr?.on("data", (
|
|
11966
|
-
const text2 =
|
|
12360
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
12361
|
+
const text2 = chunk2.toString();
|
|
11967
12362
|
stderrBuffer += text2;
|
|
11968
12363
|
process.stderr.write(text2);
|
|
11969
12364
|
heartbeat.activity();
|
|
@@ -12058,14 +12453,14 @@ ${message}
|
|
|
12058
12453
|
const subprocess = execa("make", cmdArgs, options);
|
|
12059
12454
|
let stdoutBuffer = "";
|
|
12060
12455
|
let stderrBuffer = "";
|
|
12061
|
-
subprocess.stdout?.on("data", (
|
|
12062
|
-
const text2 =
|
|
12456
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
12457
|
+
const text2 = chunk2.toString();
|
|
12063
12458
|
stdoutBuffer += text2;
|
|
12064
12459
|
process.stdout.write(text2);
|
|
12065
12460
|
heartbeat.activity();
|
|
12066
12461
|
});
|
|
12067
|
-
subprocess.stderr?.on("data", (
|
|
12068
|
-
const text2 =
|
|
12462
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
12463
|
+
const text2 = chunk2.toString();
|
|
12069
12464
|
stderrBuffer += text2;
|
|
12070
12465
|
process.stderr.write(text2);
|
|
12071
12466
|
heartbeat.activity();
|
|
@@ -12161,14 +12556,14 @@ ${message}
|
|
|
12161
12556
|
const subprocess = execa("npx", ["tsc", ...cmdArgs], options);
|
|
12162
12557
|
let stdoutBuffer = "";
|
|
12163
12558
|
let stderrBuffer = "";
|
|
12164
|
-
subprocess.stdout?.on("data", (
|
|
12165
|
-
const text2 =
|
|
12559
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
12560
|
+
const text2 = chunk2.toString();
|
|
12166
12561
|
stdoutBuffer += text2;
|
|
12167
12562
|
process.stdout.write(text2);
|
|
12168
12563
|
heartbeat.activity();
|
|
12169
12564
|
});
|
|
12170
|
-
subprocess.stderr?.on("data", (
|
|
12171
|
-
const text2 =
|
|
12565
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
12566
|
+
const text2 = chunk2.toString();
|
|
12172
12567
|
stderrBuffer += text2;
|
|
12173
12568
|
process.stderr.write(text2);
|
|
12174
12569
|
heartbeat.activity();
|
|
@@ -12265,14 +12660,14 @@ ${message}
|
|
|
12265
12660
|
});
|
|
12266
12661
|
let stdoutBuffer = "";
|
|
12267
12662
|
let stderrBuffer = "";
|
|
12268
|
-
subprocess.stdout?.on("data", (
|
|
12269
|
-
const text2 =
|
|
12663
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
12664
|
+
const text2 = chunk2.toString();
|
|
12270
12665
|
stdoutBuffer += text2;
|
|
12271
12666
|
process.stdout.write(text2);
|
|
12272
12667
|
heartbeat.activity();
|
|
12273
12668
|
});
|
|
12274
|
-
subprocess.stderr?.on("data", (
|
|
12275
|
-
const text2 =
|
|
12669
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
12670
|
+
const text2 = chunk2.toString();
|
|
12276
12671
|
stderrBuffer += text2;
|
|
12277
12672
|
process.stderr.write(text2);
|
|
12278
12673
|
heartbeat.activity();
|
|
@@ -12352,14 +12747,14 @@ ${message}
|
|
|
12352
12747
|
});
|
|
12353
12748
|
let stdoutBuffer = "";
|
|
12354
12749
|
let stderrBuffer = "";
|
|
12355
|
-
subprocess.stdout?.on("data", (
|
|
12356
|
-
const text2 =
|
|
12750
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
12751
|
+
const text2 = chunk2.toString();
|
|
12357
12752
|
stdoutBuffer += text2;
|
|
12358
12753
|
process.stdout.write(text2);
|
|
12359
12754
|
heartbeat.activity();
|
|
12360
12755
|
});
|
|
12361
|
-
subprocess.stderr?.on("data", (
|
|
12362
|
-
const text2 =
|
|
12756
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
12757
|
+
const text2 = chunk2.toString();
|
|
12363
12758
|
stderrBuffer += text2;
|
|
12364
12759
|
process.stderr.write(text2);
|
|
12365
12760
|
heartbeat.activity();
|
|
@@ -15885,13 +16280,13 @@ Examples:
|
|
|
15885
16280
|
const content = await fs19.readFile(fullPath, "utf-8");
|
|
15886
16281
|
if (content.length > 1e5) continue;
|
|
15887
16282
|
const fileChunks = chunkContent(content, DEFAULT_CHUNK_SIZE);
|
|
15888
|
-
for (const
|
|
15889
|
-
const vector = await getEmbedding(
|
|
16283
|
+
for (const chunk2 of fileChunks) {
|
|
16284
|
+
const vector = await getEmbedding(chunk2.text);
|
|
15890
16285
|
chunks.push({
|
|
15891
16286
|
file,
|
|
15892
|
-
startLine:
|
|
15893
|
-
endLine:
|
|
15894
|
-
text:
|
|
16287
|
+
startLine: chunk2.startLine,
|
|
16288
|
+
endLine: chunk2.endLine,
|
|
16289
|
+
text: chunk2.text,
|
|
15895
16290
|
vector,
|
|
15896
16291
|
mtime: stat2.mtimeMs
|
|
15897
16292
|
});
|
|
@@ -15925,9 +16320,9 @@ Examples:
|
|
|
15925
16320
|
}
|
|
15926
16321
|
}
|
|
15927
16322
|
const queryVector = await getEmbedding(query);
|
|
15928
|
-
const scored = index.chunks.map((
|
|
15929
|
-
chunk,
|
|
15930
|
-
score: cosineSimilarity(queryVector,
|
|
16323
|
+
const scored = index.chunks.map((chunk2) => ({
|
|
16324
|
+
chunk: chunk2,
|
|
16325
|
+
score: cosineSimilarity(queryVector, chunk2.vector)
|
|
15931
16326
|
}));
|
|
15932
16327
|
const filtered = scored.filter((s) => s.score >= effectiveThreshold).sort((a, b) => b.score - a.score).slice(0, effectiveMaxResults);
|
|
15933
16328
|
const results = filtered.map((s) => {
|
|
@@ -21138,7 +21533,6 @@ var READ_ONLY_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
21138
21533
|
"recall_memory",
|
|
21139
21534
|
"list_memories",
|
|
21140
21535
|
"list_checkpoints",
|
|
21141
|
-
"spawnSimpleAgent",
|
|
21142
21536
|
"checkAgentCapability"
|
|
21143
21537
|
]);
|
|
21144
21538
|
var WRITE_CAPABLE_TOOL_NAMES = /* @__PURE__ */ new Set(["run_linter"]);
|
|
@@ -21184,6 +21578,22 @@ var DefaultPermissionPolicy = class {
|
|
|
21184
21578
|
return { allowed: true, risk };
|
|
21185
21579
|
}
|
|
21186
21580
|
canExecuteToolInput(mode, tool, input) {
|
|
21581
|
+
if (tool.name === "spawnSimpleAgent") {
|
|
21582
|
+
const risk = riskForSpawnedAgent(input);
|
|
21583
|
+
const definition2 = getAgentMode(mode);
|
|
21584
|
+
if (definition2.readOnly && risk !== "read-only" && risk !== "network") {
|
|
21585
|
+
return {
|
|
21586
|
+
allowed: false,
|
|
21587
|
+
reason: `${definition2.label} mode is read-only; spawnSimpleAgent with this role can perform ${risk} work.`,
|
|
21588
|
+
risk
|
|
21589
|
+
};
|
|
21590
|
+
}
|
|
21591
|
+
return {
|
|
21592
|
+
allowed: true,
|
|
21593
|
+
requiresConfirmation: risk === "destructive" || risk === "secrets-sensitive",
|
|
21594
|
+
risk
|
|
21595
|
+
};
|
|
21596
|
+
}
|
|
21187
21597
|
if (tool.name !== "run_linter") {
|
|
21188
21598
|
return this.canExecuteTool(mode, tool);
|
|
21189
21599
|
}
|
|
@@ -21203,6 +21613,37 @@ var DefaultPermissionPolicy = class {
|
|
|
21203
21613
|
function createPermissionPolicy() {
|
|
21204
21614
|
return new DefaultPermissionPolicy();
|
|
21205
21615
|
}
|
|
21616
|
+
function riskForSpawnedAgent(input) {
|
|
21617
|
+
const type = typeof input["type"] === "string" ? input["type"] : void 0;
|
|
21618
|
+
const role = typeof input["role"] === "string" ? input["role"] : void 0;
|
|
21619
|
+
const resolved = type ?? role;
|
|
21620
|
+
switch (resolved) {
|
|
21621
|
+
case "explore":
|
|
21622
|
+
case "plan":
|
|
21623
|
+
case "review":
|
|
21624
|
+
case "architect":
|
|
21625
|
+
case "security":
|
|
21626
|
+
case "docs":
|
|
21627
|
+
case "researcher":
|
|
21628
|
+
case "reviewer":
|
|
21629
|
+
case "planner":
|
|
21630
|
+
return "read-only";
|
|
21631
|
+
case "database":
|
|
21632
|
+
return "secrets-sensitive";
|
|
21633
|
+
case "test":
|
|
21634
|
+
case "tdd":
|
|
21635
|
+
case "e2e":
|
|
21636
|
+
case "tester":
|
|
21637
|
+
return "destructive";
|
|
21638
|
+
case "debug":
|
|
21639
|
+
case "refactor":
|
|
21640
|
+
case "coder":
|
|
21641
|
+
case "optimizer":
|
|
21642
|
+
return "write";
|
|
21643
|
+
default:
|
|
21644
|
+
return "read-only";
|
|
21645
|
+
}
|
|
21646
|
+
}
|
|
21206
21647
|
|
|
21207
21648
|
// src/providers/anthropic.ts
|
|
21208
21649
|
init_errors();
|
|
@@ -22340,12 +22781,12 @@ var OpenAIProvider = class {
|
|
|
22340
22781
|
...reasoningEffort && { reasoning_effort: reasoningEffort }
|
|
22341
22782
|
});
|
|
22342
22783
|
let streamStopReason;
|
|
22343
|
-
for await (const
|
|
22344
|
-
const delta =
|
|
22784
|
+
for await (const chunk2 of stream) {
|
|
22785
|
+
const delta = chunk2.choices[0]?.delta;
|
|
22345
22786
|
if (delta?.content) {
|
|
22346
22787
|
yield { type: "text", text: delta.content };
|
|
22347
22788
|
}
|
|
22348
|
-
const finishReason =
|
|
22789
|
+
const finishReason = chunk2.choices[0]?.finish_reason;
|
|
22349
22790
|
if (finishReason) {
|
|
22350
22791
|
streamStopReason = this.mapFinishReason(finishReason);
|
|
22351
22792
|
}
|
|
@@ -22414,8 +22855,8 @@ var OpenAIProvider = class {
|
|
|
22414
22855
|
});
|
|
22415
22856
|
try {
|
|
22416
22857
|
let streamStopReason;
|
|
22417
|
-
for await (const
|
|
22418
|
-
const delta =
|
|
22858
|
+
for await (const chunk2 of stream) {
|
|
22859
|
+
const delta = chunk2.choices[0]?.delta;
|
|
22419
22860
|
if (delta?.content || delta?.tool_calls) {
|
|
22420
22861
|
lastActivityTime = Date.now();
|
|
22421
22862
|
}
|
|
@@ -22453,7 +22894,7 @@ var OpenAIProvider = class {
|
|
|
22453
22894
|
}
|
|
22454
22895
|
}
|
|
22455
22896
|
}
|
|
22456
|
-
const finishReason =
|
|
22897
|
+
const finishReason = chunk2.choices[0]?.finish_reason;
|
|
22457
22898
|
if (finishReason) {
|
|
22458
22899
|
streamStopReason = this.mapFinishReason(finishReason);
|
|
22459
22900
|
}
|
|
@@ -24169,12 +24610,12 @@ var GeminiProvider = class {
|
|
|
24169
24610
|
config: this.buildConfig(messages, options)
|
|
24170
24611
|
});
|
|
24171
24612
|
let streamStopReason = "end_turn";
|
|
24172
|
-
for await (const
|
|
24173
|
-
const text2 =
|
|
24613
|
+
for await (const chunk2 of stream) {
|
|
24614
|
+
const text2 = chunk2.text;
|
|
24174
24615
|
if (text2) {
|
|
24175
24616
|
yield { type: "text", text: text2 };
|
|
24176
24617
|
}
|
|
24177
|
-
const finishReason =
|
|
24618
|
+
const finishReason = chunk2.candidates?.[0]?.finishReason;
|
|
24178
24619
|
if (finishReason) {
|
|
24179
24620
|
streamStopReason = this.mapFinishReason(finishReason);
|
|
24180
24621
|
}
|
|
@@ -24195,12 +24636,12 @@ var GeminiProvider = class {
|
|
|
24195
24636
|
let streamStopReason = "end_turn";
|
|
24196
24637
|
let fallbackToolCounter = 0;
|
|
24197
24638
|
const emittedToolIds = /* @__PURE__ */ new Set();
|
|
24198
|
-
for await (const
|
|
24199
|
-
const text2 =
|
|
24639
|
+
for await (const chunk2 of stream) {
|
|
24640
|
+
const text2 = chunk2.text;
|
|
24200
24641
|
if (text2) {
|
|
24201
24642
|
yield { type: "text", text: text2 };
|
|
24202
24643
|
}
|
|
24203
|
-
const toolCalls = this.extractToolCalls(
|
|
24644
|
+
const toolCalls = this.extractToolCalls(chunk2, { includeLegacyFunctionCalls: true });
|
|
24204
24645
|
for (const toolCall of toolCalls) {
|
|
24205
24646
|
const toolCallId = toolCall.id ?? `gemini_call_${++fallbackToolCounter}`;
|
|
24206
24647
|
if (emittedToolIds.has(toolCallId)) continue;
|
|
@@ -24221,7 +24662,7 @@ var GeminiProvider = class {
|
|
|
24221
24662
|
toolCall: normalizedToolCall
|
|
24222
24663
|
};
|
|
24223
24664
|
}
|
|
24224
|
-
const finishReason =
|
|
24665
|
+
const finishReason = chunk2.candidates?.[0]?.finishReason;
|
|
24225
24666
|
if (toolCalls.length > 0) {
|
|
24226
24667
|
streamStopReason = "tool_use";
|
|
24227
24668
|
} else if (finishReason) {
|
|
@@ -24564,8 +25005,8 @@ var VertexProvider = class {
|
|
|
24564
25005
|
this.ensureInitialized();
|
|
24565
25006
|
const stream = await this.streamGenerateContent(messages, options);
|
|
24566
25007
|
let stopReason = "end_turn";
|
|
24567
|
-
for await (const
|
|
24568
|
-
const candidate =
|
|
25008
|
+
for await (const chunk2 of stream) {
|
|
25009
|
+
const candidate = chunk2.candidates?.[0];
|
|
24569
25010
|
const parts = candidate?.content?.parts ?? [];
|
|
24570
25011
|
for (const part of parts) {
|
|
24571
25012
|
if (part.text) {
|
|
@@ -24587,8 +25028,8 @@ var VertexProvider = class {
|
|
|
24587
25028
|
let stopReason = "end_turn";
|
|
24588
25029
|
let streamToolCallCounter = 0;
|
|
24589
25030
|
const emittedToolFingerprints = /* @__PURE__ */ new Set();
|
|
24590
|
-
for await (const
|
|
24591
|
-
const candidate =
|
|
25031
|
+
for await (const chunk2 of stream) {
|
|
25032
|
+
const candidate = chunk2.candidates?.[0];
|
|
24592
25033
|
const parts = candidate?.content?.parts ?? [];
|
|
24593
25034
|
for (const part of parts) {
|
|
24594
25035
|
if (part.text) {
|
|
@@ -25188,9 +25629,9 @@ var ResilientProvider = class {
|
|
|
25188
25629
|
}
|
|
25189
25630
|
let emittedChunk = false;
|
|
25190
25631
|
try {
|
|
25191
|
-
for await (const
|
|
25632
|
+
for await (const chunk2 of createStream()) {
|
|
25192
25633
|
emittedChunk = true;
|
|
25193
|
-
yield
|
|
25634
|
+
yield chunk2;
|
|
25194
25635
|
}
|
|
25195
25636
|
this.breaker.recordSuccess();
|
|
25196
25637
|
return;
|
|
@@ -25737,19 +26178,26 @@ function createWorkflowCatalog(workflows) {
|
|
|
25737
26178
|
|
|
25738
26179
|
// src/runtime/workflow-engine.ts
|
|
25739
26180
|
var WorkflowEngine = class {
|
|
25740
|
-
constructor(catalog = createWorkflowCatalog(), eventLog = createEventLog()) {
|
|
26181
|
+
constructor(catalog = createWorkflowCatalog(), eventLog = createEventLog(), options = {}) {
|
|
25741
26182
|
this.catalog = catalog;
|
|
25742
26183
|
this.eventLog = eventLog;
|
|
26184
|
+
this.sharedState = options.sharedState ?? new InMemorySharedWorkspaceStore();
|
|
26185
|
+
this.nodeExecutor = options.nodeExecutor;
|
|
25743
26186
|
}
|
|
25744
26187
|
catalog;
|
|
25745
26188
|
eventLog;
|
|
25746
26189
|
handlers = /* @__PURE__ */ new Map();
|
|
26190
|
+
sharedState;
|
|
26191
|
+
nodeExecutor;
|
|
25747
26192
|
registerHandler(workflowId, handler) {
|
|
25748
26193
|
if (!this.catalog.get(workflowId)) {
|
|
25749
26194
|
throw new Error(`Unknown workflow: ${workflowId}`);
|
|
25750
26195
|
}
|
|
25751
26196
|
this.handlers.set(workflowId, handler);
|
|
25752
26197
|
}
|
|
26198
|
+
registerNodeExecutor(executor) {
|
|
26199
|
+
this.nodeExecutor = executor;
|
|
26200
|
+
}
|
|
25753
26201
|
createPlan(workflowId, input) {
|
|
25754
26202
|
return this.catalog.createPlan(workflowId, input, this.eventLog);
|
|
25755
26203
|
}
|
|
@@ -25759,23 +26207,35 @@ var WorkflowEngine = class {
|
|
|
25759
26207
|
throw new Error(`Unknown workflow: ${request.workflowId}`);
|
|
25760
26208
|
}
|
|
25761
26209
|
const handler = this.handlers.get(request.workflowId);
|
|
25762
|
-
if (!handler) {
|
|
25763
|
-
throw new Error(`No handler registered for workflow: ${request.workflowId}`);
|
|
25764
|
-
}
|
|
25765
26210
|
const plan = request.plan ?? this.createPlan(request.workflowId, request.input);
|
|
25766
26211
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
25767
26212
|
const runId = `${request.workflowId}-run-${Date.now().toString(36)}`;
|
|
26213
|
+
const trace = createAgentTraceContext({ workflowRunId: runId });
|
|
25768
26214
|
this.eventLog.record("workflow.started", {
|
|
25769
26215
|
workflowId: request.workflowId,
|
|
25770
26216
|
planId: plan.id,
|
|
25771
|
-
runId
|
|
26217
|
+
runId,
|
|
26218
|
+
trace
|
|
25772
26219
|
});
|
|
25773
26220
|
try {
|
|
25774
|
-
const
|
|
26221
|
+
const graphResult = handler ? void 0 : await new AgentGraphEngine({
|
|
26222
|
+
eventLog: this.eventLog,
|
|
26223
|
+
sharedState: this.sharedState,
|
|
26224
|
+
nodeExecutor: this.nodeExecutor,
|
|
26225
|
+
trace
|
|
26226
|
+
}).run({
|
|
26227
|
+
workflowRunId: runId,
|
|
26228
|
+
graph: workflowToAgentGraph(workflow),
|
|
26229
|
+
input: request.input
|
|
26230
|
+
});
|
|
26231
|
+
const output = graphResult ?? await handler(request.input, {
|
|
25775
26232
|
workflow,
|
|
25776
26233
|
plan,
|
|
25777
26234
|
eventLog: this.eventLog
|
|
25778
26235
|
});
|
|
26236
|
+
if (graphResult?.status === "failed") {
|
|
26237
|
+
throw new Error(graphResult.error ?? "Workflow graph failed");
|
|
26238
|
+
}
|
|
25779
26239
|
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
25780
26240
|
const result = {
|
|
25781
26241
|
id: runId,
|
|
@@ -25783,12 +26243,15 @@ var WorkflowEngine = class {
|
|
|
25783
26243
|
status: "completed",
|
|
25784
26244
|
output,
|
|
25785
26245
|
startedAt,
|
|
25786
|
-
completedAt
|
|
26246
|
+
completedAt,
|
|
26247
|
+
graphResult,
|
|
26248
|
+
trace
|
|
25787
26249
|
};
|
|
25788
26250
|
this.eventLog.record("workflow.completed", {
|
|
25789
26251
|
workflowId: request.workflowId,
|
|
25790
26252
|
planId: plan.id,
|
|
25791
|
-
runId
|
|
26253
|
+
runId,
|
|
26254
|
+
trace
|
|
25792
26255
|
});
|
|
25793
26256
|
return result;
|
|
25794
26257
|
} catch (error) {
|
|
@@ -25798,7 +26261,8 @@ var WorkflowEngine = class {
|
|
|
25798
26261
|
workflowId: request.workflowId,
|
|
25799
26262
|
planId: plan.id,
|
|
25800
26263
|
runId,
|
|
25801
|
-
error: message
|
|
26264
|
+
error: message,
|
|
26265
|
+
trace
|
|
25802
26266
|
});
|
|
25803
26267
|
return {
|
|
25804
26268
|
id: runId,
|
|
@@ -25807,13 +26271,14 @@ var WorkflowEngine = class {
|
|
|
25807
26271
|
output: null,
|
|
25808
26272
|
startedAt,
|
|
25809
26273
|
completedAt,
|
|
25810
|
-
error: message
|
|
26274
|
+
error: message,
|
|
26275
|
+
trace
|
|
25811
26276
|
};
|
|
25812
26277
|
}
|
|
25813
26278
|
}
|
|
25814
26279
|
};
|
|
25815
|
-
function createWorkflowEngine(catalog, eventLog) {
|
|
25816
|
-
return new WorkflowEngine(catalog, eventLog);
|
|
26280
|
+
function createWorkflowEngine(catalog, eventLog, options) {
|
|
26281
|
+
return new WorkflowEngine(catalog, eventLog, options);
|
|
25817
26282
|
}
|
|
25818
26283
|
|
|
25819
26284
|
// src/runtime/agent-runtime.ts
|
|
@@ -25991,7 +26456,7 @@ var AgentRuntime = class {
|
|
|
25991
26456
|
let completed = false;
|
|
25992
26457
|
let failed = false;
|
|
25993
26458
|
try {
|
|
25994
|
-
for await (const
|
|
26459
|
+
for await (const chunk2 of provider.stream(messages, {
|
|
25995
26460
|
model: input.options?.model,
|
|
25996
26461
|
maxTokens: input.options?.maxTokens,
|
|
25997
26462
|
temperature: input.options?.temperature,
|
|
@@ -26001,12 +26466,12 @@ var AgentRuntime = class {
|
|
|
26001
26466
|
signal: input.options?.signal,
|
|
26002
26467
|
thinking: input.options?.thinking
|
|
26003
26468
|
})) {
|
|
26004
|
-
if (
|
|
26005
|
-
content +=
|
|
26469
|
+
if (chunk2.type === "text" && chunk2.text) {
|
|
26470
|
+
content += chunk2.text;
|
|
26006
26471
|
yield {
|
|
26007
26472
|
type: "text",
|
|
26008
26473
|
sessionId: effectiveSession.id,
|
|
26009
|
-
text:
|
|
26474
|
+
text: chunk2.text
|
|
26010
26475
|
};
|
|
26011
26476
|
}
|
|
26012
26477
|
}
|