@corbat-tech/coco 2.37.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/README.md +149 -13
- package/dist/adapters/index.d.ts +37 -0
- package/dist/adapters/index.js +46 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/agent-runtime-DJY9FzL_.d.ts +969 -0
- package/dist/blueprints-DYgm3K65.d.ts +99 -0
- package/dist/cli/index.js +1078 -169
- package/dist/cli/index.js.map +1 -1
- package/dist/extension-manifests-CAQQILhE.d.ts +147 -0
- package/dist/index-Dp1o8c9g.d.ts +2807 -0
- package/dist/index.d.ts +25 -913
- package/dist/index.js +1900 -101
- package/dist/index.js.map +1 -1
- package/dist/presets/index.d.ts +39 -0
- package/dist/presets/index.js +27050 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/profiles-BcyL-gQ9.d.ts +76 -0
- package/dist/rag-BakFRE-u.d.ts +31 -0
- package/dist/registry-CEpl9Jq0.d.ts +115 -0
- package/dist/runtime/index.d.ts +54 -0
- package/dist/runtime/index.js +27584 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +18751 -0
- package/dist/tools/index.js.map +1 -0
- package/package.json +9 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Logger } from 'tslog';
|
|
2
2
|
import * as fs4 from 'fs';
|
|
3
|
-
import fs4__default, { readFileSync, mkdirSync,
|
|
3
|
+
import fs4__default, { readFileSync, mkdirSync, writeFileSync, appendFileSync, renameSync, constants } from 'fs';
|
|
4
4
|
import * as path17 from 'path';
|
|
5
5
|
import path17__default, { dirname, join, basename, resolve } from 'path';
|
|
6
6
|
import * as fs16 from 'fs/promises';
|
|
@@ -7350,25 +7350,25 @@ var DuplicationAnalyzer = class {
|
|
|
7350
7350
|
const lines = content.split("\n");
|
|
7351
7351
|
totalLines += lines.length;
|
|
7352
7352
|
for (let i = 0; i <= lines.length - this.minLines; i++) {
|
|
7353
|
-
const
|
|
7354
|
-
if (
|
|
7355
|
-
if (!chunks.has(
|
|
7356
|
-
chunks.set(
|
|
7353
|
+
const chunk2 = lines.slice(i, i + this.minLines).join("\n").trim();
|
|
7354
|
+
if (chunk2.length < 20) continue;
|
|
7355
|
+
if (!chunks.has(chunk2)) {
|
|
7356
|
+
chunks.set(chunk2, []);
|
|
7357
7357
|
}
|
|
7358
|
-
chunks.get(
|
|
7358
|
+
chunks.get(chunk2).push({ file, line: i + 1 });
|
|
7359
7359
|
}
|
|
7360
7360
|
} catch {
|
|
7361
7361
|
}
|
|
7362
7362
|
}
|
|
7363
7363
|
const duplicates = [];
|
|
7364
7364
|
let duplicateLines = 0;
|
|
7365
|
-
for (const [
|
|
7365
|
+
for (const [chunk2, locations] of chunks.entries()) {
|
|
7366
7366
|
if (locations.length > 1) {
|
|
7367
7367
|
duplicates.push({
|
|
7368
|
-
lines:
|
|
7368
|
+
lines: chunk2.split("\n"),
|
|
7369
7369
|
files: locations
|
|
7370
7370
|
});
|
|
7371
|
-
duplicateLines +=
|
|
7371
|
+
duplicateLines += chunk2.split("\n").length * (locations.length - 1);
|
|
7372
7372
|
}
|
|
7373
7373
|
}
|
|
7374
7374
|
const percentage = totalLines > 0 ? duplicateLines / totalLines * 100 : 0;
|
|
@@ -15845,12 +15845,12 @@ var OpenAIProvider = class {
|
|
|
15845
15845
|
...reasoningEffort && { reasoning_effort: reasoningEffort }
|
|
15846
15846
|
});
|
|
15847
15847
|
let streamStopReason;
|
|
15848
|
-
for await (const
|
|
15849
|
-
const delta =
|
|
15848
|
+
for await (const chunk2 of stream) {
|
|
15849
|
+
const delta = chunk2.choices[0]?.delta;
|
|
15850
15850
|
if (delta?.content) {
|
|
15851
15851
|
yield { type: "text", text: delta.content };
|
|
15852
15852
|
}
|
|
15853
|
-
const finishReason =
|
|
15853
|
+
const finishReason = chunk2.choices[0]?.finish_reason;
|
|
15854
15854
|
if (finishReason) {
|
|
15855
15855
|
streamStopReason = this.mapFinishReason(finishReason);
|
|
15856
15856
|
}
|
|
@@ -15919,8 +15919,8 @@ var OpenAIProvider = class {
|
|
|
15919
15919
|
});
|
|
15920
15920
|
try {
|
|
15921
15921
|
let streamStopReason;
|
|
15922
|
-
for await (const
|
|
15923
|
-
const delta =
|
|
15922
|
+
for await (const chunk2 of stream) {
|
|
15923
|
+
const delta = chunk2.choices[0]?.delta;
|
|
15924
15924
|
if (delta?.content || delta?.tool_calls) {
|
|
15925
15925
|
lastActivityTime = Date.now();
|
|
15926
15926
|
}
|
|
@@ -15958,7 +15958,7 @@ var OpenAIProvider = class {
|
|
|
15958
15958
|
}
|
|
15959
15959
|
}
|
|
15960
15960
|
}
|
|
15961
|
-
const finishReason =
|
|
15961
|
+
const finishReason = chunk2.choices[0]?.finish_reason;
|
|
15962
15962
|
if (finishReason) {
|
|
15963
15963
|
streamStopReason = this.mapFinishReason(finishReason);
|
|
15964
15964
|
}
|
|
@@ -17674,12 +17674,12 @@ var GeminiProvider = class {
|
|
|
17674
17674
|
config: this.buildConfig(messages, options)
|
|
17675
17675
|
});
|
|
17676
17676
|
let streamStopReason = "end_turn";
|
|
17677
|
-
for await (const
|
|
17678
|
-
const text2 =
|
|
17677
|
+
for await (const chunk2 of stream) {
|
|
17678
|
+
const text2 = chunk2.text;
|
|
17679
17679
|
if (text2) {
|
|
17680
17680
|
yield { type: "text", text: text2 };
|
|
17681
17681
|
}
|
|
17682
|
-
const finishReason =
|
|
17682
|
+
const finishReason = chunk2.candidates?.[0]?.finishReason;
|
|
17683
17683
|
if (finishReason) {
|
|
17684
17684
|
streamStopReason = this.mapFinishReason(finishReason);
|
|
17685
17685
|
}
|
|
@@ -17700,12 +17700,12 @@ var GeminiProvider = class {
|
|
|
17700
17700
|
let streamStopReason = "end_turn";
|
|
17701
17701
|
let fallbackToolCounter = 0;
|
|
17702
17702
|
const emittedToolIds = /* @__PURE__ */ new Set();
|
|
17703
|
-
for await (const
|
|
17704
|
-
const text2 =
|
|
17703
|
+
for await (const chunk2 of stream) {
|
|
17704
|
+
const text2 = chunk2.text;
|
|
17705
17705
|
if (text2) {
|
|
17706
17706
|
yield { type: "text", text: text2 };
|
|
17707
17707
|
}
|
|
17708
|
-
const toolCalls = this.extractToolCalls(
|
|
17708
|
+
const toolCalls = this.extractToolCalls(chunk2, { includeLegacyFunctionCalls: true });
|
|
17709
17709
|
for (const toolCall of toolCalls) {
|
|
17710
17710
|
const toolCallId = toolCall.id ?? `gemini_call_${++fallbackToolCounter}`;
|
|
17711
17711
|
if (emittedToolIds.has(toolCallId)) continue;
|
|
@@ -17726,7 +17726,7 @@ var GeminiProvider = class {
|
|
|
17726
17726
|
toolCall: normalizedToolCall
|
|
17727
17727
|
};
|
|
17728
17728
|
}
|
|
17729
|
-
const finishReason =
|
|
17729
|
+
const finishReason = chunk2.candidates?.[0]?.finishReason;
|
|
17730
17730
|
if (toolCalls.length > 0) {
|
|
17731
17731
|
streamStopReason = "tool_use";
|
|
17732
17732
|
} else if (finishReason) {
|
|
@@ -18069,8 +18069,8 @@ var VertexProvider = class {
|
|
|
18069
18069
|
this.ensureInitialized();
|
|
18070
18070
|
const stream = await this.streamGenerateContent(messages, options);
|
|
18071
18071
|
let stopReason = "end_turn";
|
|
18072
|
-
for await (const
|
|
18073
|
-
const candidate =
|
|
18072
|
+
for await (const chunk2 of stream) {
|
|
18073
|
+
const candidate = chunk2.candidates?.[0];
|
|
18074
18074
|
const parts = candidate?.content?.parts ?? [];
|
|
18075
18075
|
for (const part of parts) {
|
|
18076
18076
|
if (part.text) {
|
|
@@ -18092,8 +18092,8 @@ var VertexProvider = class {
|
|
|
18092
18092
|
let stopReason = "end_turn";
|
|
18093
18093
|
let streamToolCallCounter = 0;
|
|
18094
18094
|
const emittedToolFingerprints = /* @__PURE__ */ new Set();
|
|
18095
|
-
for await (const
|
|
18096
|
-
const candidate =
|
|
18095
|
+
for await (const chunk2 of stream) {
|
|
18096
|
+
const candidate = chunk2.candidates?.[0];
|
|
18097
18097
|
const parts = candidate?.content?.parts ?? [];
|
|
18098
18098
|
for (const part of parts) {
|
|
18099
18099
|
if (part.text) {
|
|
@@ -18693,9 +18693,9 @@ var ResilientProvider = class {
|
|
|
18693
18693
|
}
|
|
18694
18694
|
let emittedChunk = false;
|
|
18695
18695
|
try {
|
|
18696
|
-
for await (const
|
|
18696
|
+
for await (const chunk2 of createStream()) {
|
|
18697
18697
|
emittedChunk = true;
|
|
18698
|
-
yield
|
|
18698
|
+
yield chunk2;
|
|
18699
18699
|
}
|
|
18700
18700
|
this.breaker.recordSuccess();
|
|
18701
18701
|
return;
|
|
@@ -19437,6 +19437,774 @@ z.string().regex(
|
|
|
19437
19437
|
|
|
19438
19438
|
// src/cli/repl/agents/manager.ts
|
|
19439
19439
|
init_logger();
|
|
19440
|
+
var LEGACY_ROLE_MAPPINGS = [
|
|
19441
|
+
{ legacy: "explore", role: "researcher", reason: "read-only codebase exploration" },
|
|
19442
|
+
{ legacy: "researcher", role: "researcher", reason: "legacy executor role" },
|
|
19443
|
+
{ legacy: "plan", role: "planner", reason: "task planning" },
|
|
19444
|
+
{ legacy: "planner", role: "planner", reason: "legacy executor role" },
|
|
19445
|
+
{ legacy: "architect", role: "architect", reason: "architecture design" },
|
|
19446
|
+
{ legacy: "editor", role: "editor", reason: "implementation edits" },
|
|
19447
|
+
{ legacy: "debug", role: "coder", reason: "debugging maps to coding capability" },
|
|
19448
|
+
{ legacy: "coder", role: "coder", reason: "legacy executor role" },
|
|
19449
|
+
{ legacy: "test", role: "tester", reason: "test authoring/execution" },
|
|
19450
|
+
{ legacy: "tester", role: "tester", reason: "legacy executor role" },
|
|
19451
|
+
{ legacy: "tdd", role: "tester", reason: "test-first implementation" },
|
|
19452
|
+
{ legacy: "e2e", role: "tester", reason: "end-to-end testing" },
|
|
19453
|
+
{ legacy: "review", role: "reviewer", reason: "code review" },
|
|
19454
|
+
{ legacy: "reviewer", role: "reviewer", reason: "legacy executor role" },
|
|
19455
|
+
{ legacy: "refactor", role: "optimizer", reason: "structure optimization" },
|
|
19456
|
+
{ legacy: "optimizer", role: "optimizer", reason: "legacy executor role" },
|
|
19457
|
+
{ legacy: "security", role: "security", reason: "security analysis" },
|
|
19458
|
+
{ legacy: "qa", role: "qa", reason: "quality assurance" },
|
|
19459
|
+
{ legacy: "integrator", role: "integrator", reason: "integration coordination" },
|
|
19460
|
+
{ legacy: "pm", role: "pm", reason: "product/project coordination" },
|
|
19461
|
+
{ legacy: "docs", role: "docs", reason: "documentation" },
|
|
19462
|
+
{ legacy: "database", role: "database", reason: "database work" }
|
|
19463
|
+
];
|
|
19464
|
+
var LEGACY_ROLE_MAP = new Map(LEGACY_ROLE_MAPPINGS.map((mapping) => [mapping.legacy, mapping]));
|
|
19465
|
+
function mapLegacyAgentRole(legacyRole, fallback = "coder") {
|
|
19466
|
+
return LEGACY_ROLE_MAP.get(legacyRole)?.role ?? fallback;
|
|
19467
|
+
}
|
|
19468
|
+
function listLegacyAgentRoleMappings() {
|
|
19469
|
+
return LEGACY_ROLE_MAPPINGS.map((mapping) => ({ ...mapping }));
|
|
19470
|
+
}
|
|
19471
|
+
function assertProvenance(provenance) {
|
|
19472
|
+
if (!provenance.workflowRunId) {
|
|
19473
|
+
throw new Error("Shared workspace writes require workflowRunId provenance.");
|
|
19474
|
+
}
|
|
19475
|
+
}
|
|
19476
|
+
function snapshotFromRecords(records, role) {
|
|
19477
|
+
const includeSensitive = role === void 0 || role === "security" || role === "integrator" || role === "pm";
|
|
19478
|
+
const facts = /* @__PURE__ */ new Map();
|
|
19479
|
+
const decisions = /* @__PURE__ */ new Map();
|
|
19480
|
+
const risks = /* @__PURE__ */ new Map();
|
|
19481
|
+
const files = /* @__PURE__ */ new Map();
|
|
19482
|
+
const testResults = /* @__PURE__ */ new Map();
|
|
19483
|
+
const artifacts = [];
|
|
19484
|
+
for (const record of records) {
|
|
19485
|
+
if (!includeSensitive && (record.kind === "risk" || record.provenance.risk === "secrets-sensitive")) {
|
|
19486
|
+
continue;
|
|
19487
|
+
}
|
|
19488
|
+
switch (record.kind) {
|
|
19489
|
+
case "fact":
|
|
19490
|
+
facts.set(record.key, record.value);
|
|
19491
|
+
break;
|
|
19492
|
+
case "decision":
|
|
19493
|
+
decisions.set(record.key, record.value);
|
|
19494
|
+
break;
|
|
19495
|
+
case "risk":
|
|
19496
|
+
risks.set(record.key, record.value);
|
|
19497
|
+
break;
|
|
19498
|
+
case "file":
|
|
19499
|
+
files.set(record.key, record.value);
|
|
19500
|
+
break;
|
|
19501
|
+
case "testResult":
|
|
19502
|
+
testResults.set(record.key, record.value);
|
|
19503
|
+
break;
|
|
19504
|
+
case "artifact":
|
|
19505
|
+
if (isAgentArtifact(record.value)) {
|
|
19506
|
+
if (includeSensitive || record.value.kind !== "riskReport") {
|
|
19507
|
+
artifacts.push(cloneArtifact(record.value));
|
|
19508
|
+
}
|
|
19509
|
+
}
|
|
19510
|
+
break;
|
|
19511
|
+
}
|
|
19512
|
+
}
|
|
19513
|
+
return {
|
|
19514
|
+
facts: Object.fromEntries(facts),
|
|
19515
|
+
decisions: Object.fromEntries(decisions),
|
|
19516
|
+
risks: Object.fromEntries(risks),
|
|
19517
|
+
files: Object.fromEntries(files),
|
|
19518
|
+
testResults: Object.fromEntries(testResults),
|
|
19519
|
+
artifacts
|
|
19520
|
+
};
|
|
19521
|
+
}
|
|
19522
|
+
var InMemorySharedWorkspaceStore = class {
|
|
19523
|
+
records = [];
|
|
19524
|
+
write(input) {
|
|
19525
|
+
assertProvenance(input.provenance);
|
|
19526
|
+
const record = {
|
|
19527
|
+
id: `state-${randomUUID()}`,
|
|
19528
|
+
kind: input.kind,
|
|
19529
|
+
key: input.key,
|
|
19530
|
+
value: cloneUnknown(input.value),
|
|
19531
|
+
provenance: { ...input.provenance },
|
|
19532
|
+
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
19533
|
+
};
|
|
19534
|
+
this.records.push(record);
|
|
19535
|
+
return cloneRecord(record);
|
|
19536
|
+
}
|
|
19537
|
+
list() {
|
|
19538
|
+
return this.records.map(cloneRecord);
|
|
19539
|
+
}
|
|
19540
|
+
snapshot() {
|
|
19541
|
+
return snapshotFromRecords(this.records);
|
|
19542
|
+
}
|
|
19543
|
+
readForRole(role) {
|
|
19544
|
+
return snapshotFromRecords(this.records, role);
|
|
19545
|
+
}
|
|
19546
|
+
clear() {
|
|
19547
|
+
this.records = [];
|
|
19548
|
+
}
|
|
19549
|
+
};
|
|
19550
|
+
var FileSharedWorkspaceStore = class {
|
|
19551
|
+
constructor(filePath) {
|
|
19552
|
+
this.filePath = filePath;
|
|
19553
|
+
try {
|
|
19554
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
19555
|
+
for (const record of this.readRecordsFromDisk()) {
|
|
19556
|
+
this.memory.write(record);
|
|
19557
|
+
}
|
|
19558
|
+
} catch {
|
|
19559
|
+
this.writable = false;
|
|
19560
|
+
}
|
|
19561
|
+
}
|
|
19562
|
+
filePath;
|
|
19563
|
+
memory = new InMemorySharedWorkspaceStore();
|
|
19564
|
+
writable = true;
|
|
19565
|
+
write(input) {
|
|
19566
|
+
const record = this.memory.write(input);
|
|
19567
|
+
if (this.writable) {
|
|
19568
|
+
try {
|
|
19569
|
+
writeFileSync(this.filePath, JSON.stringify(this.memory.list(), null, 2), "utf-8");
|
|
19570
|
+
} catch {
|
|
19571
|
+
this.writable = false;
|
|
19572
|
+
}
|
|
19573
|
+
}
|
|
19574
|
+
return record;
|
|
19575
|
+
}
|
|
19576
|
+
list() {
|
|
19577
|
+
return this.memory.list();
|
|
19578
|
+
}
|
|
19579
|
+
snapshot() {
|
|
19580
|
+
return this.memory.snapshot();
|
|
19581
|
+
}
|
|
19582
|
+
readForRole(role) {
|
|
19583
|
+
return this.memory.readForRole(role);
|
|
19584
|
+
}
|
|
19585
|
+
clear() {
|
|
19586
|
+
this.memory.clear();
|
|
19587
|
+
if (this.writable) {
|
|
19588
|
+
try {
|
|
19589
|
+
writeFileSync(this.filePath, "[]", "utf-8");
|
|
19590
|
+
} catch {
|
|
19591
|
+
this.writable = false;
|
|
19592
|
+
}
|
|
19593
|
+
}
|
|
19594
|
+
}
|
|
19595
|
+
readRecordsFromDisk() {
|
|
19596
|
+
try {
|
|
19597
|
+
const parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
19598
|
+
return Array.isArray(parsed) ? parsed.map((record) => ({
|
|
19599
|
+
kind: record.kind,
|
|
19600
|
+
key: record.key,
|
|
19601
|
+
value: record.value,
|
|
19602
|
+
provenance: record.provenance,
|
|
19603
|
+
createdAt: record.createdAt
|
|
19604
|
+
})) : [];
|
|
19605
|
+
} catch {
|
|
19606
|
+
return [];
|
|
19607
|
+
}
|
|
19608
|
+
}
|
|
19609
|
+
};
|
|
19610
|
+
var SharedWorkspaceState = class {
|
|
19611
|
+
workflowRunId = `legacy-state-${Date.now().toString(36)}`;
|
|
19612
|
+
store = new InMemorySharedWorkspaceStore();
|
|
19613
|
+
facts = /* @__PURE__ */ new Map();
|
|
19614
|
+
decisions = /* @__PURE__ */ new Map();
|
|
19615
|
+
risks = /* @__PURE__ */ new Map();
|
|
19616
|
+
files = /* @__PURE__ */ new Map();
|
|
19617
|
+
testResults = /* @__PURE__ */ new Map();
|
|
19618
|
+
artifacts = [];
|
|
19619
|
+
writeFact(key, value) {
|
|
19620
|
+
this.facts.set(key, value);
|
|
19621
|
+
this.store.write({
|
|
19622
|
+
kind: "fact",
|
|
19623
|
+
key,
|
|
19624
|
+
value,
|
|
19625
|
+
provenance: { workflowRunId: this.workflowRunId }
|
|
19626
|
+
});
|
|
19627
|
+
}
|
|
19628
|
+
recordDecision(key, value) {
|
|
19629
|
+
this.decisions.set(key, value);
|
|
19630
|
+
this.store.write({
|
|
19631
|
+
kind: "decision",
|
|
19632
|
+
key,
|
|
19633
|
+
value,
|
|
19634
|
+
provenance: { workflowRunId: this.workflowRunId }
|
|
19635
|
+
});
|
|
19636
|
+
}
|
|
19637
|
+
recordRisk(key, value) {
|
|
19638
|
+
this.risks.set(key, value);
|
|
19639
|
+
this.store.write({
|
|
19640
|
+
kind: "risk",
|
|
19641
|
+
key,
|
|
19642
|
+
value,
|
|
19643
|
+
provenance: { workflowRunId: this.workflowRunId, risk: "secrets-sensitive" }
|
|
19644
|
+
});
|
|
19645
|
+
}
|
|
19646
|
+
recordFile(path44, value) {
|
|
19647
|
+
this.files.set(path44, value);
|
|
19648
|
+
this.store.write({
|
|
19649
|
+
kind: "file",
|
|
19650
|
+
key: path44,
|
|
19651
|
+
value,
|
|
19652
|
+
provenance: { workflowRunId: this.workflowRunId }
|
|
19653
|
+
});
|
|
19654
|
+
}
|
|
19655
|
+
recordTestResult(key, value) {
|
|
19656
|
+
this.testResults.set(key, value);
|
|
19657
|
+
this.store.write({
|
|
19658
|
+
kind: "testResult",
|
|
19659
|
+
key,
|
|
19660
|
+
value,
|
|
19661
|
+
provenance: { workflowRunId: this.workflowRunId }
|
|
19662
|
+
});
|
|
19663
|
+
}
|
|
19664
|
+
addArtifact(artifact) {
|
|
19665
|
+
this.artifacts.push(cloneArtifact(artifact));
|
|
19666
|
+
this.store.write({
|
|
19667
|
+
kind: "artifact",
|
|
19668
|
+
key: artifact.id,
|
|
19669
|
+
value: artifact,
|
|
19670
|
+
provenance: {
|
|
19671
|
+
workflowRunId: this.workflowRunId,
|
|
19672
|
+
agentRunId: artifact.agentRunId,
|
|
19673
|
+
taskId: artifact.taskId
|
|
19674
|
+
}
|
|
19675
|
+
});
|
|
19676
|
+
}
|
|
19677
|
+
readForRole(role) {
|
|
19678
|
+
const includeSensitive = role === "security" || role === "integrator" || role === "pm";
|
|
19679
|
+
return {
|
|
19680
|
+
facts: Object.fromEntries(this.facts),
|
|
19681
|
+
decisions: Object.fromEntries(this.decisions),
|
|
19682
|
+
risks: includeSensitive ? Object.fromEntries(this.risks) : {},
|
|
19683
|
+
files: Object.fromEntries(this.files),
|
|
19684
|
+
testResults: Object.fromEntries(this.testResults),
|
|
19685
|
+
artifacts: this.artifacts.filter((artifact) => includeSensitive || artifact.kind !== "riskReport").map(cloneArtifact)
|
|
19686
|
+
};
|
|
19687
|
+
}
|
|
19688
|
+
snapshot() {
|
|
19689
|
+
return {
|
|
19690
|
+
facts: Object.fromEntries(this.facts),
|
|
19691
|
+
decisions: Object.fromEntries(this.decisions),
|
|
19692
|
+
risks: Object.fromEntries(this.risks),
|
|
19693
|
+
files: Object.fromEntries(this.files),
|
|
19694
|
+
testResults: Object.fromEntries(this.testResults),
|
|
19695
|
+
artifacts: this.artifacts.map(cloneArtifact)
|
|
19696
|
+
};
|
|
19697
|
+
}
|
|
19698
|
+
records() {
|
|
19699
|
+
return this.store.list();
|
|
19700
|
+
}
|
|
19701
|
+
};
|
|
19702
|
+
function evaluateAgentToolPolicy(input) {
|
|
19703
|
+
const manifestEntry = input.manifest?.[input.toolName];
|
|
19704
|
+
const risk = manifestEntry?.risk ?? input.capability.risk;
|
|
19705
|
+
if (!input.capability.allowedTools.includes(input.toolName)) {
|
|
19706
|
+
return {
|
|
19707
|
+
allowed: false,
|
|
19708
|
+
risk,
|
|
19709
|
+
reason: `Tool '${input.toolName}' is not allowed for agent role '${input.capability.role}'.`
|
|
19710
|
+
};
|
|
19711
|
+
}
|
|
19712
|
+
if (manifestEntry?.requiredCapability) {
|
|
19713
|
+
const allowedRoles = Array.isArray(manifestEntry.requiredCapability) ? manifestEntry.requiredCapability : [manifestEntry.requiredCapability];
|
|
19714
|
+
if (!allowedRoles.includes(input.capability.role)) {
|
|
19715
|
+
return {
|
|
19716
|
+
allowed: false,
|
|
19717
|
+
risk,
|
|
19718
|
+
reason: `Tool '${input.toolName}' requires role ${allowedRoles.join(", ")}.`
|
|
19719
|
+
};
|
|
19720
|
+
}
|
|
19721
|
+
}
|
|
19722
|
+
if (riskRank(risk) > riskRank(input.capability.risk)) {
|
|
19723
|
+
return {
|
|
19724
|
+
allowed: false,
|
|
19725
|
+
risk,
|
|
19726
|
+
reason: `Tool '${input.toolName}' risk '${risk}' exceeds agent capability risk '${input.capability.risk}'.`
|
|
19727
|
+
};
|
|
19728
|
+
}
|
|
19729
|
+
return {
|
|
19730
|
+
allowed: true,
|
|
19731
|
+
risk,
|
|
19732
|
+
requiresConsent: manifestEntry?.requiresConsent ?? (risk === "destructive" || risk === "secrets-sensitive")
|
|
19733
|
+
};
|
|
19734
|
+
}
|
|
19735
|
+
function createAgentTraceContext(input = {}) {
|
|
19736
|
+
return {
|
|
19737
|
+
traceId: input.traceId ?? `trace-${randomUUID()}`,
|
|
19738
|
+
spanId: input.spanId ?? `span-${randomUUID()}`,
|
|
19739
|
+
parentSpanId: input.parentSpanId,
|
|
19740
|
+
workflowRunId: input.workflowRunId,
|
|
19741
|
+
agentRunId: input.agentRunId,
|
|
19742
|
+
taskId: input.taskId,
|
|
19743
|
+
toolCallId: input.toolCallId
|
|
19744
|
+
};
|
|
19745
|
+
}
|
|
19746
|
+
var AgentGraphEngine = class {
|
|
19747
|
+
eventLog;
|
|
19748
|
+
sharedState;
|
|
19749
|
+
nodeExecutor;
|
|
19750
|
+
gateEvaluator;
|
|
19751
|
+
trace;
|
|
19752
|
+
constructor(options = {}) {
|
|
19753
|
+
this.eventLog = options.eventLog;
|
|
19754
|
+
this.sharedState = options.sharedState ?? new InMemorySharedWorkspaceStore();
|
|
19755
|
+
this.nodeExecutor = options.nodeExecutor ?? defaultAgentGraphNodeExecutor;
|
|
19756
|
+
this.gateEvaluator = options.gateEvaluator ?? defaultAgentGateEvaluator;
|
|
19757
|
+
this.trace = options.trace ?? createAgentTraceContext();
|
|
19758
|
+
}
|
|
19759
|
+
async run(input) {
|
|
19760
|
+
const validation = validateAgentGraph(input.graph);
|
|
19761
|
+
if (!validation.valid) {
|
|
19762
|
+
throw new Error(
|
|
19763
|
+
`Invalid agent graph: ${validation.issues.map((issue) => issue.message).join("; ")}`
|
|
19764
|
+
);
|
|
19765
|
+
}
|
|
19766
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19767
|
+
const nodeResults = /* @__PURE__ */ new Map();
|
|
19768
|
+
const artifacts = [];
|
|
19769
|
+
const graphTrace = createAgentTraceContext({
|
|
19770
|
+
...this.trace,
|
|
19771
|
+
workflowRunId: input.workflowRunId
|
|
19772
|
+
});
|
|
19773
|
+
this.eventLog?.record("agent.graph.started", {
|
|
19774
|
+
workflowRunId: input.workflowRunId,
|
|
19775
|
+
trace: graphTrace,
|
|
19776
|
+
levels: validation.levels
|
|
19777
|
+
});
|
|
19778
|
+
try {
|
|
19779
|
+
for (const level of validation.levels) {
|
|
19780
|
+
const batches = chunk(level, input.graph.parallelism ?? level.length);
|
|
19781
|
+
for (const batch of batches) {
|
|
19782
|
+
const levelResults = await Promise.all(
|
|
19783
|
+
batch.map(
|
|
19784
|
+
(nodeId) => this.executeNode({
|
|
19785
|
+
node: input.graph.nodes.find((candidate) => candidate.id === nodeId),
|
|
19786
|
+
graph: input.graph,
|
|
19787
|
+
workflowRunId: input.workflowRunId,
|
|
19788
|
+
input: input.input,
|
|
19789
|
+
graphTrace,
|
|
19790
|
+
nodeResults
|
|
19791
|
+
})
|
|
19792
|
+
)
|
|
19793
|
+
);
|
|
19794
|
+
for (const result2 of levelResults) {
|
|
19795
|
+
nodeResults.set(result2.taskId, result2);
|
|
19796
|
+
artifacts.push(...result2.artifacts.map(cloneArtifact));
|
|
19797
|
+
}
|
|
19798
|
+
}
|
|
19799
|
+
}
|
|
19800
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19801
|
+
const result = {
|
|
19802
|
+
id: input.workflowRunId,
|
|
19803
|
+
status: "completed",
|
|
19804
|
+
nodeResults: Object.fromEntries(nodeResults),
|
|
19805
|
+
artifacts,
|
|
19806
|
+
stateSnapshot: this.sharedState.snapshot(),
|
|
19807
|
+
trace: graphTrace,
|
|
19808
|
+
startedAt,
|
|
19809
|
+
completedAt
|
|
19810
|
+
};
|
|
19811
|
+
this.eventLog?.record("agent.graph.completed", {
|
|
19812
|
+
workflowRunId: input.workflowRunId,
|
|
19813
|
+
trace: graphTrace,
|
|
19814
|
+
nodeCount: nodeResults.size
|
|
19815
|
+
});
|
|
19816
|
+
return result;
|
|
19817
|
+
} catch (error) {
|
|
19818
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19819
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
19820
|
+
this.eventLog?.record("agent.graph.failed", {
|
|
19821
|
+
workflowRunId: input.workflowRunId,
|
|
19822
|
+
trace: graphTrace,
|
|
19823
|
+
error: message
|
|
19824
|
+
});
|
|
19825
|
+
return {
|
|
19826
|
+
id: input.workflowRunId,
|
|
19827
|
+
status: "failed",
|
|
19828
|
+
nodeResults: Object.fromEntries(nodeResults),
|
|
19829
|
+
artifacts,
|
|
19830
|
+
stateSnapshot: this.sharedState.snapshot(),
|
|
19831
|
+
trace: graphTrace,
|
|
19832
|
+
startedAt,
|
|
19833
|
+
completedAt,
|
|
19834
|
+
error: message
|
|
19835
|
+
};
|
|
19836
|
+
}
|
|
19837
|
+
}
|
|
19838
|
+
async executeNode(input) {
|
|
19839
|
+
const attempts = input.node.retryPolicy?.maxAttempts ?? 1;
|
|
19840
|
+
let lastResult;
|
|
19841
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
19842
|
+
const task = graphNodeToTask(input.node, input.input);
|
|
19843
|
+
const trace = createAgentTraceContext({
|
|
19844
|
+
traceId: input.graphTrace.traceId,
|
|
19845
|
+
parentSpanId: input.graphTrace.spanId,
|
|
19846
|
+
workflowRunId: input.workflowRunId,
|
|
19847
|
+
taskId: task.id
|
|
19848
|
+
});
|
|
19849
|
+
this.eventLog?.record("agent.started", {
|
|
19850
|
+
workflowRunId: input.workflowRunId,
|
|
19851
|
+
nodeId: input.node.id,
|
|
19852
|
+
taskId: task.id,
|
|
19853
|
+
role: task.role,
|
|
19854
|
+
attempt,
|
|
19855
|
+
trace
|
|
19856
|
+
});
|
|
19857
|
+
const result = await this.nodeExecutor({
|
|
19858
|
+
node: input.node,
|
|
19859
|
+
task,
|
|
19860
|
+
attempt,
|
|
19861
|
+
workflowRunId: input.workflowRunId,
|
|
19862
|
+
trace,
|
|
19863
|
+
dependencyResults: input.nodeResults,
|
|
19864
|
+
sharedState: this.sharedState,
|
|
19865
|
+
eventLog: this.eventLog ?? NULL_EVENT_LOG
|
|
19866
|
+
});
|
|
19867
|
+
lastResult = result;
|
|
19868
|
+
for (const artifact of result.artifacts) {
|
|
19869
|
+
this.sharedState.write({
|
|
19870
|
+
kind: "artifact",
|
|
19871
|
+
key: artifact.id,
|
|
19872
|
+
value: artifact,
|
|
19873
|
+
provenance: {
|
|
19874
|
+
workflowRunId: input.workflowRunId,
|
|
19875
|
+
agentRunId: result.id,
|
|
19876
|
+
nodeId: input.node.id,
|
|
19877
|
+
taskId: task.id,
|
|
19878
|
+
risk: input.node.risk
|
|
19879
|
+
}
|
|
19880
|
+
});
|
|
19881
|
+
this.eventLog?.record("agent.artifact.created", {
|
|
19882
|
+
workflowRunId: input.workflowRunId,
|
|
19883
|
+
nodeId: input.node.id,
|
|
19884
|
+
agentRunId: result.id,
|
|
19885
|
+
artifactId: artifact.id,
|
|
19886
|
+
kind: artifact.kind,
|
|
19887
|
+
trace
|
|
19888
|
+
});
|
|
19889
|
+
}
|
|
19890
|
+
if (result.success) {
|
|
19891
|
+
await this.evaluateNodeGates(input.graph, input.node, result, input.workflowRunId, trace);
|
|
19892
|
+
this.eventLog?.record("agent.completed", {
|
|
19893
|
+
workflowRunId: input.workflowRunId,
|
|
19894
|
+
nodeId: input.node.id,
|
|
19895
|
+
agentRunId: result.id,
|
|
19896
|
+
taskId: task.id,
|
|
19897
|
+
role: result.role,
|
|
19898
|
+
attempt,
|
|
19899
|
+
trace
|
|
19900
|
+
});
|
|
19901
|
+
return result;
|
|
19902
|
+
}
|
|
19903
|
+
this.eventLog?.record("agent.failed", {
|
|
19904
|
+
workflowRunId: input.workflowRunId,
|
|
19905
|
+
nodeId: input.node.id,
|
|
19906
|
+
agentRunId: result.id,
|
|
19907
|
+
taskId: task.id,
|
|
19908
|
+
role: result.role,
|
|
19909
|
+
attempt,
|
|
19910
|
+
error: result.error,
|
|
19911
|
+
trace
|
|
19912
|
+
});
|
|
19913
|
+
if (attempt < attempts && input.node.retryPolicy?.backoffMs) {
|
|
19914
|
+
await new Promise((resolve3) => setTimeout(resolve3, input.node.retryPolicy.backoffMs));
|
|
19915
|
+
}
|
|
19916
|
+
}
|
|
19917
|
+
throw new Error(
|
|
19918
|
+
`Node '${input.node.id}' failed after ${attempts} attempt(s): ${lastResult?.error ?? "unknown error"}`
|
|
19919
|
+
);
|
|
19920
|
+
}
|
|
19921
|
+
async evaluateNodeGates(graph, node, result, workflowRunId, trace) {
|
|
19922
|
+
for (const gateId of node.gates ?? []) {
|
|
19923
|
+
const gate = graph.gates?.find((candidate) => candidate.id === gateId);
|
|
19924
|
+
if (!gate) continue;
|
|
19925
|
+
const evaluation = await this.gateEvaluator({
|
|
19926
|
+
gate,
|
|
19927
|
+
node,
|
|
19928
|
+
result,
|
|
19929
|
+
workflowRunId,
|
|
19930
|
+
trace,
|
|
19931
|
+
sharedState: this.sharedState,
|
|
19932
|
+
eventLog: this.eventLog ?? NULL_EVENT_LOG
|
|
19933
|
+
});
|
|
19934
|
+
const eventType = evaluation.passed ? "workflow.gate.passed" : "workflow.gate.failed";
|
|
19935
|
+
this.eventLog?.record(eventType, {
|
|
19936
|
+
workflowRunId,
|
|
19937
|
+
nodeId: node.id,
|
|
19938
|
+
gateId: gate.id,
|
|
19939
|
+
kind: gate.kind,
|
|
19940
|
+
required: gate.required,
|
|
19941
|
+
reason: evaluation.reason,
|
|
19942
|
+
trace
|
|
19943
|
+
});
|
|
19944
|
+
if (!evaluation.passed && gate.required) {
|
|
19945
|
+
throw new Error(
|
|
19946
|
+
`Required gate '${gate.id}' failed for node '${node.id}': ${evaluation.reason ?? "no reason"}`
|
|
19947
|
+
);
|
|
19948
|
+
}
|
|
19949
|
+
}
|
|
19950
|
+
}
|
|
19951
|
+
};
|
|
19952
|
+
function createAgentGraphEngine(options) {
|
|
19953
|
+
return new AgentGraphEngine(options);
|
|
19954
|
+
}
|
|
19955
|
+
function createAgentArtifact(input) {
|
|
19956
|
+
return {
|
|
19957
|
+
...input,
|
|
19958
|
+
id: input.id ?? `artifact-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
|
|
19959
|
+
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
19960
|
+
};
|
|
19961
|
+
}
|
|
19962
|
+
function createSummaryArtifact(output, metadata = {}) {
|
|
19963
|
+
return createAgentArtifact({
|
|
19964
|
+
kind: "summary",
|
|
19965
|
+
content: output,
|
|
19966
|
+
title: metadata.title ?? "Agent summary",
|
|
19967
|
+
agentRunId: metadata.agentRunId,
|
|
19968
|
+
taskId: metadata.taskId
|
|
19969
|
+
});
|
|
19970
|
+
}
|
|
19971
|
+
function normalizeAgentRunResult(input) {
|
|
19972
|
+
const completedAt = input.completedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
19973
|
+
const startedAt = input.startedAt ?? completedAt;
|
|
19974
|
+
const status = input.status ?? (input.success ? "completed" : "failed");
|
|
19975
|
+
const artifacts = input.artifacts && input.artifacts.length > 0 ? input.artifacts.map(cloneArtifact) : [createSummaryArtifact(input.output, { agentRunId: input.id, taskId: input.taskId })];
|
|
19976
|
+
return {
|
|
19977
|
+
id: input.id,
|
|
19978
|
+
taskId: input.taskId,
|
|
19979
|
+
role: input.role,
|
|
19980
|
+
status,
|
|
19981
|
+
success: input.success,
|
|
19982
|
+
output: input.output,
|
|
19983
|
+
artifacts,
|
|
19984
|
+
toolsUsed: [...input.toolsUsed ?? []],
|
|
19985
|
+
turns: input.turns ?? 0,
|
|
19986
|
+
durationMs: input.durationMs ?? 0,
|
|
19987
|
+
usage: input.usage,
|
|
19988
|
+
error: input.error,
|
|
19989
|
+
startedAt,
|
|
19990
|
+
completedAt,
|
|
19991
|
+
metadata: input.metadata
|
|
19992
|
+
};
|
|
19993
|
+
}
|
|
19994
|
+
function validateAgentCapabilities(capability, requiredTools = []) {
|
|
19995
|
+
const allowed = new Set(capability.allowedTools);
|
|
19996
|
+
return requiredTools.filter((tool) => !allowed.has(tool)).map((tool) => ({
|
|
19997
|
+
code: "missing-dependency",
|
|
19998
|
+
message: `Tool '${tool}' is not allowed for agent role '${capability.role}'.`
|
|
19999
|
+
}));
|
|
20000
|
+
}
|
|
20001
|
+
function validateAgentGraph(graph) {
|
|
20002
|
+
const issues = [];
|
|
20003
|
+
const nodeIds = /* @__PURE__ */ new Set();
|
|
20004
|
+
const gateIds = new Set((graph.gates ?? []).map((gate) => gate.id));
|
|
20005
|
+
if (graph.parallelism !== void 0 && graph.parallelism < 1) {
|
|
20006
|
+
issues.push({
|
|
20007
|
+
code: "invalid-parallelism",
|
|
20008
|
+
message: "Graph parallelism must be greater than zero."
|
|
20009
|
+
});
|
|
20010
|
+
}
|
|
20011
|
+
for (const node of graph.nodes) {
|
|
20012
|
+
if (nodeIds.has(node.id)) {
|
|
20013
|
+
issues.push({
|
|
20014
|
+
code: "duplicate-node",
|
|
20015
|
+
message: `Duplicate graph node '${node.id}'.`,
|
|
20016
|
+
nodeId: node.id
|
|
20017
|
+
});
|
|
20018
|
+
}
|
|
20019
|
+
nodeIds.add(node.id);
|
|
20020
|
+
if (node.retryPolicy && node.retryPolicy.maxAttempts < 1) {
|
|
20021
|
+
issues.push({
|
|
20022
|
+
code: "invalid-retry-policy",
|
|
20023
|
+
message: `Node '${node.id}' retry policy must allow at least one attempt.`,
|
|
20024
|
+
nodeId: node.id
|
|
20025
|
+
});
|
|
20026
|
+
}
|
|
20027
|
+
for (const dep of node.dependsOn ?? []) {
|
|
20028
|
+
if (!nodeIds.has(dep) && !graph.nodes.some((candidate) => candidate.id === dep)) {
|
|
20029
|
+
issues.push({
|
|
20030
|
+
code: "missing-dependency",
|
|
20031
|
+
message: `Node '${node.id}' depends on missing node '${dep}'.`,
|
|
20032
|
+
nodeId: node.id
|
|
20033
|
+
});
|
|
20034
|
+
}
|
|
20035
|
+
}
|
|
20036
|
+
for (const gate of node.gates ?? []) {
|
|
20037
|
+
if (!gateIds.has(gate)) {
|
|
20038
|
+
issues.push({
|
|
20039
|
+
code: "missing-gate",
|
|
20040
|
+
message: `Node '${node.id}' references missing gate '${gate}'.`,
|
|
20041
|
+
nodeId: node.id,
|
|
20042
|
+
gateId: gate
|
|
20043
|
+
});
|
|
20044
|
+
}
|
|
20045
|
+
}
|
|
20046
|
+
}
|
|
20047
|
+
for (const edge of graph.edges ?? []) {
|
|
20048
|
+
if (!nodeIds.has(edge.from)) {
|
|
20049
|
+
issues.push({
|
|
20050
|
+
code: "missing-edge-node",
|
|
20051
|
+
message: `Graph edge references missing source node '${edge.from}'.`,
|
|
20052
|
+
nodeId: edge.from
|
|
20053
|
+
});
|
|
20054
|
+
}
|
|
20055
|
+
if (!nodeIds.has(edge.to)) {
|
|
20056
|
+
issues.push({
|
|
20057
|
+
code: "missing-edge-node",
|
|
20058
|
+
message: `Graph edge references missing target node '${edge.to}'.`,
|
|
20059
|
+
nodeId: edge.to
|
|
20060
|
+
});
|
|
20061
|
+
}
|
|
20062
|
+
}
|
|
20063
|
+
const levels = buildExecutionLevels(graph, issues);
|
|
20064
|
+
return { valid: issues.length === 0, issues, levels };
|
|
20065
|
+
}
|
|
20066
|
+
function buildExecutionLevels(graph, issues) {
|
|
20067
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
20068
|
+
for (const node of graph.nodes) {
|
|
20069
|
+
dependencies.set(node.id, new Set(node.dependsOn ?? []));
|
|
20070
|
+
}
|
|
20071
|
+
for (const edge of graph.edges ?? []) {
|
|
20072
|
+
if (dependencies.has(edge.to)) {
|
|
20073
|
+
dependencies.get(edge.to).add(edge.from);
|
|
20074
|
+
}
|
|
20075
|
+
}
|
|
20076
|
+
const completed = /* @__PURE__ */ new Set();
|
|
20077
|
+
const levels = [];
|
|
20078
|
+
while (completed.size < dependencies.size) {
|
|
20079
|
+
const level = [...dependencies.entries()].filter(([id, deps]) => !completed.has(id) && [...deps].every((dep) => completed.has(dep))).map(([id]) => id);
|
|
20080
|
+
if (level.length === 0) {
|
|
20081
|
+
const remaining = [...dependencies.keys()].filter((id) => !completed.has(id));
|
|
20082
|
+
issues.push({
|
|
20083
|
+
code: "cycle",
|
|
20084
|
+
message: `Graph contains a cycle involving: ${remaining.join(", ")}.`
|
|
20085
|
+
});
|
|
20086
|
+
return levels;
|
|
20087
|
+
}
|
|
20088
|
+
for (const id of level) completed.add(id);
|
|
20089
|
+
levels.push(level);
|
|
20090
|
+
}
|
|
20091
|
+
return levels;
|
|
20092
|
+
}
|
|
20093
|
+
var NULL_EVENT_LOG = {
|
|
20094
|
+
record(type, data = {}) {
|
|
20095
|
+
return {
|
|
20096
|
+
id: `event-${randomUUID()}`,
|
|
20097
|
+
type,
|
|
20098
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20099
|
+
data
|
|
20100
|
+
};
|
|
20101
|
+
},
|
|
20102
|
+
list() {
|
|
20103
|
+
return [];
|
|
20104
|
+
},
|
|
20105
|
+
count() {
|
|
20106
|
+
return 0;
|
|
20107
|
+
},
|
|
20108
|
+
clear() {
|
|
20109
|
+
}
|
|
20110
|
+
};
|
|
20111
|
+
function graphNodeToTask(node, workflowInput) {
|
|
20112
|
+
return {
|
|
20113
|
+
id: node.id,
|
|
20114
|
+
role: node.agentRole ?? "coder",
|
|
20115
|
+
objective: node.description,
|
|
20116
|
+
context: {
|
|
20117
|
+
workflowInput,
|
|
20118
|
+
condition: node.condition
|
|
20119
|
+
},
|
|
20120
|
+
dependencies: node.dependsOn,
|
|
20121
|
+
constraints: node.requiredTools?.map((tool) => `Requires tool: ${tool}`)
|
|
20122
|
+
};
|
|
20123
|
+
}
|
|
20124
|
+
async function defaultAgentGraphNodeExecutor(execution) {
|
|
20125
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20126
|
+
const dependencyOutputs = Object.fromEntries(
|
|
20127
|
+
[...execution.dependencyResults.entries()].map(([id, result]) => [
|
|
20128
|
+
id,
|
|
20129
|
+
{ success: result.success, output: result.output }
|
|
20130
|
+
])
|
|
20131
|
+
);
|
|
20132
|
+
const output = [
|
|
20133
|
+
`Node '${execution.node.id}' executed by ${execution.task.role}.`,
|
|
20134
|
+
`Objective: ${execution.task.objective}`,
|
|
20135
|
+
Object.keys(dependencyOutputs).length > 0 ? `Dependencies: ${JSON.stringify(dependencyOutputs)}` : "Dependencies: none"
|
|
20136
|
+
].join("\n");
|
|
20137
|
+
return normalizeAgentRunResult({
|
|
20138
|
+
id: `${execution.workflowRunId}-${execution.node.id}-attempt-${execution.attempt}`,
|
|
20139
|
+
taskId: execution.task.id,
|
|
20140
|
+
role: execution.task.role,
|
|
20141
|
+
success: true,
|
|
20142
|
+
output,
|
|
20143
|
+
startedAt,
|
|
20144
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20145
|
+
turns: 0,
|
|
20146
|
+
toolsUsed: [],
|
|
20147
|
+
durationMs: 0,
|
|
20148
|
+
metadata: {
|
|
20149
|
+
workflowRunId: execution.workflowRunId,
|
|
20150
|
+
nodeId: execution.node.id,
|
|
20151
|
+
trace: execution.trace,
|
|
20152
|
+
simulated: true
|
|
20153
|
+
}
|
|
20154
|
+
});
|
|
20155
|
+
}
|
|
20156
|
+
async function defaultAgentGateEvaluator(input) {
|
|
20157
|
+
if (!input.result.success) {
|
|
20158
|
+
return { passed: false, reason: "Agent result was not successful." };
|
|
20159
|
+
}
|
|
20160
|
+
return { passed: true };
|
|
20161
|
+
}
|
|
20162
|
+
function chunk(items, size) {
|
|
20163
|
+
const safeSize = Math.max(1, size);
|
|
20164
|
+
const result = [];
|
|
20165
|
+
for (let index = 0; index < items.length; index += safeSize) {
|
|
20166
|
+
result.push(items.slice(index, index + safeSize));
|
|
20167
|
+
}
|
|
20168
|
+
return result;
|
|
20169
|
+
}
|
|
20170
|
+
function riskRank(risk) {
|
|
20171
|
+
switch (risk) {
|
|
20172
|
+
case "read-only":
|
|
20173
|
+
return 0;
|
|
20174
|
+
case "network":
|
|
20175
|
+
return 1;
|
|
20176
|
+
case "write":
|
|
20177
|
+
return 2;
|
|
20178
|
+
case "destructive":
|
|
20179
|
+
return 3;
|
|
20180
|
+
case "secrets-sensitive":
|
|
20181
|
+
return 4;
|
|
20182
|
+
}
|
|
20183
|
+
}
|
|
20184
|
+
function cloneUnknown(value) {
|
|
20185
|
+
if (value === void 0 || value === null) return value;
|
|
20186
|
+
try {
|
|
20187
|
+
return JSON.parse(JSON.stringify(value));
|
|
20188
|
+
} catch {
|
|
20189
|
+
return value;
|
|
20190
|
+
}
|
|
20191
|
+
}
|
|
20192
|
+
function cloneRecord(record) {
|
|
20193
|
+
return {
|
|
20194
|
+
...record,
|
|
20195
|
+
value: cloneUnknown(record.value),
|
|
20196
|
+
provenance: { ...record.provenance }
|
|
20197
|
+
};
|
|
20198
|
+
}
|
|
20199
|
+
function isAgentArtifact(value) {
|
|
20200
|
+
return typeof value === "object" && value !== null && "id" in value && "kind" in value && "content" in value && "createdAt" in value;
|
|
20201
|
+
}
|
|
20202
|
+
function cloneArtifact(artifact) {
|
|
20203
|
+
return {
|
|
20204
|
+
...artifact,
|
|
20205
|
+
metadata: artifact.metadata ? { ...artifact.metadata } : void 0
|
|
20206
|
+
};
|
|
20207
|
+
}
|
|
19440
20208
|
|
|
19441
20209
|
// src/cli/repl/agents/prompts.ts
|
|
19442
20210
|
var EXPLORE_PROMPT = `You are an exploration agent for Corbat-Coco.
|
|
@@ -20018,11 +20786,15 @@ var AgentManager = class extends EventEmitter {
|
|
|
20018
20786
|
failedAgent.status = "failed";
|
|
20019
20787
|
failedAgent.error = error;
|
|
20020
20788
|
failedAgent.completedAt = /* @__PURE__ */ new Date();
|
|
20021
|
-
return {
|
|
20789
|
+
return this.buildResult({
|
|
20022
20790
|
agent: failedAgent,
|
|
20023
20791
|
success: false,
|
|
20024
|
-
output: error
|
|
20025
|
-
|
|
20792
|
+
output: error,
|
|
20793
|
+
turns: 0,
|
|
20794
|
+
toolsUsed: [],
|
|
20795
|
+
startedAt: failedAgent.createdAt.toISOString(),
|
|
20796
|
+
usage: { inputTokens: 0, outputTokens: 0 }
|
|
20797
|
+
});
|
|
20026
20798
|
}
|
|
20027
20799
|
const agent = this.createAgent(type, task);
|
|
20028
20800
|
this.activeAgents.set(agent.id, agent);
|
|
@@ -20074,11 +20846,15 @@ var AgentManager = class extends EventEmitter {
|
|
|
20074
20846
|
options.onStatusChange?.(agent);
|
|
20075
20847
|
this.logger.error(`Agent ${agent.id} failed unexpectedly`, { error: errorMessage });
|
|
20076
20848
|
this.emitEvent("fail", agent);
|
|
20077
|
-
return {
|
|
20849
|
+
return this.buildResult({
|
|
20078
20850
|
agent,
|
|
20079
20851
|
success: false,
|
|
20080
|
-
output: errorMessage
|
|
20081
|
-
|
|
20852
|
+
output: errorMessage,
|
|
20853
|
+
turns: 0,
|
|
20854
|
+
toolsUsed: [],
|
|
20855
|
+
startedAt: agent.createdAt.toISOString(),
|
|
20856
|
+
usage: { inputTokens: 0, outputTokens: 0 }
|
|
20857
|
+
});
|
|
20082
20858
|
}
|
|
20083
20859
|
}
|
|
20084
20860
|
/**
|
|
@@ -20199,6 +20975,8 @@ var AgentManager = class extends EventEmitter {
|
|
|
20199
20975
|
let finalOutput = "";
|
|
20200
20976
|
let iteration = 0;
|
|
20201
20977
|
const maxTurns = config.maxTurns ?? 10;
|
|
20978
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20979
|
+
const toolsUsed = /* @__PURE__ */ new Set();
|
|
20202
20980
|
while (iteration < maxTurns) {
|
|
20203
20981
|
iteration++;
|
|
20204
20982
|
if (options.signal?.aborted) {
|
|
@@ -20207,12 +20985,15 @@ var AgentManager = class extends EventEmitter {
|
|
|
20207
20985
|
agent.completedAt = /* @__PURE__ */ new Date();
|
|
20208
20986
|
this.moveToCompleted(agent.id);
|
|
20209
20987
|
options.onStatusChange?.(agent);
|
|
20210
|
-
return {
|
|
20988
|
+
return this.buildResult({
|
|
20211
20989
|
agent,
|
|
20212
20990
|
success: false,
|
|
20213
20991
|
output: "Agent execution was aborted",
|
|
20992
|
+
turns: iteration,
|
|
20993
|
+
toolsUsed: Array.from(toolsUsed),
|
|
20994
|
+
startedAt,
|
|
20214
20995
|
usage: { inputTokens: totalInputTokens, outputTokens: totalOutputTokens }
|
|
20215
|
-
};
|
|
20996
|
+
});
|
|
20216
20997
|
}
|
|
20217
20998
|
const response = await this.provider.chatWithTools(messages, {
|
|
20218
20999
|
system: config.systemPrompt,
|
|
@@ -20229,7 +21010,7 @@ var AgentManager = class extends EventEmitter {
|
|
|
20229
21010
|
messages.push({ role: "assistant", content: response.content });
|
|
20230
21011
|
break;
|
|
20231
21012
|
}
|
|
20232
|
-
const toolResults = await this.executeToolCalls(response.toolCalls, config);
|
|
21013
|
+
const toolResults = await this.executeToolCalls(response.toolCalls, config, toolsUsed);
|
|
20233
21014
|
const toolUses = response.toolCalls.map((tc) => ({
|
|
20234
21015
|
type: "tool_use",
|
|
20235
21016
|
id: tc.id,
|
|
@@ -20253,12 +21034,15 @@ var AgentManager = class extends EventEmitter {
|
|
|
20253
21034
|
iterations: iteration,
|
|
20254
21035
|
outputLength: finalOutput.length
|
|
20255
21036
|
});
|
|
20256
|
-
return {
|
|
21037
|
+
return this.buildResult({
|
|
20257
21038
|
agent,
|
|
20258
21039
|
success: true,
|
|
20259
21040
|
output: finalOutput,
|
|
21041
|
+
turns: iteration,
|
|
21042
|
+
toolsUsed: Array.from(toolsUsed),
|
|
21043
|
+
startedAt,
|
|
20260
21044
|
usage: { inputTokens: totalInputTokens, outputTokens: totalOutputTokens }
|
|
20261
|
-
};
|
|
21045
|
+
});
|
|
20262
21046
|
}
|
|
20263
21047
|
/**
|
|
20264
21048
|
* Get tool definitions filtered for the agent's allowed tools
|
|
@@ -20271,10 +21055,11 @@ var AgentManager = class extends EventEmitter {
|
|
|
20271
21055
|
/**
|
|
20272
21056
|
* Execute tool calls and return results
|
|
20273
21057
|
*/
|
|
20274
|
-
async executeToolCalls(toolCalls, config) {
|
|
21058
|
+
async executeToolCalls(toolCalls, config, toolsUsed) {
|
|
20275
21059
|
const results = [];
|
|
20276
21060
|
const allowedTools = new Set(config.tools);
|
|
20277
21061
|
for (const toolCall of toolCalls) {
|
|
21062
|
+
toolsUsed.add(toolCall.name);
|
|
20278
21063
|
if (!allowedTools.has(toolCall.name)) {
|
|
20279
21064
|
results.push({
|
|
20280
21065
|
type: "tool_result",
|
|
@@ -20315,6 +21100,33 @@ var AgentManager = class extends EventEmitter {
|
|
|
20315
21100
|
this.abortControllers.delete(agentId);
|
|
20316
21101
|
}
|
|
20317
21102
|
}
|
|
21103
|
+
buildResult(input) {
|
|
21104
|
+
const structuredResult = normalizeAgentRunResult({
|
|
21105
|
+
id: `${input.agent.id}-run`,
|
|
21106
|
+
taskId: input.agent.id,
|
|
21107
|
+
role: agentTypeToRuntimeRole(input.agent.type),
|
|
21108
|
+
success: input.success,
|
|
21109
|
+
output: input.output,
|
|
21110
|
+
turns: input.turns,
|
|
21111
|
+
toolsUsed: input.toolsUsed,
|
|
21112
|
+
usage: input.usage,
|
|
21113
|
+
startedAt: input.startedAt,
|
|
21114
|
+
durationMs: input.agent.completedAt ? input.agent.completedAt.getTime() - input.agent.createdAt.getTime() : 0,
|
|
21115
|
+
status: input.success ? "completed" : "failed",
|
|
21116
|
+
error: input.success ? void 0 : input.agent.error,
|
|
21117
|
+
metadata: { agentType: input.agent.type }
|
|
21118
|
+
});
|
|
21119
|
+
return {
|
|
21120
|
+
agent: input.agent,
|
|
21121
|
+
success: input.success,
|
|
21122
|
+
output: input.output,
|
|
21123
|
+
artifacts: structuredResult.artifacts,
|
|
21124
|
+
structuredResult,
|
|
21125
|
+
toolsUsed: input.toolsUsed,
|
|
21126
|
+
turns: input.turns,
|
|
21127
|
+
usage: input.usage
|
|
21128
|
+
};
|
|
21129
|
+
}
|
|
20318
21130
|
/**
|
|
20319
21131
|
* Emit an agent event
|
|
20320
21132
|
*/
|
|
@@ -20324,6 +21136,9 @@ var AgentManager = class extends EventEmitter {
|
|
|
20324
21136
|
this.emit("agent", event);
|
|
20325
21137
|
}
|
|
20326
21138
|
};
|
|
21139
|
+
function agentTypeToRuntimeRole(type) {
|
|
21140
|
+
return mapLegacyAgentRole(type);
|
|
21141
|
+
}
|
|
20327
21142
|
|
|
20328
21143
|
// src/agents/provider-bridge.ts
|
|
20329
21144
|
var agentProvider = null;
|
|
@@ -20355,6 +21170,140 @@ function getAgentManager() {
|
|
|
20355
21170
|
|
|
20356
21171
|
// src/runtime/agent-runtime.ts
|
|
20357
21172
|
init_env();
|
|
21173
|
+
var PUBLIC_WEB_TOOLS = /* @__PURE__ */ new Set(["search_public_docs", "list_public_services"]);
|
|
21174
|
+
var CUSTOMER_SUPPORT_TOOLS = /* @__PURE__ */ new Set([
|
|
21175
|
+
"search_public_docs",
|
|
21176
|
+
"knowledge_search",
|
|
21177
|
+
"create_support_draft",
|
|
21178
|
+
"request_human_escalation"
|
|
21179
|
+
]);
|
|
21180
|
+
function createNoToolRegistry() {
|
|
21181
|
+
return new ToolRegistry();
|
|
21182
|
+
}
|
|
21183
|
+
function createCodingToolRegistry() {
|
|
21184
|
+
return createFullToolRegistry();
|
|
21185
|
+
}
|
|
21186
|
+
function createPublicWebToolRegistry(source) {
|
|
21187
|
+
return copyAllowedTools(PUBLIC_WEB_TOOLS, source);
|
|
21188
|
+
}
|
|
21189
|
+
function createCustomerSupportToolRegistry(source) {
|
|
21190
|
+
return copyAllowedTools(CUSTOMER_SUPPORT_TOOLS, source);
|
|
21191
|
+
}
|
|
21192
|
+
function createSupportRagToolRegistry(options = {}) {
|
|
21193
|
+
const registry = createRagToolRegistry(options.retriever);
|
|
21194
|
+
if (options.supportDraft) {
|
|
21195
|
+
registry.register(
|
|
21196
|
+
defineTool({
|
|
21197
|
+
name: "create_support_draft",
|
|
21198
|
+
description: "Create a support response draft from the customer message and approved retrieved sources.",
|
|
21199
|
+
category: "document",
|
|
21200
|
+
parameters: z.object({
|
|
21201
|
+
conversationId: z.string(),
|
|
21202
|
+
customerMessage: z.string(),
|
|
21203
|
+
retrievedSources: z.array(
|
|
21204
|
+
z.object({
|
|
21205
|
+
id: z.string(),
|
|
21206
|
+
title: z.string(),
|
|
21207
|
+
content: z.string(),
|
|
21208
|
+
url: z.string().optional(),
|
|
21209
|
+
score: z.number(),
|
|
21210
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
21211
|
+
})
|
|
21212
|
+
).optional()
|
|
21213
|
+
}),
|
|
21214
|
+
execute: options.supportDraft
|
|
21215
|
+
})
|
|
21216
|
+
);
|
|
21217
|
+
}
|
|
21218
|
+
if (options.humanEscalation) {
|
|
21219
|
+
registry.register(
|
|
21220
|
+
defineTool({
|
|
21221
|
+
name: "request_human_escalation",
|
|
21222
|
+
description: "Prepare a human escalation request. Runtime consumers must confirmation-gate this external action.",
|
|
21223
|
+
category: "config",
|
|
21224
|
+
parameters: z.object({
|
|
21225
|
+
conversationId: z.string(),
|
|
21226
|
+
summary: z.string(),
|
|
21227
|
+
priority: z.enum(["low", "normal", "high", "urgent"]),
|
|
21228
|
+
reason: z.string()
|
|
21229
|
+
}),
|
|
21230
|
+
execute: options.humanEscalation
|
|
21231
|
+
})
|
|
21232
|
+
);
|
|
21233
|
+
}
|
|
21234
|
+
return registry;
|
|
21235
|
+
}
|
|
21236
|
+
function createSalesIntakeToolRegistry(options = {}) {
|
|
21237
|
+
const registry = new ToolRegistry();
|
|
21238
|
+
if (options.leadSummary) {
|
|
21239
|
+
registry.register(
|
|
21240
|
+
defineTool({
|
|
21241
|
+
name: "create_sales_lead_summary",
|
|
21242
|
+
description: "Create a structured lead intake summary and recommended commercial next step.",
|
|
21243
|
+
category: "document",
|
|
21244
|
+
parameters: z.object({
|
|
21245
|
+
conversationId: z.string(),
|
|
21246
|
+
company: z.string().optional(),
|
|
21247
|
+
contact: z.string().optional(),
|
|
21248
|
+
problem: z.string(),
|
|
21249
|
+
desiredOutcome: z.string().optional(),
|
|
21250
|
+
urgency: z.enum(["low", "normal", "high"]).optional(),
|
|
21251
|
+
budgetRange: z.string().optional(),
|
|
21252
|
+
currentStack: z.string().optional()
|
|
21253
|
+
}),
|
|
21254
|
+
execute: options.leadSummary
|
|
21255
|
+
})
|
|
21256
|
+
);
|
|
21257
|
+
}
|
|
21258
|
+
return registry;
|
|
21259
|
+
}
|
|
21260
|
+
function createInternalOpsToolRegistry(options = {}) {
|
|
21261
|
+
const registry = new ToolRegistry();
|
|
21262
|
+
if (options.opsDraft) {
|
|
21263
|
+
registry.register(
|
|
21264
|
+
defineTool({
|
|
21265
|
+
name: "create_internal_ops_draft",
|
|
21266
|
+
description: "Prepare an internal operations action draft. This does not execute the operation.",
|
|
21267
|
+
category: "document",
|
|
21268
|
+
parameters: z.object({
|
|
21269
|
+
requestId: z.string(),
|
|
21270
|
+
requester: z.string().optional(),
|
|
21271
|
+
workflow: z.string(),
|
|
21272
|
+
requestedAction: z.string(),
|
|
21273
|
+
context: z.string().optional()
|
|
21274
|
+
}),
|
|
21275
|
+
execute: options.opsDraft
|
|
21276
|
+
})
|
|
21277
|
+
);
|
|
21278
|
+
}
|
|
21279
|
+
return registry;
|
|
21280
|
+
}
|
|
21281
|
+
function createRagToolRegistry(retriever) {
|
|
21282
|
+
const registry = new ToolRegistry();
|
|
21283
|
+
if (!retriever) return registry;
|
|
21284
|
+
registry.register(
|
|
21285
|
+
defineTool({
|
|
21286
|
+
name: "knowledge_search",
|
|
21287
|
+
description: "Search the configured knowledge base and return ranked sources.",
|
|
21288
|
+
category: "search",
|
|
21289
|
+
parameters: z.object({
|
|
21290
|
+
query: z.string(),
|
|
21291
|
+
limit: z.number().optional()
|
|
21292
|
+
}),
|
|
21293
|
+
execute: async ({ query, limit }) => retriever.search(query, { limit })
|
|
21294
|
+
})
|
|
21295
|
+
);
|
|
21296
|
+
return registry;
|
|
21297
|
+
}
|
|
21298
|
+
function copyAllowedTools(allowed, source) {
|
|
21299
|
+
const registry = new ToolRegistry();
|
|
21300
|
+
if (!source) return registry;
|
|
21301
|
+
for (const name of allowed) {
|
|
21302
|
+
const tool = source.get(name);
|
|
21303
|
+
if (tool) registry.register(tool);
|
|
21304
|
+
}
|
|
21305
|
+
return registry;
|
|
21306
|
+
}
|
|
20358
21307
|
init_errors();
|
|
20359
21308
|
init_allowed_paths();
|
|
20360
21309
|
function levenshtein(a, b) {
|
|
@@ -21450,14 +22399,14 @@ ${message}
|
|
|
21450
22399
|
const subprocess = execa(command, options);
|
|
21451
22400
|
let stdoutBuffer = "";
|
|
21452
22401
|
let stderrBuffer = "";
|
|
21453
|
-
subprocess.stdout?.on("data", (
|
|
21454
|
-
const text2 =
|
|
22402
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
22403
|
+
const text2 = chunk2.toString();
|
|
21455
22404
|
stdoutBuffer += text2;
|
|
21456
22405
|
process.stdout.write(text2);
|
|
21457
22406
|
heartbeat.activity();
|
|
21458
22407
|
});
|
|
21459
|
-
subprocess.stderr?.on("data", (
|
|
21460
|
-
const text2 =
|
|
22408
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
22409
|
+
const text2 = chunk2.toString();
|
|
21461
22410
|
stderrBuffer += text2;
|
|
21462
22411
|
process.stderr.write(text2);
|
|
21463
22412
|
heartbeat.activity();
|
|
@@ -22133,7 +23082,7 @@ var AGENT_TYPES = [
|
|
|
22133
23082
|
"docs",
|
|
22134
23083
|
"database"
|
|
22135
23084
|
];
|
|
22136
|
-
var
|
|
23085
|
+
var LEGACY_ROLE_MAP2 = {
|
|
22137
23086
|
researcher: "explore",
|
|
22138
23087
|
coder: "debug",
|
|
22139
23088
|
// "debug" has write + bash + read — closest to general coding
|
|
@@ -22153,7 +23102,7 @@ var SpawnSimpleAgentSchema = z.object({
|
|
|
22153
23102
|
});
|
|
22154
23103
|
function resolveAgentType(input) {
|
|
22155
23104
|
if (input.type) return input.type;
|
|
22156
|
-
if (input.role && input.role in
|
|
23105
|
+
if (input.role && input.role in LEGACY_ROLE_MAP2) return LEGACY_ROLE_MAP2[input.role];
|
|
22157
23106
|
return "explore";
|
|
22158
23107
|
}
|
|
22159
23108
|
var spawnSimpleAgentTool = defineTool({
|
|
@@ -23431,14 +24380,14 @@ ${message}
|
|
|
23431
24380
|
const subprocess = execa(pm, cmdArgs, options);
|
|
23432
24381
|
let stdoutBuffer = "";
|
|
23433
24382
|
let stderrBuffer = "";
|
|
23434
|
-
subprocess.stdout?.on("data", (
|
|
23435
|
-
const text2 =
|
|
24383
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
24384
|
+
const text2 = chunk2.toString();
|
|
23436
24385
|
stdoutBuffer += text2;
|
|
23437
24386
|
process.stdout.write(text2);
|
|
23438
24387
|
heartbeat.activity();
|
|
23439
24388
|
});
|
|
23440
|
-
subprocess.stderr?.on("data", (
|
|
23441
|
-
const text2 =
|
|
24389
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
24390
|
+
const text2 = chunk2.toString();
|
|
23442
24391
|
stderrBuffer += text2;
|
|
23443
24392
|
process.stderr.write(text2);
|
|
23444
24393
|
heartbeat.activity();
|
|
@@ -23556,14 +24505,14 @@ ${message}
|
|
|
23556
24505
|
const subprocess = execa(pm, cmdArgs, options);
|
|
23557
24506
|
let stdoutBuffer = "";
|
|
23558
24507
|
let stderrBuffer = "";
|
|
23559
|
-
subprocess.stdout?.on("data", (
|
|
23560
|
-
const text2 =
|
|
24508
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
24509
|
+
const text2 = chunk2.toString();
|
|
23561
24510
|
stdoutBuffer += text2;
|
|
23562
24511
|
process.stdout.write(text2);
|
|
23563
24512
|
heartbeat.activity();
|
|
23564
24513
|
});
|
|
23565
|
-
subprocess.stderr?.on("data", (
|
|
23566
|
-
const text2 =
|
|
24514
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
24515
|
+
const text2 = chunk2.toString();
|
|
23567
24516
|
stderrBuffer += text2;
|
|
23568
24517
|
process.stderr.write(text2);
|
|
23569
24518
|
heartbeat.activity();
|
|
@@ -23658,14 +24607,14 @@ ${message}
|
|
|
23658
24607
|
const subprocess = execa("make", cmdArgs, options);
|
|
23659
24608
|
let stdoutBuffer = "";
|
|
23660
24609
|
let stderrBuffer = "";
|
|
23661
|
-
subprocess.stdout?.on("data", (
|
|
23662
|
-
const text2 =
|
|
24610
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
24611
|
+
const text2 = chunk2.toString();
|
|
23663
24612
|
stdoutBuffer += text2;
|
|
23664
24613
|
process.stdout.write(text2);
|
|
23665
24614
|
heartbeat.activity();
|
|
23666
24615
|
});
|
|
23667
|
-
subprocess.stderr?.on("data", (
|
|
23668
|
-
const text2 =
|
|
24616
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
24617
|
+
const text2 = chunk2.toString();
|
|
23669
24618
|
stderrBuffer += text2;
|
|
23670
24619
|
process.stderr.write(text2);
|
|
23671
24620
|
heartbeat.activity();
|
|
@@ -23761,14 +24710,14 @@ ${message}
|
|
|
23761
24710
|
const subprocess = execa("npx", ["tsc", ...cmdArgs], options);
|
|
23762
24711
|
let stdoutBuffer = "";
|
|
23763
24712
|
let stderrBuffer = "";
|
|
23764
|
-
subprocess.stdout?.on("data", (
|
|
23765
|
-
const text2 =
|
|
24713
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
24714
|
+
const text2 = chunk2.toString();
|
|
23766
24715
|
stdoutBuffer += text2;
|
|
23767
24716
|
process.stdout.write(text2);
|
|
23768
24717
|
heartbeat.activity();
|
|
23769
24718
|
});
|
|
23770
|
-
subprocess.stderr?.on("data", (
|
|
23771
|
-
const text2 =
|
|
24719
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
24720
|
+
const text2 = chunk2.toString();
|
|
23772
24721
|
stderrBuffer += text2;
|
|
23773
24722
|
process.stderr.write(text2);
|
|
23774
24723
|
heartbeat.activity();
|
|
@@ -23865,14 +24814,14 @@ ${message}
|
|
|
23865
24814
|
});
|
|
23866
24815
|
let stdoutBuffer = "";
|
|
23867
24816
|
let stderrBuffer = "";
|
|
23868
|
-
subprocess.stdout?.on("data", (
|
|
23869
|
-
const text2 =
|
|
24817
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
24818
|
+
const text2 = chunk2.toString();
|
|
23870
24819
|
stdoutBuffer += text2;
|
|
23871
24820
|
process.stdout.write(text2);
|
|
23872
24821
|
heartbeat.activity();
|
|
23873
24822
|
});
|
|
23874
|
-
subprocess.stderr?.on("data", (
|
|
23875
|
-
const text2 =
|
|
24823
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
24824
|
+
const text2 = chunk2.toString();
|
|
23876
24825
|
stderrBuffer += text2;
|
|
23877
24826
|
process.stderr.write(text2);
|
|
23878
24827
|
heartbeat.activity();
|
|
@@ -23952,14 +24901,14 @@ ${message}
|
|
|
23952
24901
|
});
|
|
23953
24902
|
let stdoutBuffer = "";
|
|
23954
24903
|
let stderrBuffer = "";
|
|
23955
|
-
subprocess.stdout?.on("data", (
|
|
23956
|
-
const text2 =
|
|
24904
|
+
subprocess.stdout?.on("data", (chunk2) => {
|
|
24905
|
+
const text2 = chunk2.toString();
|
|
23957
24906
|
stdoutBuffer += text2;
|
|
23958
24907
|
process.stdout.write(text2);
|
|
23959
24908
|
heartbeat.activity();
|
|
23960
24909
|
});
|
|
23961
|
-
subprocess.stderr?.on("data", (
|
|
23962
|
-
const text2 =
|
|
24910
|
+
subprocess.stderr?.on("data", (chunk2) => {
|
|
24911
|
+
const text2 = chunk2.toString();
|
|
23963
24912
|
stderrBuffer += text2;
|
|
23964
24913
|
process.stderr.write(text2);
|
|
23965
24914
|
heartbeat.activity();
|
|
@@ -27167,13 +28116,13 @@ Examples:
|
|
|
27167
28116
|
const content = await fs28.readFile(fullPath, "utf-8");
|
|
27168
28117
|
if (content.length > 1e5) continue;
|
|
27169
28118
|
const fileChunks = chunkContent(content, DEFAULT_CHUNK_SIZE);
|
|
27170
|
-
for (const
|
|
27171
|
-
const vector = await getEmbedding(
|
|
28119
|
+
for (const chunk2 of fileChunks) {
|
|
28120
|
+
const vector = await getEmbedding(chunk2.text);
|
|
27172
28121
|
chunks.push({
|
|
27173
28122
|
file,
|
|
27174
|
-
startLine:
|
|
27175
|
-
endLine:
|
|
27176
|
-
text:
|
|
28123
|
+
startLine: chunk2.startLine,
|
|
28124
|
+
endLine: chunk2.endLine,
|
|
28125
|
+
text: chunk2.text,
|
|
27177
28126
|
vector,
|
|
27178
28127
|
mtime: stat2.mtimeMs
|
|
27179
28128
|
});
|
|
@@ -27207,9 +28156,9 @@ Examples:
|
|
|
27207
28156
|
}
|
|
27208
28157
|
}
|
|
27209
28158
|
const queryVector = await getEmbedding(query);
|
|
27210
|
-
const scored = index.chunks.map((
|
|
27211
|
-
chunk,
|
|
27212
|
-
score: cosineSimilarity(queryVector,
|
|
28159
|
+
const scored = index.chunks.map((chunk2) => ({
|
|
28160
|
+
chunk: chunk2,
|
|
28161
|
+
score: cosineSimilarity(queryVector, chunk2.vector)
|
|
27213
28162
|
}));
|
|
27214
28163
|
const filtered = scored.filter((s) => s.score >= effectiveThreshold).sort((a, b) => b.score - a.score).slice(0, effectiveMaxResults);
|
|
27215
28164
|
const results = filtered.map((s) => {
|
|
@@ -32305,7 +33254,6 @@ var READ_ONLY_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
32305
33254
|
"recall_memory",
|
|
32306
33255
|
"list_memories",
|
|
32307
33256
|
"list_checkpoints",
|
|
32308
|
-
"spawnSimpleAgent",
|
|
32309
33257
|
"checkAgentCapability"
|
|
32310
33258
|
]);
|
|
32311
33259
|
var WRITE_CAPABLE_TOOL_NAMES = /* @__PURE__ */ new Set(["run_linter"]);
|
|
@@ -32316,7 +33264,8 @@ var DESTRUCTIVE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
32316
33264
|
"delete_file",
|
|
32317
33265
|
"restore_checkpoint",
|
|
32318
33266
|
"git_commit",
|
|
32319
|
-
"git_push"
|
|
33267
|
+
"git_push",
|
|
33268
|
+
"request_human_escalation"
|
|
32320
33269
|
]);
|
|
32321
33270
|
function riskForTool(tool) {
|
|
32322
33271
|
if (READ_ONLY_TOOL_NAMES.has(tool.name)) return "read-only";
|
|
@@ -32350,6 +33299,22 @@ var DefaultPermissionPolicy = class {
|
|
|
32350
33299
|
return { allowed: true, risk };
|
|
32351
33300
|
}
|
|
32352
33301
|
canExecuteToolInput(mode, tool, input) {
|
|
33302
|
+
if (tool.name === "spawnSimpleAgent") {
|
|
33303
|
+
const risk = riskForSpawnedAgent(input);
|
|
33304
|
+
const definition2 = getAgentMode(mode);
|
|
33305
|
+
if (definition2.readOnly && risk !== "read-only" && risk !== "network") {
|
|
33306
|
+
return {
|
|
33307
|
+
allowed: false,
|
|
33308
|
+
reason: `${definition2.label} mode is read-only; spawnSimpleAgent with this role can perform ${risk} work.`,
|
|
33309
|
+
risk
|
|
33310
|
+
};
|
|
33311
|
+
}
|
|
33312
|
+
return {
|
|
33313
|
+
allowed: true,
|
|
33314
|
+
requiresConfirmation: risk === "destructive" || risk === "secrets-sensitive",
|
|
33315
|
+
risk
|
|
33316
|
+
};
|
|
33317
|
+
}
|
|
32353
33318
|
if (tool.name !== "run_linter") {
|
|
32354
33319
|
return this.canExecuteTool(mode, tool);
|
|
32355
33320
|
}
|
|
@@ -32369,6 +33334,37 @@ var DefaultPermissionPolicy = class {
|
|
|
32369
33334
|
function createPermissionPolicy() {
|
|
32370
33335
|
return new DefaultPermissionPolicy();
|
|
32371
33336
|
}
|
|
33337
|
+
function riskForSpawnedAgent(input) {
|
|
33338
|
+
const type = typeof input["type"] === "string" ? input["type"] : void 0;
|
|
33339
|
+
const role = typeof input["role"] === "string" ? input["role"] : void 0;
|
|
33340
|
+
const resolved = type ?? role;
|
|
33341
|
+
switch (resolved) {
|
|
33342
|
+
case "explore":
|
|
33343
|
+
case "plan":
|
|
33344
|
+
case "review":
|
|
33345
|
+
case "architect":
|
|
33346
|
+
case "security":
|
|
33347
|
+
case "docs":
|
|
33348
|
+
case "researcher":
|
|
33349
|
+
case "reviewer":
|
|
33350
|
+
case "planner":
|
|
33351
|
+
return "read-only";
|
|
33352
|
+
case "database":
|
|
33353
|
+
return "secrets-sensitive";
|
|
33354
|
+
case "test":
|
|
33355
|
+
case "tdd":
|
|
33356
|
+
case "e2e":
|
|
33357
|
+
case "tester":
|
|
33358
|
+
return "destructive";
|
|
33359
|
+
case "debug":
|
|
33360
|
+
case "refactor":
|
|
33361
|
+
case "coder":
|
|
33362
|
+
case "optimizer":
|
|
33363
|
+
return "write";
|
|
33364
|
+
default:
|
|
33365
|
+
return "read-only";
|
|
33366
|
+
}
|
|
33367
|
+
}
|
|
32372
33368
|
|
|
32373
33369
|
// src/runtime/provider-registry.ts
|
|
32374
33370
|
init_catalog();
|
|
@@ -32543,7 +33539,32 @@ function cloneWorkflow(workflow) {
|
|
|
32543
33539
|
steps: workflow.steps.map((step) => ({
|
|
32544
33540
|
...step,
|
|
32545
33541
|
requiredTools: [...step.requiredTools]
|
|
32546
|
-
}))
|
|
33542
|
+
})),
|
|
33543
|
+
nodes: workflow.nodes?.map((node) => ({
|
|
33544
|
+
...node,
|
|
33545
|
+
dependsOn: node.dependsOn ? [...node.dependsOn] : void 0,
|
|
33546
|
+
requiredTools: node.requiredTools ? [...node.requiredTools] : void 0,
|
|
33547
|
+
gates: node.gates ? [...node.gates] : void 0,
|
|
33548
|
+
retryPolicy: node.retryPolicy ? { ...node.retryPolicy } : void 0
|
|
33549
|
+
})),
|
|
33550
|
+
edges: workflow.edges?.map((edge) => ({ ...edge })),
|
|
33551
|
+
gates: workflow.gates?.map((gate) => ({ ...gate })),
|
|
33552
|
+
retryPolicy: workflow.retryPolicy ? { ...workflow.retryPolicy } : void 0
|
|
33553
|
+
};
|
|
33554
|
+
}
|
|
33555
|
+
function workflowToAgentGraph(workflow) {
|
|
33556
|
+
const nodes = workflow.nodes ?? workflow.steps.map((step, index) => ({
|
|
33557
|
+
id: step.id,
|
|
33558
|
+
description: step.description,
|
|
33559
|
+
requiredTools: [...step.requiredTools],
|
|
33560
|
+
risk: step.risk,
|
|
33561
|
+
dependsOn: index > 0 ? [workflow.steps[index - 1].id] : []
|
|
33562
|
+
}));
|
|
33563
|
+
return {
|
|
33564
|
+
nodes,
|
|
33565
|
+
edges: workflow.edges,
|
|
33566
|
+
gates: workflow.gates,
|
|
33567
|
+
parallelism: workflow.parallelism
|
|
32547
33568
|
};
|
|
32548
33569
|
}
|
|
32549
33570
|
var WorkflowCatalog = class {
|
|
@@ -32554,6 +33575,12 @@ var WorkflowCatalog = class {
|
|
|
32554
33575
|
}
|
|
32555
33576
|
}
|
|
32556
33577
|
register(workflow) {
|
|
33578
|
+
const validation = validateAgentGraph(workflowToAgentGraph(workflow));
|
|
33579
|
+
if (!validation.valid) {
|
|
33580
|
+
throw new Error(
|
|
33581
|
+
`Invalid workflow graph for '${workflow.id}': ${validation.issues.map((issue) => issue.message).join("; ")}`
|
|
33582
|
+
);
|
|
33583
|
+
}
|
|
32557
33584
|
this.workflows.set(workflow.id, cloneWorkflow(workflow));
|
|
32558
33585
|
}
|
|
32559
33586
|
get(id) {
|
|
@@ -32579,7 +33606,8 @@ var WorkflowCatalog = class {
|
|
|
32579
33606
|
workflowId,
|
|
32580
33607
|
planId: plan.id,
|
|
32581
33608
|
replayable: workflow.replayable,
|
|
32582
|
-
checks: workflow.checks
|
|
33609
|
+
checks: workflow.checks,
|
|
33610
|
+
graphLevels: validateAgentGraph(workflowToAgentGraph(workflow)).levels
|
|
32583
33611
|
});
|
|
32584
33612
|
return plan;
|
|
32585
33613
|
}
|
|
@@ -32729,19 +33757,26 @@ function createWorkflowRegistry(workflows) {
|
|
|
32729
33757
|
|
|
32730
33758
|
// src/runtime/workflow-engine.ts
|
|
32731
33759
|
var WorkflowEngine = class {
|
|
32732
|
-
constructor(catalog = createWorkflowCatalog(), eventLog = createEventLog()) {
|
|
33760
|
+
constructor(catalog = createWorkflowCatalog(), eventLog = createEventLog(), options = {}) {
|
|
32733
33761
|
this.catalog = catalog;
|
|
32734
33762
|
this.eventLog = eventLog;
|
|
33763
|
+
this.sharedState = options.sharedState ?? new InMemorySharedWorkspaceStore();
|
|
33764
|
+
this.nodeExecutor = options.nodeExecutor;
|
|
32735
33765
|
}
|
|
32736
33766
|
catalog;
|
|
32737
33767
|
eventLog;
|
|
32738
33768
|
handlers = /* @__PURE__ */ new Map();
|
|
33769
|
+
sharedState;
|
|
33770
|
+
nodeExecutor;
|
|
32739
33771
|
registerHandler(workflowId, handler) {
|
|
32740
33772
|
if (!this.catalog.get(workflowId)) {
|
|
32741
33773
|
throw new Error(`Unknown workflow: ${workflowId}`);
|
|
32742
33774
|
}
|
|
32743
33775
|
this.handlers.set(workflowId, handler);
|
|
32744
33776
|
}
|
|
33777
|
+
registerNodeExecutor(executor) {
|
|
33778
|
+
this.nodeExecutor = executor;
|
|
33779
|
+
}
|
|
32745
33780
|
createPlan(workflowId, input) {
|
|
32746
33781
|
return this.catalog.createPlan(workflowId, input, this.eventLog);
|
|
32747
33782
|
}
|
|
@@ -32751,23 +33786,35 @@ var WorkflowEngine = class {
|
|
|
32751
33786
|
throw new Error(`Unknown workflow: ${request.workflowId}`);
|
|
32752
33787
|
}
|
|
32753
33788
|
const handler = this.handlers.get(request.workflowId);
|
|
32754
|
-
if (!handler) {
|
|
32755
|
-
throw new Error(`No handler registered for workflow: ${request.workflowId}`);
|
|
32756
|
-
}
|
|
32757
33789
|
const plan = request.plan ?? this.createPlan(request.workflowId, request.input);
|
|
32758
33790
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
32759
33791
|
const runId = `${request.workflowId}-run-${Date.now().toString(36)}`;
|
|
33792
|
+
const trace = createAgentTraceContext({ workflowRunId: runId });
|
|
32760
33793
|
this.eventLog.record("workflow.started", {
|
|
32761
33794
|
workflowId: request.workflowId,
|
|
32762
33795
|
planId: plan.id,
|
|
32763
|
-
runId
|
|
33796
|
+
runId,
|
|
33797
|
+
trace
|
|
32764
33798
|
});
|
|
32765
33799
|
try {
|
|
32766
|
-
const
|
|
33800
|
+
const graphResult = handler ? void 0 : await new AgentGraphEngine({
|
|
33801
|
+
eventLog: this.eventLog,
|
|
33802
|
+
sharedState: this.sharedState,
|
|
33803
|
+
nodeExecutor: this.nodeExecutor,
|
|
33804
|
+
trace
|
|
33805
|
+
}).run({
|
|
33806
|
+
workflowRunId: runId,
|
|
33807
|
+
graph: workflowToAgentGraph(workflow),
|
|
33808
|
+
input: request.input
|
|
33809
|
+
});
|
|
33810
|
+
const output = graphResult ?? await handler(request.input, {
|
|
32767
33811
|
workflow,
|
|
32768
33812
|
plan,
|
|
32769
33813
|
eventLog: this.eventLog
|
|
32770
33814
|
});
|
|
33815
|
+
if (graphResult?.status === "failed") {
|
|
33816
|
+
throw new Error(graphResult.error ?? "Workflow graph failed");
|
|
33817
|
+
}
|
|
32771
33818
|
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
32772
33819
|
const result = {
|
|
32773
33820
|
id: runId,
|
|
@@ -32775,12 +33822,15 @@ var WorkflowEngine = class {
|
|
|
32775
33822
|
status: "completed",
|
|
32776
33823
|
output,
|
|
32777
33824
|
startedAt,
|
|
32778
|
-
completedAt
|
|
33825
|
+
completedAt,
|
|
33826
|
+
graphResult,
|
|
33827
|
+
trace
|
|
32779
33828
|
};
|
|
32780
33829
|
this.eventLog.record("workflow.completed", {
|
|
32781
33830
|
workflowId: request.workflowId,
|
|
32782
33831
|
planId: plan.id,
|
|
32783
|
-
runId
|
|
33832
|
+
runId,
|
|
33833
|
+
trace
|
|
32784
33834
|
});
|
|
32785
33835
|
return result;
|
|
32786
33836
|
} catch (error) {
|
|
@@ -32790,7 +33840,8 @@ var WorkflowEngine = class {
|
|
|
32790
33840
|
workflowId: request.workflowId,
|
|
32791
33841
|
planId: plan.id,
|
|
32792
33842
|
runId,
|
|
32793
|
-
error: message
|
|
33843
|
+
error: message,
|
|
33844
|
+
trace
|
|
32794
33845
|
});
|
|
32795
33846
|
return {
|
|
32796
33847
|
id: runId,
|
|
@@ -32799,13 +33850,14 @@ var WorkflowEngine = class {
|
|
|
32799
33850
|
output: null,
|
|
32800
33851
|
startedAt,
|
|
32801
33852
|
completedAt,
|
|
32802
|
-
error: message
|
|
33853
|
+
error: message,
|
|
33854
|
+
trace
|
|
32803
33855
|
};
|
|
32804
33856
|
}
|
|
32805
33857
|
}
|
|
32806
33858
|
};
|
|
32807
|
-
function createWorkflowEngine(catalog, eventLog) {
|
|
32808
|
-
return new WorkflowEngine(catalog, eventLog);
|
|
33859
|
+
function createWorkflowEngine(catalog, eventLog, options) {
|
|
33860
|
+
return new WorkflowEngine(catalog, eventLog, options);
|
|
32809
33861
|
}
|
|
32810
33862
|
|
|
32811
33863
|
// src/runtime/agent-runtime.ts
|
|
@@ -32983,7 +34035,7 @@ var AgentRuntime = class {
|
|
|
32983
34035
|
let completed = false;
|
|
32984
34036
|
let failed = false;
|
|
32985
34037
|
try {
|
|
32986
|
-
for await (const
|
|
34038
|
+
for await (const chunk2 of provider.stream(messages, {
|
|
32987
34039
|
model: input.options?.model,
|
|
32988
34040
|
maxTokens: input.options?.maxTokens,
|
|
32989
34041
|
temperature: input.options?.temperature,
|
|
@@ -32993,12 +34045,12 @@ var AgentRuntime = class {
|
|
|
32993
34045
|
signal: input.options?.signal,
|
|
32994
34046
|
thinking: input.options?.thinking
|
|
32995
34047
|
})) {
|
|
32996
|
-
if (
|
|
32997
|
-
content +=
|
|
34048
|
+
if (chunk2.type === "text" && chunk2.text) {
|
|
34049
|
+
content += chunk2.text;
|
|
32998
34050
|
yield {
|
|
32999
34051
|
type: "text",
|
|
33000
34052
|
sessionId: effectiveSession.id,
|
|
33001
|
-
text:
|
|
34053
|
+
text: chunk2.text
|
|
33002
34054
|
};
|
|
33003
34055
|
}
|
|
33004
34056
|
}
|
|
@@ -33177,6 +34229,213 @@ async function createAgentRuntime(options) {
|
|
|
33177
34229
|
await runtime.initialize();
|
|
33178
34230
|
return runtime;
|
|
33179
34231
|
}
|
|
34232
|
+
|
|
34233
|
+
// src/runtime/agent-runner.ts
|
|
34234
|
+
var AgentRunner = class {
|
|
34235
|
+
constructor(options = {}) {
|
|
34236
|
+
this.options = options;
|
|
34237
|
+
}
|
|
34238
|
+
options;
|
|
34239
|
+
async run(input) {
|
|
34240
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
34241
|
+
const trace = input.trace ?? createAgentTraceContext({ taskId: input.task.id });
|
|
34242
|
+
this.options.eventLog?.record("agent.started", {
|
|
34243
|
+
taskId: input.task.id,
|
|
34244
|
+
role: input.task.role,
|
|
34245
|
+
trace
|
|
34246
|
+
});
|
|
34247
|
+
try {
|
|
34248
|
+
const raw = await (this.options.executor ?? defaultExecutor)({
|
|
34249
|
+
task: input.task,
|
|
34250
|
+
capability: input.capability,
|
|
34251
|
+
trace,
|
|
34252
|
+
assertToolAllowed: (toolName) => {
|
|
34253
|
+
const decision = evaluateAgentToolPolicy({
|
|
34254
|
+
capability: input.capability,
|
|
34255
|
+
toolName,
|
|
34256
|
+
manifest: input.toolRiskManifest
|
|
34257
|
+
});
|
|
34258
|
+
this.options.eventLog?.record("agent.tool.called", {
|
|
34259
|
+
taskId: input.task.id,
|
|
34260
|
+
role: input.task.role,
|
|
34261
|
+
toolName,
|
|
34262
|
+
decision,
|
|
34263
|
+
trace
|
|
34264
|
+
});
|
|
34265
|
+
if (!decision.allowed) {
|
|
34266
|
+
throw new Error(decision.reason ?? `Tool '${toolName}' is not allowed.`);
|
|
34267
|
+
}
|
|
34268
|
+
}
|
|
34269
|
+
});
|
|
34270
|
+
const result = normalizeAgentRunResult({
|
|
34271
|
+
id: `${input.task.id}-run-${Date.now().toString(36)}`,
|
|
34272
|
+
taskId: input.task.id,
|
|
34273
|
+
role: input.task.role,
|
|
34274
|
+
success: raw.success ?? true,
|
|
34275
|
+
output: raw.output,
|
|
34276
|
+
turns: raw.turns,
|
|
34277
|
+
toolsUsed: raw.toolsUsed,
|
|
34278
|
+
usage: {
|
|
34279
|
+
inputTokens: raw.inputTokens ?? 0,
|
|
34280
|
+
outputTokens: raw.outputTokens ?? 0,
|
|
34281
|
+
estimated: raw.inputTokens === void 0 || raw.outputTokens === void 0
|
|
34282
|
+
},
|
|
34283
|
+
startedAt,
|
|
34284
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34285
|
+
durationMs: Date.now() - Date.parse(startedAt),
|
|
34286
|
+
error: raw.error,
|
|
34287
|
+
metadata: { ...raw.metadata, trace }
|
|
34288
|
+
});
|
|
34289
|
+
this.options.eventLog?.record(result.success ? "agent.completed" : "agent.failed", {
|
|
34290
|
+
taskId: input.task.id,
|
|
34291
|
+
role: input.task.role,
|
|
34292
|
+
agentRunId: result.id,
|
|
34293
|
+
trace,
|
|
34294
|
+
error: result.error
|
|
34295
|
+
});
|
|
34296
|
+
return result;
|
|
34297
|
+
} catch (error) {
|
|
34298
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34299
|
+
const result = normalizeAgentRunResult({
|
|
34300
|
+
id: `${input.task.id}-run-${Date.now().toString(36)}`,
|
|
34301
|
+
taskId: input.task.id,
|
|
34302
|
+
role: input.task.role,
|
|
34303
|
+
success: false,
|
|
34304
|
+
output: message,
|
|
34305
|
+
startedAt,
|
|
34306
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34307
|
+
durationMs: Date.now() - Date.parse(startedAt),
|
|
34308
|
+
error: message,
|
|
34309
|
+
metadata: { trace }
|
|
34310
|
+
});
|
|
34311
|
+
this.options.eventLog?.record("agent.failed", {
|
|
34312
|
+
taskId: input.task.id,
|
|
34313
|
+
role: input.task.role,
|
|
34314
|
+
agentRunId: result.id,
|
|
34315
|
+
trace,
|
|
34316
|
+
error: message
|
|
34317
|
+
});
|
|
34318
|
+
return result;
|
|
34319
|
+
}
|
|
34320
|
+
}
|
|
34321
|
+
};
|
|
34322
|
+
function createAgentRunner(options) {
|
|
34323
|
+
return new AgentRunner(options);
|
|
34324
|
+
}
|
|
34325
|
+
async function defaultExecutor(context) {
|
|
34326
|
+
return {
|
|
34327
|
+
output: `Agent ${context.capability.role} accepted task '${context.task.objective}'.`
|
|
34328
|
+
};
|
|
34329
|
+
}
|
|
34330
|
+
|
|
34331
|
+
// src/runtime/tool-calling-turn-runner.ts
|
|
34332
|
+
function runtimeWithTools(runtime) {
|
|
34333
|
+
if (runtime && typeof runtime === "object" && "executeTool" in runtime && typeof runtime.executeTool === "function") {
|
|
34334
|
+
return runtime;
|
|
34335
|
+
}
|
|
34336
|
+
throw new Error("ToolCallingRuntimeTurnRunner requires a runtime with executeTool().");
|
|
34337
|
+
}
|
|
34338
|
+
function toolResultToContent(result) {
|
|
34339
|
+
if (!result.success) {
|
|
34340
|
+
return `Error: ${result.error ?? "Tool failed."}`;
|
|
34341
|
+
}
|
|
34342
|
+
if (typeof result.output === "string") return result.output;
|
|
34343
|
+
return JSON.stringify(result.output ?? null);
|
|
34344
|
+
}
|
|
34345
|
+
var ToolCallingRuntimeTurnRunner = class {
|
|
34346
|
+
maxToolIterations;
|
|
34347
|
+
constructor(options = {}) {
|
|
34348
|
+
this.maxToolIterations = options.maxToolIterations ?? 10;
|
|
34349
|
+
}
|
|
34350
|
+
async run(input, context) {
|
|
34351
|
+
const runtime = runtimeWithTools(context.runtime);
|
|
34352
|
+
const messages = [
|
|
34353
|
+
...context.session.messages,
|
|
34354
|
+
{
|
|
34355
|
+
role: "user",
|
|
34356
|
+
content: input.content
|
|
34357
|
+
}
|
|
34358
|
+
];
|
|
34359
|
+
const tools = context.toolRegistry.getToolDefinitionsForLLM();
|
|
34360
|
+
const confirmedTools = new Set(input.confirmedTools ?? []);
|
|
34361
|
+
let inputTokens = 0;
|
|
34362
|
+
let outputTokens = 0;
|
|
34363
|
+
let lastModel = input.options?.model ?? context.provider.id;
|
|
34364
|
+
for (let iteration = 0; iteration < this.maxToolIterations; iteration++) {
|
|
34365
|
+
const response = await context.provider.chatWithTools(messages, {
|
|
34366
|
+
tools,
|
|
34367
|
+
model: input.options?.model,
|
|
34368
|
+
maxTokens: input.options?.maxTokens,
|
|
34369
|
+
temperature: input.options?.temperature,
|
|
34370
|
+
stopSequences: input.options?.stopSequences,
|
|
34371
|
+
system: context.session.instructions ?? input.options?.system,
|
|
34372
|
+
timeout: input.options?.timeout,
|
|
34373
|
+
signal: input.options?.signal,
|
|
34374
|
+
thinking: input.options?.thinking
|
|
34375
|
+
});
|
|
34376
|
+
inputTokens += response.usage.inputTokens;
|
|
34377
|
+
outputTokens += response.usage.outputTokens;
|
|
34378
|
+
lastModel = response.model;
|
|
34379
|
+
if (response.stopReason !== "tool_use" || response.toolCalls.length === 0) {
|
|
34380
|
+
return {
|
|
34381
|
+
sessionId: context.session.id,
|
|
34382
|
+
content: response.content,
|
|
34383
|
+
usage: { inputTokens, outputTokens },
|
|
34384
|
+
model: response.model,
|
|
34385
|
+
mode: context.session.mode
|
|
34386
|
+
};
|
|
34387
|
+
}
|
|
34388
|
+
const assistantContent = [];
|
|
34389
|
+
if (response.content.trim().length > 0) {
|
|
34390
|
+
assistantContent.push({ type: "text", text: response.content });
|
|
34391
|
+
}
|
|
34392
|
+
for (const toolCall of response.toolCalls) {
|
|
34393
|
+
assistantContent.push({
|
|
34394
|
+
type: "tool_use",
|
|
34395
|
+
id: toolCall.id,
|
|
34396
|
+
name: toolCall.name,
|
|
34397
|
+
input: toolCall.input,
|
|
34398
|
+
geminiThoughtSignature: toolCall.geminiThoughtSignature
|
|
34399
|
+
});
|
|
34400
|
+
}
|
|
34401
|
+
messages.push({
|
|
34402
|
+
role: "assistant",
|
|
34403
|
+
content: assistantContent
|
|
34404
|
+
});
|
|
34405
|
+
const toolResults = [];
|
|
34406
|
+
for (const toolCall of response.toolCalls) {
|
|
34407
|
+
const result = await runtime.executeTool({
|
|
34408
|
+
sessionId: context.session.id,
|
|
34409
|
+
mode: context.session.mode,
|
|
34410
|
+
toolName: toolCall.name,
|
|
34411
|
+
input: toolCall.input,
|
|
34412
|
+
confirmed: confirmedTools.has(toolCall.name),
|
|
34413
|
+
metadata: input.metadata
|
|
34414
|
+
});
|
|
34415
|
+
toolResults.push({
|
|
34416
|
+
type: "tool_result",
|
|
34417
|
+
tool_use_id: toolCall.id,
|
|
34418
|
+
content: toolResultToContent(result),
|
|
34419
|
+
is_error: !result.success
|
|
34420
|
+
});
|
|
34421
|
+
}
|
|
34422
|
+
messages.push({
|
|
34423
|
+
role: "user",
|
|
34424
|
+
content: toolResults
|
|
34425
|
+
});
|
|
34426
|
+
}
|
|
34427
|
+
return {
|
|
34428
|
+
sessionId: context.session.id,
|
|
34429
|
+
content: "The tool-calling runtime reached its maximum tool iteration budget.",
|
|
34430
|
+
usage: { inputTokens, outputTokens },
|
|
34431
|
+
model: lastModel,
|
|
34432
|
+
mode: context.session.mode
|
|
34433
|
+
};
|
|
34434
|
+
}
|
|
34435
|
+
};
|
|
34436
|
+
function createToolCallingRuntimeTurnRunner(options) {
|
|
34437
|
+
return new ToolCallingRuntimeTurnRunner(options);
|
|
34438
|
+
}
|
|
33180
34439
|
var HttpRequestError = class extends Error {
|
|
33181
34440
|
constructor(message, status) {
|
|
33182
34441
|
super(message);
|
|
@@ -33187,8 +34446,8 @@ var HttpRequestError = class extends Error {
|
|
|
33187
34446
|
async function readJsonBody(request, maxBodyBytes) {
|
|
33188
34447
|
const chunks = [];
|
|
33189
34448
|
let size = 0;
|
|
33190
|
-
for await (const
|
|
33191
|
-
const buffer = Buffer.isBuffer(
|
|
34449
|
+
for await (const chunk2 of request) {
|
|
34450
|
+
const buffer = Buffer.isBuffer(chunk2) ? chunk2 : Buffer.from(chunk2);
|
|
33192
34451
|
size += buffer.length;
|
|
33193
34452
|
if (size > maxBodyBytes) {
|
|
33194
34453
|
throw new HttpRequestError(`Request body exceeds ${maxBodyBytes} bytes.`, 413);
|
|
@@ -33288,11 +34547,551 @@ function createMcpToolPolicy(server, tool, risk, allowedModes = ["ask", "plan",
|
|
|
33288
34547
|
};
|
|
33289
34548
|
}
|
|
33290
34549
|
|
|
34550
|
+
// src/runtime/guardrails.ts
|
|
34551
|
+
var DEFAULT_REDACTION = "[REDACTED]";
|
|
34552
|
+
var SECRET_PATTERNS = [
|
|
34553
|
+
{ id: "openai-api-key", pattern: /\bsk-[A-Za-z0-9_-]{20,}\b/g },
|
|
34554
|
+
{ id: "anthropic-api-key", pattern: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g },
|
|
34555
|
+
{ id: "github-token", pattern: /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/g },
|
|
34556
|
+
{ id: "generic-bearer-token", pattern: /\bBearer\s+[A-Za-z0-9._~+/=-]{20,}\b/gi },
|
|
34557
|
+
{
|
|
34558
|
+
id: "private-key",
|
|
34559
|
+
pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g
|
|
34560
|
+
}
|
|
34561
|
+
];
|
|
34562
|
+
var PROMPT_INJECTION_PATTERNS = [
|
|
34563
|
+
{
|
|
34564
|
+
id: "ignore-instructions",
|
|
34565
|
+
pattern: /\b(ignore|forget|override|bypass)\b.{0,60}\b(instructions|system|developer|policy|guardrail)\b/i
|
|
34566
|
+
},
|
|
34567
|
+
{
|
|
34568
|
+
id: "reveal-prompt",
|
|
34569
|
+
pattern: /\b(reveal|print|show|dump)\b.{0,40}\b(system prompt|instructions|developer message)\b/i
|
|
34570
|
+
},
|
|
34571
|
+
{
|
|
34572
|
+
id: "tool-exfiltration",
|
|
34573
|
+
pattern: /\b(use|call|run)\b.{0,40}\b(tool|shell|filesystem|git)\b.{0,40}\b(secret|token|key)\b/i
|
|
34574
|
+
},
|
|
34575
|
+
{
|
|
34576
|
+
id: "agent-privilege-escalation",
|
|
34577
|
+
pattern: /\b(spawn|delegate|handoff)\b.{0,50}\b(agent|sub.?agent)\b.{0,50}\b(admin|root|full access|unrestricted|destructive)\b/i
|
|
34578
|
+
},
|
|
34579
|
+
{
|
|
34580
|
+
id: "credential-exfiltration",
|
|
34581
|
+
pattern: /\b(exfiltrate|copy|send|upload)\b.{0,50}\b(secret|token|api key|credential|private key)\b/i
|
|
34582
|
+
}
|
|
34583
|
+
];
|
|
34584
|
+
var defaultPublicGuardrails = {
|
|
34585
|
+
maxInputChars: 4e3,
|
|
34586
|
+
maxOutputChars: 6e3,
|
|
34587
|
+
secretRedaction: { enabled: true },
|
|
34588
|
+
promptInjectionDetection: true
|
|
34589
|
+
};
|
|
34590
|
+
function redactSecrets(content, config = { enabled: true }) {
|
|
34591
|
+
if (!config.enabled) return { content, findings: [] };
|
|
34592
|
+
let redacted = content;
|
|
34593
|
+
const findings = [];
|
|
34594
|
+
const replacement = config.replacement ?? DEFAULT_REDACTION;
|
|
34595
|
+
for (const { id, pattern } of SECRET_PATTERNS) {
|
|
34596
|
+
const before = redacted;
|
|
34597
|
+
redacted = redacted.replace(pattern, replacement);
|
|
34598
|
+
if (before !== redacted) {
|
|
34599
|
+
findings.push({
|
|
34600
|
+
id,
|
|
34601
|
+
stage: "input",
|
|
34602
|
+
severity: "warning",
|
|
34603
|
+
message: `Potential secret redacted: ${id}`,
|
|
34604
|
+
redacted: true
|
|
34605
|
+
});
|
|
34606
|
+
}
|
|
34607
|
+
}
|
|
34608
|
+
return { content: redacted, findings };
|
|
34609
|
+
}
|
|
34610
|
+
function runGuardrails(stage, content, config = {}) {
|
|
34611
|
+
const findings = [];
|
|
34612
|
+
const maxChars = stage === "input" ? config.maxInputChars : config.maxOutputChars;
|
|
34613
|
+
let checked = content;
|
|
34614
|
+
if (typeof maxChars === "number" && checked.length > maxChars) {
|
|
34615
|
+
findings.push({
|
|
34616
|
+
id: `${stage}-too-long`,
|
|
34617
|
+
stage,
|
|
34618
|
+
severity: "blocked",
|
|
34619
|
+
message: `${stage} exceeds ${maxChars} characters.`
|
|
34620
|
+
});
|
|
34621
|
+
}
|
|
34622
|
+
const redaction = redactSecrets(checked, config.secretRedaction);
|
|
34623
|
+
checked = redaction.content;
|
|
34624
|
+
findings.push(...redaction.findings.map((finding) => ({ ...finding, stage })));
|
|
34625
|
+
if (config.promptInjectionDetection) {
|
|
34626
|
+
for (const { id, pattern } of PROMPT_INJECTION_PATTERNS) {
|
|
34627
|
+
if (pattern.test(checked)) {
|
|
34628
|
+
findings.push({
|
|
34629
|
+
id,
|
|
34630
|
+
stage,
|
|
34631
|
+
severity: "warning",
|
|
34632
|
+
message: `Potential prompt-injection pattern detected: ${id}`
|
|
34633
|
+
});
|
|
34634
|
+
}
|
|
34635
|
+
}
|
|
34636
|
+
}
|
|
34637
|
+
const blockedTopics = config.topicBoundary?.blockedTopics ?? [];
|
|
34638
|
+
for (const topic of blockedTopics) {
|
|
34639
|
+
if (topic && checked.toLowerCase().includes(topic.toLowerCase())) {
|
|
34640
|
+
findings.push({
|
|
34641
|
+
id: "blocked-topic",
|
|
34642
|
+
stage,
|
|
34643
|
+
severity: "blocked",
|
|
34644
|
+
message: `Content mentions blocked topic: ${topic}`
|
|
34645
|
+
});
|
|
34646
|
+
}
|
|
34647
|
+
}
|
|
34648
|
+
return {
|
|
34649
|
+
allowed: !findings.some((finding) => finding.severity === "blocked"),
|
|
34650
|
+
content: checked,
|
|
34651
|
+
findings
|
|
34652
|
+
};
|
|
34653
|
+
}
|
|
34654
|
+
function validateStructuredOutput(output, schema) {
|
|
34655
|
+
if (!schema) return [];
|
|
34656
|
+
const result = schema.safeParse(output);
|
|
34657
|
+
if (result.success) return [];
|
|
34658
|
+
return [
|
|
34659
|
+
{
|
|
34660
|
+
id: "invalid-structured-output",
|
|
34661
|
+
stage: "output",
|
|
34662
|
+
severity: "blocked",
|
|
34663
|
+
message: result.error.issues.map((issue) => issue.message).join("; ")
|
|
34664
|
+
}
|
|
34665
|
+
];
|
|
34666
|
+
}
|
|
34667
|
+
|
|
34668
|
+
// src/runtime/blueprints.ts
|
|
34669
|
+
function mapActionModeToRuntimeMode(mode) {
|
|
34670
|
+
if (mode === "act") return "build";
|
|
34671
|
+
if (mode === "review") return "review";
|
|
34672
|
+
return "ask";
|
|
34673
|
+
}
|
|
34674
|
+
function createSafeToolRegistry(allowedTools, source) {
|
|
34675
|
+
const safe = new ToolRegistry();
|
|
34676
|
+
if (!source) return safe;
|
|
34677
|
+
for (const toolName of allowedTools) {
|
|
34678
|
+
const tool = source.get(toolName);
|
|
34679
|
+
if (tool) safe.register(tool);
|
|
34680
|
+
}
|
|
34681
|
+
return safe;
|
|
34682
|
+
}
|
|
34683
|
+
async function createAgentFromBlueprint(blueprint, options) {
|
|
34684
|
+
const runtime = await createAgentRuntime({
|
|
34685
|
+
providerType: options.providerType,
|
|
34686
|
+
model: options.model,
|
|
34687
|
+
providerConfig: options.providerConfig,
|
|
34688
|
+
provider: options.provider,
|
|
34689
|
+
eventLog: options.eventLog,
|
|
34690
|
+
turnRunner: options.turnRunner,
|
|
34691
|
+
toolRegistry: options.toolRegistry ?? createSafeToolRegistry(blueprint.allowedTools.length > 0 ? blueprint.allowedTools : []),
|
|
34692
|
+
publishToGlobalBridge: false
|
|
34693
|
+
});
|
|
34694
|
+
return {
|
|
34695
|
+
blueprint,
|
|
34696
|
+
runtime,
|
|
34697
|
+
createSession(metadata = {}) {
|
|
34698
|
+
return runtime.createSession({
|
|
34699
|
+
mode: mapActionModeToRuntimeMode(blueprint.defaultMode),
|
|
34700
|
+
instructions: blueprint.instructions,
|
|
34701
|
+
metadata: {
|
|
34702
|
+
blueprintId: blueprint.id,
|
|
34703
|
+
surface: blueprint.surface,
|
|
34704
|
+
...metadata
|
|
34705
|
+
}
|
|
34706
|
+
});
|
|
34707
|
+
},
|
|
34708
|
+
async runTurn(input) {
|
|
34709
|
+
const guardrails = { ...defaultPublicGuardrails, ...blueprint.guardrails };
|
|
34710
|
+
const checkedInput = runGuardrails("input", input.content, guardrails);
|
|
34711
|
+
runtime.eventLog.record("guardrail.input", {
|
|
34712
|
+
blueprintId: blueprint.id,
|
|
34713
|
+
allowed: checkedInput.allowed,
|
|
34714
|
+
findings: checkedInput.findings
|
|
34715
|
+
});
|
|
34716
|
+
if (!checkedInput.allowed) {
|
|
34717
|
+
throw new Error(formatGuardrailBlock(checkedInput.findings));
|
|
34718
|
+
}
|
|
34719
|
+
const result = await runtime.runTurn({
|
|
34720
|
+
...input,
|
|
34721
|
+
content: checkedInput.content,
|
|
34722
|
+
mode: input.mode ?? mapActionModeToRuntimeMode(blueprint.defaultMode)
|
|
34723
|
+
});
|
|
34724
|
+
const checkedOutput = runGuardrails("output", result.content, guardrails);
|
|
34725
|
+
runtime.eventLog.record("guardrail.output", {
|
|
34726
|
+
blueprintId: blueprint.id,
|
|
34727
|
+
allowed: checkedOutput.allowed,
|
|
34728
|
+
findings: checkedOutput.findings
|
|
34729
|
+
});
|
|
34730
|
+
if (!checkedOutput.allowed) {
|
|
34731
|
+
throw new Error(formatGuardrailBlock(checkedOutput.findings));
|
|
34732
|
+
}
|
|
34733
|
+
return { ...result, content: checkedOutput.content };
|
|
34734
|
+
}
|
|
34735
|
+
};
|
|
34736
|
+
}
|
|
34737
|
+
function formatGuardrailBlock(findings) {
|
|
34738
|
+
const messages = findings.filter((finding) => finding.severity === "blocked").map((finding) => finding.message);
|
|
34739
|
+
return messages.length > 0 ? messages.join("; ") : "Guardrail blocked the request.";
|
|
34740
|
+
}
|
|
34741
|
+
function createBaseBlueprint(input) {
|
|
34742
|
+
return {
|
|
34743
|
+
...input,
|
|
34744
|
+
guardrails: input.guardrails ?? defaultPublicGuardrails,
|
|
34745
|
+
memory: input.memory ?? { enabled: true, retention: "session" },
|
|
34746
|
+
approval: input.approval ?? { requireHumanForExternalActions: true },
|
|
34747
|
+
observability: input.observability ?? { logEvents: true, redactSensitiveData: true }
|
|
34748
|
+
};
|
|
34749
|
+
}
|
|
34750
|
+
|
|
34751
|
+
// src/runtime/rag.ts
|
|
34752
|
+
var InMemoryKnowledgeRetriever = class {
|
|
34753
|
+
constructor(documents) {
|
|
34754
|
+
this.documents = documents;
|
|
34755
|
+
}
|
|
34756
|
+
documents;
|
|
34757
|
+
async search(query, options = {}) {
|
|
34758
|
+
const terms = tokenize(query);
|
|
34759
|
+
const limit = options.limit ?? 5;
|
|
34760
|
+
const minScore = options.minScore ?? 0;
|
|
34761
|
+
return this.documents.map((document) => ({
|
|
34762
|
+
...document,
|
|
34763
|
+
score: scoreDocument(document, terms)
|
|
34764
|
+
})).filter((source) => source.score >= minScore && source.score > 0).sort((a, b) => b.score - a.score).slice(0, limit);
|
|
34765
|
+
}
|
|
34766
|
+
};
|
|
34767
|
+
function createInMemoryKnowledgeRetriever(documents) {
|
|
34768
|
+
return new InMemoryKnowledgeRetriever(documents);
|
|
34769
|
+
}
|
|
34770
|
+
function formatRetrievedSourcesForPrompt(sources) {
|
|
34771
|
+
if (sources.length === 0) return "No retrieved sources.";
|
|
34772
|
+
return sources.map((source, index) => {
|
|
34773
|
+
const url = source.url ? `
|
|
34774
|
+
URL: ${source.url}` : "";
|
|
34775
|
+
return `[${index + 1}] ${source.title}${url}
|
|
34776
|
+
${source.content}`;
|
|
34777
|
+
}).join("\n\n");
|
|
34778
|
+
}
|
|
34779
|
+
function tokenize(text2) {
|
|
34780
|
+
return text2.toLowerCase().split(/[^a-z0-9áéíóúüñ]+/i).map((term) => term.trim()).filter((term) => term.length > 2);
|
|
34781
|
+
}
|
|
34782
|
+
function scoreDocument(document, terms) {
|
|
34783
|
+
const haystack = `${document.title}
|
|
34784
|
+
${document.content}`.toLowerCase();
|
|
34785
|
+
if (terms.length === 0) return 0;
|
|
34786
|
+
const matches = terms.filter((term) => haystack.includes(term)).length;
|
|
34787
|
+
return matches / terms.length;
|
|
34788
|
+
}
|
|
34789
|
+
|
|
34790
|
+
// src/presets/index.ts
|
|
34791
|
+
var publicWebsiteAssistantPreset = {
|
|
34792
|
+
id: "public-website-assistant",
|
|
34793
|
+
name: "Public Website Assistant",
|
|
34794
|
+
createBlueprint(config) {
|
|
34795
|
+
return createBaseBlueprint({
|
|
34796
|
+
id: "public-website-assistant",
|
|
34797
|
+
name: "Public Website Assistant",
|
|
34798
|
+
description: "Safe public assistant for landing pages, FAQs, service explanation, and lead intake.",
|
|
34799
|
+
surface: "web",
|
|
34800
|
+
defaultMode: "ask",
|
|
34801
|
+
maturity: "experimental",
|
|
34802
|
+
instructions: [
|
|
34803
|
+
`You are the public website assistant for ${config.brand}.`,
|
|
34804
|
+
"Help visitors understand services, ask concise qualification questions, and suggest a safe next step.",
|
|
34805
|
+
"Do not claim that you sent messages, changed systems, booked meetings, or created records unless a registered tool result proves it.",
|
|
34806
|
+
"If you are unsure, say so and offer to route the visitor to a human.",
|
|
34807
|
+
config.audience ? `Primary audience: ${config.audience}.` : "",
|
|
34808
|
+
config.extraInstructions ?? ""
|
|
34809
|
+
].filter(Boolean).join("\n"),
|
|
34810
|
+
allowedTools: []
|
|
34811
|
+
});
|
|
34812
|
+
},
|
|
34813
|
+
async createRuntime(config) {
|
|
34814
|
+
return createPresetRuntime(config, publicWebsiteAssistantPreset.createBlueprint(config));
|
|
34815
|
+
}
|
|
34816
|
+
};
|
|
34817
|
+
var ragKnowledgeAssistantPreset = {
|
|
34818
|
+
id: "rag-knowledge-assistant",
|
|
34819
|
+
name: "RAG Knowledge Assistant",
|
|
34820
|
+
createBlueprint(config) {
|
|
34821
|
+
return createBaseBlueprint({
|
|
34822
|
+
id: "rag-knowledge-assistant",
|
|
34823
|
+
name: "RAG Knowledge Assistant",
|
|
34824
|
+
description: "Assistant that answers from a configured knowledge base and cites retrieved sources.",
|
|
34825
|
+
surface: "web",
|
|
34826
|
+
defaultMode: "ask",
|
|
34827
|
+
maturity: "experimental",
|
|
34828
|
+
instructions: [
|
|
34829
|
+
`You are a knowledge assistant for ${config.brand}.`,
|
|
34830
|
+
"Answer only from retrieved or approved knowledge.",
|
|
34831
|
+
"Cite source titles when using retrieved content.",
|
|
34832
|
+
"If the answer is not in the available knowledge, say you do not know and suggest escalation.",
|
|
34833
|
+
config.extraInstructions ?? ""
|
|
34834
|
+
].filter(Boolean).join("\n"),
|
|
34835
|
+
allowedTools: config.retriever ? ["knowledge_search"] : []
|
|
34836
|
+
});
|
|
34837
|
+
},
|
|
34838
|
+
async createRuntime(config) {
|
|
34839
|
+
const blueprint = ragKnowledgeAssistantPreset.createBlueprint(config);
|
|
34840
|
+
return createPresetRuntime(config, blueprint, createRagToolRegistry(config.retriever));
|
|
34841
|
+
}
|
|
34842
|
+
};
|
|
34843
|
+
var supportRagAssistantPreset = {
|
|
34844
|
+
id: "support-rag-assistant",
|
|
34845
|
+
name: "Support RAG Assistant",
|
|
34846
|
+
createBlueprint(config) {
|
|
34847
|
+
const allowedTools = [];
|
|
34848
|
+
if (config.retriever) allowedTools.push("knowledge_search");
|
|
34849
|
+
if (config.supportDraft) allowedTools.push("create_support_draft");
|
|
34850
|
+
if (config.humanEscalation) allowedTools.push("request_human_escalation");
|
|
34851
|
+
return createBaseBlueprint({
|
|
34852
|
+
id: "support-rag-assistant",
|
|
34853
|
+
name: "Support RAG Assistant",
|
|
34854
|
+
description: "Support assistant that answers from approved knowledge, drafts responses, and escalates uncertain cases.",
|
|
34855
|
+
surface: "web",
|
|
34856
|
+
defaultMode: "draft",
|
|
34857
|
+
maturity: "experimental",
|
|
34858
|
+
instructions: [
|
|
34859
|
+
`You are a support assistant for ${config.brand}.`,
|
|
34860
|
+
"Answer only from approved retrieved knowledge.",
|
|
34861
|
+
"Cite source titles when using retrieved content.",
|
|
34862
|
+
"If retrieval is weak or the case is sensitive, say you are unsure and prepare an escalation.",
|
|
34863
|
+
"Never claim a ticket was created, closed, or escalated unless a registered tool result proves it.",
|
|
34864
|
+
config.extraInstructions ?? ""
|
|
34865
|
+
].filter(Boolean).join("\n"),
|
|
34866
|
+
allowedTools,
|
|
34867
|
+
approval: { requireHumanForExternalActions: true, requireHumanForSensitiveData: true }
|
|
34868
|
+
});
|
|
34869
|
+
},
|
|
34870
|
+
async createRuntime(config) {
|
|
34871
|
+
const blueprint = supportRagAssistantPreset.createBlueprint(config);
|
|
34872
|
+
return createPresetRuntime(
|
|
34873
|
+
config,
|
|
34874
|
+
blueprint,
|
|
34875
|
+
createSupportRagToolRegistry({
|
|
34876
|
+
retriever: config.retriever,
|
|
34877
|
+
supportDraft: config.supportDraft,
|
|
34878
|
+
humanEscalation: config.humanEscalation
|
|
34879
|
+
}),
|
|
34880
|
+
createToolCallingRuntimeTurnRunner()
|
|
34881
|
+
);
|
|
34882
|
+
}
|
|
34883
|
+
};
|
|
34884
|
+
var salesIntakeAssistantPreset = {
|
|
34885
|
+
id: "sales-intake-assistant",
|
|
34886
|
+
name: "Sales Intake Assistant",
|
|
34887
|
+
createBlueprint(config) {
|
|
34888
|
+
return createBaseBlueprint({
|
|
34889
|
+
id: "sales-intake-assistant",
|
|
34890
|
+
name: "Sales Intake Assistant",
|
|
34891
|
+
description: "Assistant for lead qualification, project context, urgency, budget, and next step capture.",
|
|
34892
|
+
surface: "web",
|
|
34893
|
+
defaultMode: "ask",
|
|
34894
|
+
maturity: "experimental",
|
|
34895
|
+
instructions: [
|
|
34896
|
+
`You are the sales intake assistant for ${config.brand}.`,
|
|
34897
|
+
"Collect problem, desired outcome, urgency, approximate budget, current stack, decision process, and contact preference.",
|
|
34898
|
+
"Keep the conversation concise and useful. Produce a clear summary and recommended next step when enough context is available.",
|
|
34899
|
+
"Do not promise pricing, timelines, or delivery commitments.",
|
|
34900
|
+
"Use create_sales_lead_summary only to prepare an internal summary; do not claim a CRM record was created.",
|
|
34901
|
+
config.extraInstructions ?? ""
|
|
34902
|
+
].filter(Boolean).join("\n"),
|
|
34903
|
+
allowedTools: config.leadSummary ? ["create_sales_lead_summary"] : []
|
|
34904
|
+
});
|
|
34905
|
+
},
|
|
34906
|
+
async createRuntime(config) {
|
|
34907
|
+
return createPresetRuntime(
|
|
34908
|
+
config,
|
|
34909
|
+
salesIntakeAssistantPreset.createBlueprint(config),
|
|
34910
|
+
createSalesIntakeToolRegistry({ leadSummary: config.leadSummary }),
|
|
34911
|
+
createToolCallingRuntimeTurnRunner()
|
|
34912
|
+
);
|
|
34913
|
+
}
|
|
34914
|
+
};
|
|
34915
|
+
var customerSupportAssistantPreset = {
|
|
34916
|
+
id: "customer-support-assistant",
|
|
34917
|
+
name: "Customer Support Assistant",
|
|
34918
|
+
createBlueprint(config) {
|
|
34919
|
+
return createBaseBlueprint({
|
|
34920
|
+
id: "customer-support-assistant",
|
|
34921
|
+
name: "Customer Support Assistant",
|
|
34922
|
+
description: "Assistant for support triage, answer drafts, and escalation recommendations.",
|
|
34923
|
+
surface: "web",
|
|
34924
|
+
defaultMode: "draft",
|
|
34925
|
+
maturity: "experimental",
|
|
34926
|
+
instructions: [
|
|
34927
|
+
`You are the customer support assistant for ${config.brand}.`,
|
|
34928
|
+
"Classify the issue, suggest a helpful answer, and escalate sensitive or uncertain cases to a human.",
|
|
34929
|
+
"Do not close tickets or make account changes without explicit approval and a registered tool result.",
|
|
34930
|
+
config.extraInstructions ?? ""
|
|
34931
|
+
].filter(Boolean).join("\n"),
|
|
34932
|
+
allowedTools: []
|
|
34933
|
+
});
|
|
34934
|
+
},
|
|
34935
|
+
async createRuntime(config) {
|
|
34936
|
+
return createPresetRuntime(
|
|
34937
|
+
config,
|
|
34938
|
+
customerSupportAssistantPreset.createBlueprint(config),
|
|
34939
|
+
createCustomerSupportToolRegistry(config.toolRegistry)
|
|
34940
|
+
);
|
|
34941
|
+
}
|
|
34942
|
+
};
|
|
34943
|
+
var appointmentBookingAssistantPreset = {
|
|
34944
|
+
id: "appointment-booking-assistant",
|
|
34945
|
+
name: "Appointment Booking Assistant",
|
|
34946
|
+
createBlueprint(config) {
|
|
34947
|
+
return createBaseBlueprint({
|
|
34948
|
+
id: "appointment-booking-assistant",
|
|
34949
|
+
name: "Appointment Booking Assistant",
|
|
34950
|
+
description: "Assistant for appointment intake, availability discussion, and confirmation-gated booking.",
|
|
34951
|
+
surface: "web",
|
|
34952
|
+
defaultMode: "draft",
|
|
34953
|
+
maturity: "experimental",
|
|
34954
|
+
instructions: [
|
|
34955
|
+
`You are the appointment assistant for ${config.brand}.`,
|
|
34956
|
+
config.businessHours ? `Business hours: ${config.businessHours}.` : "",
|
|
34957
|
+
"Collect preferred time, timezone, purpose, and contact details.",
|
|
34958
|
+
"Never book, cancel, or move an appointment without explicit user confirmation and an approved tool call.",
|
|
34959
|
+
config.extraInstructions ?? ""
|
|
34960
|
+
].filter(Boolean).join("\n"),
|
|
34961
|
+
allowedTools: []
|
|
34962
|
+
});
|
|
34963
|
+
},
|
|
34964
|
+
async createRuntime(config) {
|
|
34965
|
+
return createPresetRuntime(config, appointmentBookingAssistantPreset.createBlueprint(config));
|
|
34966
|
+
}
|
|
34967
|
+
};
|
|
34968
|
+
var internalOpsAssistantPreset = {
|
|
34969
|
+
id: "internal-ops-assistant",
|
|
34970
|
+
name: "Internal Ops Assistant",
|
|
34971
|
+
createBlueprint(config) {
|
|
34972
|
+
return createBaseBlueprint({
|
|
34973
|
+
id: "internal-ops-assistant",
|
|
34974
|
+
name: "Internal Ops Assistant",
|
|
34975
|
+
description: "Internal automation assistant for controlled operations workflows.",
|
|
34976
|
+
surface: "internal",
|
|
34977
|
+
defaultMode: "draft",
|
|
34978
|
+
maturity: "experimental",
|
|
34979
|
+
instructions: [
|
|
34980
|
+
`You are an internal operations assistant for ${config.brand}.`,
|
|
34981
|
+
"Prefer drafts and summaries before actions. Ask for confirmation before external side effects.",
|
|
34982
|
+
"Use create_internal_ops_draft for controlled planning only. Do not execute ERP, CRM, billing, or account changes unless a separate allowlisted tool exists.",
|
|
34983
|
+
"Follow the configured tool policy and record decisions for audit.",
|
|
34984
|
+
config.extraInstructions ?? ""
|
|
34985
|
+
].filter(Boolean).join("\n"),
|
|
34986
|
+
allowedTools: config.opsDraft ? ["create_internal_ops_draft"] : [],
|
|
34987
|
+
approval: { requireHumanForExternalActions: true, requireHumanForSensitiveData: true }
|
|
34988
|
+
});
|
|
34989
|
+
},
|
|
34990
|
+
async createRuntime(config) {
|
|
34991
|
+
return createPresetRuntime(
|
|
34992
|
+
config,
|
|
34993
|
+
internalOpsAssistantPreset.createBlueprint(config),
|
|
34994
|
+
createInternalOpsToolRegistry({ opsDraft: config.opsDraft }),
|
|
34995
|
+
createToolCallingRuntimeTurnRunner()
|
|
34996
|
+
);
|
|
34997
|
+
}
|
|
34998
|
+
};
|
|
34999
|
+
var codingAgentPreset = {
|
|
35000
|
+
id: "coding-agent",
|
|
35001
|
+
name: "Coco Coding Agent",
|
|
35002
|
+
createBlueprint(config) {
|
|
35003
|
+
return createBaseBlueprint({
|
|
35004
|
+
id: "coding-agent",
|
|
35005
|
+
name: "Coco Coding Agent",
|
|
35006
|
+
description: "Coco's full coding-agent surface for trusted developer environments.",
|
|
35007
|
+
surface: "cli",
|
|
35008
|
+
defaultMode: "act",
|
|
35009
|
+
maturity: "beta",
|
|
35010
|
+
instructions: config.extraInstructions ?? "You are Coco, a coding agent for trusted repositories.",
|
|
35011
|
+
allowedTools: [],
|
|
35012
|
+
guardrails: { secretRedaction: { enabled: true }, promptInjectionDetection: true },
|
|
35013
|
+
approval: { requireHumanForExternalActions: true, requireHumanForSensitiveData: true }
|
|
35014
|
+
});
|
|
35015
|
+
},
|
|
35016
|
+
async createRuntime(config) {
|
|
35017
|
+
return createPresetRuntime(
|
|
35018
|
+
config,
|
|
35019
|
+
codingAgentPreset.createBlueprint(config),
|
|
35020
|
+
createCodingToolRegistry()
|
|
35021
|
+
);
|
|
35022
|
+
}
|
|
35023
|
+
};
|
|
35024
|
+
async function createPresetRuntime(config, blueprint, fallbackToolRegistry = createNoToolRegistry(), fallbackTurnRunner = config.turnRunner) {
|
|
35025
|
+
return createAgentRuntime({
|
|
35026
|
+
providerType: config.providerType,
|
|
35027
|
+
model: config.model,
|
|
35028
|
+
providerConfig: config.providerConfig,
|
|
35029
|
+
provider: config.provider,
|
|
35030
|
+
eventLog: config.eventLog,
|
|
35031
|
+
turnRunner: config.turnRunner ?? fallbackTurnRunner,
|
|
35032
|
+
toolRegistry: blueprint.id === "coding-agent" ? config.toolRegistry ?? fallbackToolRegistry : config.toolRegistry ? createSafeToolRegistry(blueprint.allowedTools, config.toolRegistry) : fallbackToolRegistry,
|
|
35033
|
+
publishToGlobalBridge: false
|
|
35034
|
+
});
|
|
35035
|
+
}
|
|
35036
|
+
var AGENT_PRESETS = [
|
|
35037
|
+
publicWebsiteAssistantPreset,
|
|
35038
|
+
ragKnowledgeAssistantPreset,
|
|
35039
|
+
supportRagAssistantPreset,
|
|
35040
|
+
salesIntakeAssistantPreset,
|
|
35041
|
+
customerSupportAssistantPreset,
|
|
35042
|
+
appointmentBookingAssistantPreset,
|
|
35043
|
+
internalOpsAssistantPreset,
|
|
35044
|
+
codingAgentPreset
|
|
35045
|
+
];
|
|
35046
|
+
|
|
35047
|
+
// src/adapters/index.ts
|
|
35048
|
+
function createHttpAssistantAdapter(runtime) {
|
|
35049
|
+
return {
|
|
35050
|
+
createSession(metadata = {}) {
|
|
35051
|
+
const session = runtime.createSession({ mode: "ask", metadata });
|
|
35052
|
+
return { sessionId: session.id };
|
|
35053
|
+
},
|
|
35054
|
+
async handleMessage(input) {
|
|
35055
|
+
const sessionId = input.sessionId ?? runtime.createSession({ mode: "ask", metadata: input.metadata }).id;
|
|
35056
|
+
const result = await runtime.runTurn({
|
|
35057
|
+
sessionId,
|
|
35058
|
+
content: input.content,
|
|
35059
|
+
metadata: input.metadata
|
|
35060
|
+
});
|
|
35061
|
+
return { sessionId, content: result.content, metadata: { model: result.model } };
|
|
35062
|
+
}
|
|
35063
|
+
};
|
|
35064
|
+
}
|
|
35065
|
+
function createStreamingHttpAssistantAdapter(runtime) {
|
|
35066
|
+
const base = createHttpAssistantAdapter(runtime);
|
|
35067
|
+
return {
|
|
35068
|
+
...base,
|
|
35069
|
+
async *streamMessage(input) {
|
|
35070
|
+
const sessionId = input.sessionId ?? runtime.createSession({ mode: "ask", metadata: input.metadata }).id;
|
|
35071
|
+
yield* runtime.streamTurn({
|
|
35072
|
+
sessionId,
|
|
35073
|
+
content: input.content,
|
|
35074
|
+
metadata: input.metadata
|
|
35075
|
+
});
|
|
35076
|
+
}
|
|
35077
|
+
};
|
|
35078
|
+
}
|
|
35079
|
+
function createWebhookAssistantAdapter(runtime, options = {}) {
|
|
35080
|
+
return {
|
|
35081
|
+
id: options.id ?? "webhook-assistant",
|
|
35082
|
+
surface: options.surface ?? "api",
|
|
35083
|
+
async handle(input) {
|
|
35084
|
+
const adapter = createHttpAssistantAdapter(runtime);
|
|
35085
|
+
return adapter.handleMessage(input);
|
|
35086
|
+
}
|
|
35087
|
+
};
|
|
35088
|
+
}
|
|
35089
|
+
|
|
33291
35090
|
// src/index.ts
|
|
33292
35091
|
init_errors();
|
|
33293
35092
|
init_logger();
|
|
33294
35093
|
init_proxy();
|
|
33295
35094
|
|
|
33296
|
-
export { ADRGenerator, AGENT_MODES, AgentRuntime, AnthropicProvider, ArchitectureGenerator, BacklogGenerator, CICDGenerator, CocoError, CodeGenerator, CodeReviewer, CompleteExecutor, ConfigError, ConvergeExecutor, DEFAULT_WORKFLOWS, DefaultPermissionPolicy, DefaultRuntimeTurnRunner, DiscoveryEngine, DockerGenerator, DocsGenerator, FileEventLog, FileRuntimeSessionStore, InMemoryEventLog, InMemoryRuntimeSessionStore, OrchestrateExecutor, OutputExecutor, PhaseError, ProviderRegistry, SessionManager, SpecificationGenerator, TaskError, TaskIterator, ToolRegistry, VERSION, WorkflowCatalog, WorkflowEngine, WorkflowRegistry, configExists, createADRGenerator, createAgentRuntime, createAnthropicProvider, createArchitectureGenerator, createBacklogGenerator, createCICDGenerator, createCodeGenerator, createCodeReviewer, createCompleteExecutor, createConvergeExecutor, createDefaultConfig, createDefaultRuntimeTurnRunner, createDiscoveryEngine, createDockerGenerator, createDocsGenerator, createEventLog, createFileEventLog, createFileRuntimeSessionStore, createFullToolRegistry, createLogger, createMcpToolPolicy, createOrchestrateExecutor, createOrchestrator, createOutputExecutor, createPermissionPolicy, createProvider, createProviderRegistry, createRuntimeHttpServer, createRuntimeSessionStore, createSessionManager, createSpecificationGenerator, createTaskIterator, createToolRegistry, createWorkflowCatalog, createWorkflowEngine, createWorkflowRegistry, getAgentMode, installProxyDispatcher, isAgentMode, listAgentModes, loadConfig, registerAllTools, saveConfig };
|
|
35095
|
+
export { ADRGenerator, AGENT_MODES, AGENT_PRESETS, AgentGraphEngine, AgentRunner, AgentRuntime, AnthropicProvider, ArchitectureGenerator, BacklogGenerator, CICDGenerator, CocoError, CodeGenerator, CodeReviewer, CompleteExecutor, ConfigError, ConvergeExecutor, DEFAULT_WORKFLOWS, DefaultPermissionPolicy, DefaultRuntimeTurnRunner, DiscoveryEngine, DockerGenerator, DocsGenerator, FileEventLog, FileRuntimeSessionStore, FileSharedWorkspaceStore, InMemoryEventLog, InMemoryKnowledgeRetriever, InMemoryRuntimeSessionStore, InMemorySharedWorkspaceStore, OrchestrateExecutor, OutputExecutor, PhaseError, ProviderRegistry, SessionManager, SharedWorkspaceState, SpecificationGenerator, TaskError, TaskIterator, ToolCallingRuntimeTurnRunner, ToolRegistry, VERSION, WorkflowCatalog, WorkflowEngine, WorkflowRegistry, appointmentBookingAssistantPreset, codingAgentPreset, configExists, createADRGenerator, createAgentArtifact, createAgentFromBlueprint, createAgentGraphEngine, createAgentRunner, createAgentRuntime, createAgentTraceContext, createAnthropicProvider, createArchitectureGenerator, createBacklogGenerator, createBaseBlueprint, createCICDGenerator, createCodeGenerator, createCodeReviewer, createCodingToolRegistry, createCompleteExecutor, createConvergeExecutor, createCustomerSupportToolRegistry, createDefaultConfig, createDefaultRuntimeTurnRunner, createDiscoveryEngine, createDockerGenerator, createDocsGenerator, createEventLog, createFileEventLog, createFileRuntimeSessionStore, createFullToolRegistry, createHttpAssistantAdapter, createInMemoryKnowledgeRetriever, createLogger, createMcpToolPolicy, createNoToolRegistry, createOrchestrateExecutor, createOrchestrator, createOutputExecutor, createPermissionPolicy, createProvider, createProviderRegistry, createPublicWebToolRegistry, createRagToolRegistry, createRuntimeHttpServer, createRuntimeSessionStore, createSafeToolRegistry, createSessionManager, createSpecificationGenerator, createStreamingHttpAssistantAdapter, createSummaryArtifact, createSupportRagToolRegistry, createTaskIterator, createToolCallingRuntimeTurnRunner, createToolRegistry, createWebhookAssistantAdapter, createWorkflowCatalog, createWorkflowEngine, createWorkflowRegistry, customerSupportAssistantPreset, defaultPublicGuardrails, evaluateAgentToolPolicy, formatRetrievedSourcesForPrompt, getAgentMode, installProxyDispatcher, internalOpsAssistantPreset, isAgentMode, listAgentModes, listLegacyAgentRoleMappings, loadConfig, mapActionModeToRuntimeMode, mapLegacyAgentRole, normalizeAgentRunResult, publicWebsiteAssistantPreset, ragKnowledgeAssistantPreset, redactSecrets, registerAllTools, runGuardrails, salesIntakeAssistantPreset, saveConfig, supportRagAssistantPreset, validateAgentCapabilities, validateAgentGraph, validateStructuredOutput, workflowToAgentGraph };
|
|
33297
35096
|
//# sourceMappingURL=index.js.map
|
|
33298
35097
|
//# sourceMappingURL=index.js.map
|