@corbat-tech/coco 2.39.0 → 2.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/index.d.ts +15 -3
- package/dist/adapters/index.js +21 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/agent-runtime-Cd6pB640.d.ts +53 -0
- package/dist/{blueprints-DYgm3K65.d.ts → blueprints-Dmdaw6_I.d.ts} +4 -2
- package/dist/cli/index.js +974 -342
- package/dist/cli/index.js.map +1 -1
- package/dist/{index-Dp1o8c9g.d.ts → index-BD5_a3Q8.d.ts} +2 -2
- package/dist/index.d.ts +10 -10
- package/dist/index.js +7675 -8101
- package/dist/index.js.map +1 -1
- package/dist/presets/index.d.ts +5 -5
- package/dist/presets/index.js +22243 -22921
- package/dist/presets/index.js.map +1 -1
- package/dist/{profiles-BcyL-gQ9.d.ts → profiles-BA9dvyaF.d.ts} +6 -3
- package/dist/rag-D-Zo1oyo.d.ts +112 -0
- package/dist/runtime/index.d.ts +7 -7
- package/dist/runtime/index.js +6459 -23994
- package/dist/runtime/index.js.map +1 -1
- package/dist/{extension-manifests-CAQQILhE.d.ts → runtime-tool-executor-L5i8QWzn.d.ts} +30 -3
- package/dist/tools/index.d.ts +4 -4
- package/dist/tools/index.js +9 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/{agent-runtime-DJY9FzL_.d.ts → workflow-engine-DleSoUhy.d.ts} +383 -249
- package/package.json +1 -1
- package/dist/rag-BakFRE-u.d.ts +0 -31
- package/dist/registry-CEpl9Jq0.d.ts +0 -115
package/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { execFileSync,
|
|
2
|
+
import { execFileSync, execSync, spawn, execFile, exec } from 'child_process';
|
|
3
3
|
import { setGlobalDispatcher, EnvHttpProxyAgent } from 'undici';
|
|
4
4
|
import * as fs5 from 'fs';
|
|
5
5
|
import fs5__default, { accessSync, mkdirSync, appendFileSync, readFileSync, writeFileSync, constants as constants$1 } from 'fs';
|
|
@@ -23,7 +23,7 @@ import Anthropic from '@anthropic-ai/sdk';
|
|
|
23
23
|
import { jsonrepair } from 'jsonrepair';
|
|
24
24
|
import OpenAI from 'openai';
|
|
25
25
|
import { GoogleGenAI, FunctionCallingConfigMode } from '@google/genai';
|
|
26
|
-
import { parse } from 'yaml';
|
|
26
|
+
import { parse as parse$1 } from 'yaml';
|
|
27
27
|
import { minimatch } from 'minimatch';
|
|
28
28
|
import hljs from 'highlight.js/lib/core';
|
|
29
29
|
import bash from 'highlight.js/lib/languages/bash';
|
|
@@ -42,7 +42,7 @@ import yaml from 'highlight.js/lib/languages/yaml';
|
|
|
42
42
|
import { diffLines, diffWords } from 'diff';
|
|
43
43
|
import { glob } from 'glob';
|
|
44
44
|
import { execa } from 'execa';
|
|
45
|
-
import { parse
|
|
45
|
+
import { parse } from '@typescript-eslint/typescript-estree';
|
|
46
46
|
import { simpleGit } from 'simple-git';
|
|
47
47
|
import { Marked } from 'marked';
|
|
48
48
|
import { markedTerminal } from 'marked-terminal';
|
|
@@ -10061,7 +10061,7 @@ function parseSkillMarkdown(raw) {
|
|
|
10061
10061
|
const frontmatter = normalized.slice(3, closeIndex).trim();
|
|
10062
10062
|
const afterMarkerStart = closeIndex + closeMarker.length;
|
|
10063
10063
|
const contentStart = normalized[afterMarkerStart] === "\n" ? afterMarkerStart + 1 : afterMarkerStart;
|
|
10064
|
-
const parsed = frontmatter.length > 0 ? parse(frontmatter) : {};
|
|
10064
|
+
const parsed = frontmatter.length > 0 ? parse$1(frontmatter) : {};
|
|
10065
10065
|
return {
|
|
10066
10066
|
data: parsed && typeof parsed === "object" ? parsed : {},
|
|
10067
10067
|
content: normalized.slice(contentStart)
|
|
@@ -15465,7 +15465,7 @@ var init_complexity = __esm({
|
|
|
15465
15465
|
* Analyze single file
|
|
15466
15466
|
*/
|
|
15467
15467
|
async analyzeFile(file, content) {
|
|
15468
|
-
const ast = parse
|
|
15468
|
+
const ast = parse(content, {
|
|
15469
15469
|
loc: true,
|
|
15470
15470
|
range: true,
|
|
15471
15471
|
comment: false,
|
|
@@ -16062,7 +16062,7 @@ var init_completeness = __esm({
|
|
|
16062
16062
|
for (const file of files) {
|
|
16063
16063
|
try {
|
|
16064
16064
|
const content = await readFile(file, "utf-8");
|
|
16065
|
-
const ast = parse
|
|
16065
|
+
const ast = parse(content, {
|
|
16066
16066
|
loc: true,
|
|
16067
16067
|
range: true,
|
|
16068
16068
|
jsx: file.endsWith(".tsx") || file.endsWith(".jsx")
|
|
@@ -16275,7 +16275,7 @@ var init_robustness = __esm({
|
|
|
16275
16275
|
for (const file of targetFiles) {
|
|
16276
16276
|
try {
|
|
16277
16277
|
const content = await readFile(file, "utf-8");
|
|
16278
|
-
const ast = parse
|
|
16278
|
+
const ast = parse(content, {
|
|
16279
16279
|
loc: true,
|
|
16280
16280
|
range: true,
|
|
16281
16281
|
jsx: file.endsWith(".tsx") || file.endsWith(".jsx")
|
|
@@ -16568,7 +16568,7 @@ var init_documentation = __esm({
|
|
|
16568
16568
|
for (const file of targetFiles) {
|
|
16569
16569
|
try {
|
|
16570
16570
|
const content = await readFile(file, "utf-8");
|
|
16571
|
-
const ast = parse
|
|
16571
|
+
const ast = parse(content, {
|
|
16572
16572
|
loc: true,
|
|
16573
16573
|
range: true,
|
|
16574
16574
|
comment: true,
|
|
@@ -16946,7 +16946,7 @@ var init_readability = __esm({
|
|
|
16946
16946
|
for (const file of targetFiles) {
|
|
16947
16947
|
try {
|
|
16948
16948
|
const content = await readFile(file, "utf-8");
|
|
16949
|
-
const ast = parse
|
|
16949
|
+
const ast = parse(content, {
|
|
16950
16950
|
loc: true,
|
|
16951
16951
|
range: true,
|
|
16952
16952
|
jsx: file.endsWith(".tsx") || file.endsWith(".jsx")
|
|
@@ -17104,7 +17104,7 @@ var init_maintainability = __esm({
|
|
|
17104
17104
|
try {
|
|
17105
17105
|
const content = await readFile(file, "utf-8");
|
|
17106
17106
|
const lineCount = countLines(content);
|
|
17107
|
-
const ast = parse
|
|
17107
|
+
const ast = parse(content, {
|
|
17108
17108
|
loc: true,
|
|
17109
17109
|
range: true,
|
|
17110
17110
|
jsx: file.endsWith(".tsx") || file.endsWith(".jsx")
|
|
@@ -43310,7 +43310,7 @@ var InMemorySharedWorkspaceStore = class {
|
|
|
43310
43310
|
write(input) {
|
|
43311
43311
|
assertProvenance(input.provenance);
|
|
43312
43312
|
const record = {
|
|
43313
|
-
id: `state-${randomUUID()}`,
|
|
43313
|
+
id: input.id ?? `state-${randomUUID()}`,
|
|
43314
43314
|
kind: input.kind,
|
|
43315
43315
|
key: input.key,
|
|
43316
43316
|
value: cloneUnknown(input.value),
|
|
@@ -43353,7 +43353,7 @@ var AgentGraphEngine = class {
|
|
|
43353
43353
|
constructor(options = {}) {
|
|
43354
43354
|
this.eventLog = options.eventLog;
|
|
43355
43355
|
this.sharedState = options.sharedState ?? new InMemorySharedWorkspaceStore();
|
|
43356
|
-
this.nodeExecutor = options.nodeExecutor ??
|
|
43356
|
+
this.nodeExecutor = options.nodeExecutor ?? (options.allowSimulated ? dryRunAgentGraphNodeExecutor : missingAgentGraphNodeExecutor);
|
|
43357
43357
|
this.gateEvaluator = options.gateEvaluator ?? defaultAgentGateEvaluator;
|
|
43358
43358
|
this.trace = options.trace ?? createAgentTraceContext();
|
|
43359
43359
|
}
|
|
@@ -43437,6 +43437,39 @@ var AgentGraphEngine = class {
|
|
|
43437
43437
|
}
|
|
43438
43438
|
}
|
|
43439
43439
|
async executeNode(input) {
|
|
43440
|
+
const skipReason = shouldSkipNode(input.node, input.graph, input.input, input.nodeResults);
|
|
43441
|
+
if (skipReason) {
|
|
43442
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
43443
|
+
const task = graphNodeToTask(input.node, input.input);
|
|
43444
|
+
const skipped = normalizeAgentRunResult({
|
|
43445
|
+
id: `${input.workflowRunId}-${input.node.id}-skipped`,
|
|
43446
|
+
taskId: task.id,
|
|
43447
|
+
role: task.role,
|
|
43448
|
+
success: true,
|
|
43449
|
+
status: "cancelled",
|
|
43450
|
+
output: `Skipped node '${input.node.id}': ${skipReason}`,
|
|
43451
|
+
startedAt: completedAt,
|
|
43452
|
+
completedAt,
|
|
43453
|
+
durationMs: 0,
|
|
43454
|
+
metadata: {
|
|
43455
|
+
workflowRunId: input.workflowRunId,
|
|
43456
|
+
nodeId: input.node.id,
|
|
43457
|
+
skipped: true,
|
|
43458
|
+
skipReason
|
|
43459
|
+
}
|
|
43460
|
+
});
|
|
43461
|
+
this.eventLog?.record("agent.completed", {
|
|
43462
|
+
workflowRunId: input.workflowRunId,
|
|
43463
|
+
nodeId: input.node.id,
|
|
43464
|
+
agentRunId: skipped.id,
|
|
43465
|
+
taskId: task.id,
|
|
43466
|
+
role: skipped.role,
|
|
43467
|
+
skipped: true,
|
|
43468
|
+
reason: skipReason,
|
|
43469
|
+
trace: input.graphTrace
|
|
43470
|
+
});
|
|
43471
|
+
return skipped;
|
|
43472
|
+
}
|
|
43440
43473
|
const attempts = input.node.retryPolicy?.maxAttempts ?? 1;
|
|
43441
43474
|
let lastResult;
|
|
43442
43475
|
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
@@ -43455,19 +43488,40 @@ var AgentGraphEngine = class {
|
|
|
43455
43488
|
attempt,
|
|
43456
43489
|
trace
|
|
43457
43490
|
});
|
|
43458
|
-
const result = await
|
|
43459
|
-
|
|
43460
|
-
|
|
43461
|
-
|
|
43462
|
-
|
|
43463
|
-
|
|
43464
|
-
|
|
43465
|
-
|
|
43466
|
-
|
|
43467
|
-
|
|
43491
|
+
const result = await runWithOptionalTimeout(
|
|
43492
|
+
this.nodeExecutor({
|
|
43493
|
+
node: input.node,
|
|
43494
|
+
task,
|
|
43495
|
+
attempt,
|
|
43496
|
+
workflowRunId: input.workflowRunId,
|
|
43497
|
+
trace,
|
|
43498
|
+
dependencyResults: input.nodeResults,
|
|
43499
|
+
sharedState: this.sharedState,
|
|
43500
|
+
eventLog: this.eventLog ?? NULL_EVENT_LOG
|
|
43501
|
+
}),
|
|
43502
|
+
input.node.timeoutMs,
|
|
43503
|
+
() => normalizeAgentRunResult({
|
|
43504
|
+
id: `${input.workflowRunId}-${input.node.id}-attempt-${attempt}-timeout`,
|
|
43505
|
+
taskId: task.id,
|
|
43506
|
+
role: task.role,
|
|
43507
|
+
success: false,
|
|
43508
|
+
status: "timeout",
|
|
43509
|
+
output: "",
|
|
43510
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
43511
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
43512
|
+
durationMs: input.node.timeoutMs ?? 0,
|
|
43513
|
+
error: `Node '${input.node.id}' timed out after ${input.node.timeoutMs}ms.`,
|
|
43514
|
+
metadata: {
|
|
43515
|
+
workflowRunId: input.workflowRunId,
|
|
43516
|
+
nodeId: input.node.id,
|
|
43517
|
+
trace,
|
|
43518
|
+
timeoutMs: input.node.timeoutMs
|
|
43519
|
+
}
|
|
43520
|
+
})
|
|
43521
|
+
);
|
|
43468
43522
|
lastResult = result;
|
|
43469
43523
|
for (const artifact of result.artifacts) {
|
|
43470
|
-
this.sharedState.write({
|
|
43524
|
+
const record = this.sharedState.write({
|
|
43471
43525
|
kind: "artifact",
|
|
43472
43526
|
key: artifact.id,
|
|
43473
43527
|
value: artifact,
|
|
@@ -43479,6 +43533,15 @@ var AgentGraphEngine = class {
|
|
|
43479
43533
|
risk: input.node.risk
|
|
43480
43534
|
}
|
|
43481
43535
|
});
|
|
43536
|
+
this.eventLog?.record("shared_state.updated", {
|
|
43537
|
+
workflowRunId: input.workflowRunId,
|
|
43538
|
+
nodeId: input.node.id,
|
|
43539
|
+
agentRunId: result.id,
|
|
43540
|
+
recordId: record.id,
|
|
43541
|
+
kind: record.kind,
|
|
43542
|
+
key: record.key,
|
|
43543
|
+
trace
|
|
43544
|
+
});
|
|
43482
43545
|
this.eventLog?.record("agent.artifact.created", {
|
|
43483
43546
|
workflowRunId: input.workflowRunId,
|
|
43484
43547
|
nodeId: input.node.id,
|
|
@@ -43499,6 +43562,14 @@ var AgentGraphEngine = class {
|
|
|
43499
43562
|
attempt,
|
|
43500
43563
|
trace
|
|
43501
43564
|
});
|
|
43565
|
+
this.eventLog?.record("checkpoint.created", {
|
|
43566
|
+
workflowRunId: input.workflowRunId,
|
|
43567
|
+
nodeId: input.node.id,
|
|
43568
|
+
agentRunId: result.id,
|
|
43569
|
+
taskId: task.id,
|
|
43570
|
+
attempt,
|
|
43571
|
+
trace
|
|
43572
|
+
});
|
|
43502
43573
|
return result;
|
|
43503
43574
|
}
|
|
43504
43575
|
this.eventLog?.record("agent.failed", {
|
|
@@ -43712,7 +43783,7 @@ function graphNodeToTask(node, workflowInput) {
|
|
|
43712
43783
|
constraints: node.requiredTools?.map((tool) => `Requires tool: ${tool}`)
|
|
43713
43784
|
};
|
|
43714
43785
|
}
|
|
43715
|
-
async function
|
|
43786
|
+
async function dryRunAgentGraphNodeExecutor(execution) {
|
|
43716
43787
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
43717
43788
|
const dependencyOutputs = Object.fromEntries(
|
|
43718
43789
|
[...execution.dependencyResults.entries()].map(([id, result]) => [
|
|
@@ -43744,10 +43815,36 @@ async function defaultAgentGraphNodeExecutor(execution) {
|
|
|
43744
43815
|
}
|
|
43745
43816
|
});
|
|
43746
43817
|
}
|
|
43818
|
+
async function missingAgentGraphNodeExecutor(execution) {
|
|
43819
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
43820
|
+
return normalizeAgentRunResult({
|
|
43821
|
+
id: `${execution.workflowRunId}-${execution.node.id}-missing-executor`,
|
|
43822
|
+
taskId: execution.task.id,
|
|
43823
|
+
role: execution.task.role,
|
|
43824
|
+
success: false,
|
|
43825
|
+
output: "",
|
|
43826
|
+
startedAt: completedAt,
|
|
43827
|
+
completedAt,
|
|
43828
|
+
durationMs: 0,
|
|
43829
|
+
error: "AgentGraphEngine requires a nodeExecutor. Pass a real executor or set allowSimulated: true for dry-run/demo workflows.",
|
|
43830
|
+
metadata: {
|
|
43831
|
+
workflowRunId: execution.workflowRunId,
|
|
43832
|
+
nodeId: execution.node.id,
|
|
43833
|
+
trace: execution.trace,
|
|
43834
|
+
missingExecutor: true
|
|
43835
|
+
}
|
|
43836
|
+
});
|
|
43837
|
+
}
|
|
43747
43838
|
async function defaultAgentGateEvaluator(input) {
|
|
43748
43839
|
if (!input.result.success) {
|
|
43749
43840
|
return { passed: false, reason: "Agent result was not successful." };
|
|
43750
43841
|
}
|
|
43842
|
+
if (input.gate.kind === "tests" || input.gate.kind === "coverage" || input.gate.kind === "security" || input.gate.kind === "quality-score" || input.gate.kind === "human-approval") {
|
|
43843
|
+
return {
|
|
43844
|
+
passed: false,
|
|
43845
|
+
reason: `Gate '${input.gate.kind}' requires an explicit evaluator.`
|
|
43846
|
+
};
|
|
43847
|
+
}
|
|
43751
43848
|
return { passed: true };
|
|
43752
43849
|
}
|
|
43753
43850
|
function chunk(items, size) {
|
|
@@ -43758,6 +43855,71 @@ function chunk(items, size) {
|
|
|
43758
43855
|
}
|
|
43759
43856
|
return result;
|
|
43760
43857
|
}
|
|
43858
|
+
async function runWithOptionalTimeout(promise, timeoutMs, onTimeout) {
|
|
43859
|
+
if (!timeoutMs || timeoutMs <= 0) return promise;
|
|
43860
|
+
return Promise.race([
|
|
43861
|
+
promise,
|
|
43862
|
+
new Promise((resolve4) => {
|
|
43863
|
+
setTimeout(() => resolve4(onTimeout()), timeoutMs);
|
|
43864
|
+
})
|
|
43865
|
+
]);
|
|
43866
|
+
}
|
|
43867
|
+
function shouldSkipNode(node, graph, workflowInput, dependencyResults) {
|
|
43868
|
+
const nodeCondition = evaluateGraphCondition(node.condition, workflowInput, dependencyResults);
|
|
43869
|
+
if (!nodeCondition.passed) return nodeCondition.reason;
|
|
43870
|
+
for (const edge of graph.edges ?? []) {
|
|
43871
|
+
if (edge.to !== node.id || !edge.condition) continue;
|
|
43872
|
+
const edgeCondition = evaluateGraphCondition(edge.condition, workflowInput, dependencyResults);
|
|
43873
|
+
if (!edgeCondition.passed) {
|
|
43874
|
+
return `edge '${edge.from}' -> '${edge.to}' condition '${edge.condition}' was false`;
|
|
43875
|
+
}
|
|
43876
|
+
}
|
|
43877
|
+
return void 0;
|
|
43878
|
+
}
|
|
43879
|
+
function evaluateGraphCondition(condition, workflowInput, dependencyResults) {
|
|
43880
|
+
if (!condition || condition === "always") return { passed: true };
|
|
43881
|
+
if (condition === "never") return { passed: false, reason: "condition 'never' was false" };
|
|
43882
|
+
if (condition.startsWith("!input.")) {
|
|
43883
|
+
const path65 = condition.slice("!input.".length);
|
|
43884
|
+
return {
|
|
43885
|
+
passed: !readPath(workflowInput, path65),
|
|
43886
|
+
reason: `condition '${condition}' was false`
|
|
43887
|
+
};
|
|
43888
|
+
}
|
|
43889
|
+
if (condition.startsWith("input.")) {
|
|
43890
|
+
const path65 = condition.slice("input.".length);
|
|
43891
|
+
return {
|
|
43892
|
+
passed: Boolean(readPath(workflowInput, path65)),
|
|
43893
|
+
reason: `condition '${condition}' was false`
|
|
43894
|
+
};
|
|
43895
|
+
}
|
|
43896
|
+
if (condition.startsWith("dependency.") && condition.endsWith(".success")) {
|
|
43897
|
+
const id = condition.slice("dependency.".length, -".success".length);
|
|
43898
|
+
return {
|
|
43899
|
+
passed: dependencyResults.get(id)?.success === true,
|
|
43900
|
+
reason: `condition '${condition}' was false`
|
|
43901
|
+
};
|
|
43902
|
+
}
|
|
43903
|
+
if (condition.startsWith("dependency.") && condition.endsWith(".failed")) {
|
|
43904
|
+
const id = condition.slice("dependency.".length, -".failed".length);
|
|
43905
|
+
return {
|
|
43906
|
+
passed: dependencyResults.get(id)?.success === false,
|
|
43907
|
+
reason: `condition '${condition}' was false`
|
|
43908
|
+
};
|
|
43909
|
+
}
|
|
43910
|
+
return {
|
|
43911
|
+
passed: false,
|
|
43912
|
+
reason: `Unsupported graph condition '${condition}'.`
|
|
43913
|
+
};
|
|
43914
|
+
}
|
|
43915
|
+
function readPath(input, path65) {
|
|
43916
|
+
return path65.split(".").reduce((current, segment) => {
|
|
43917
|
+
if (current && typeof current === "object" && segment in current) {
|
|
43918
|
+
return current[segment];
|
|
43919
|
+
}
|
|
43920
|
+
return void 0;
|
|
43921
|
+
}, input);
|
|
43922
|
+
}
|
|
43761
43923
|
function cloneUnknown(value) {
|
|
43762
43924
|
if (value === void 0 || value === null) return value;
|
|
43763
43925
|
try {
|
|
@@ -43783,14 +43945,524 @@ function cloneArtifact(artifact) {
|
|
|
43783
43945
|
};
|
|
43784
43946
|
}
|
|
43785
43947
|
|
|
43948
|
+
// src/runtime/context.ts
|
|
43949
|
+
function createRuntimeRequestContext(input = {}) {
|
|
43950
|
+
return {
|
|
43951
|
+
surface: input.surface ?? "api",
|
|
43952
|
+
tenant: input.tenant ? { ...input.tenant, metadata: { ...input.tenant.metadata } } : void 0,
|
|
43953
|
+
user: input.user ? {
|
|
43954
|
+
...input.user,
|
|
43955
|
+
roles: [...input.user.roles ?? []],
|
|
43956
|
+
groups: [...input.user.groups ?? []],
|
|
43957
|
+
metadata: { ...input.user.metadata }
|
|
43958
|
+
} : void 0,
|
|
43959
|
+
channel: input.channel,
|
|
43960
|
+
correlationId: input.correlationId,
|
|
43961
|
+
policy: input.policy ? cloneRuntimePolicy(input.policy) : void 0,
|
|
43962
|
+
metadata: { ...input.metadata }
|
|
43963
|
+
};
|
|
43964
|
+
}
|
|
43965
|
+
function mergeRuntimePolicy(base, override) {
|
|
43966
|
+
if (!base && !override) return void 0;
|
|
43967
|
+
return {
|
|
43968
|
+
...base,
|
|
43969
|
+
...override,
|
|
43970
|
+
allowedTools: override?.allowedTools ? [...override.allowedTools] : base?.allowedTools ? [...base.allowedTools] : void 0,
|
|
43971
|
+
requireHumanApprovalFor: override?.requireHumanApprovalFor ? [...override.requireHumanApprovalFor] : base?.requireHumanApprovalFor ? [...base.requireHumanApprovalFor] : void 0,
|
|
43972
|
+
dataBoundary: { ...base?.dataBoundary, ...override?.dataBoundary },
|
|
43973
|
+
costBudget: { ...base?.costBudget, ...override?.costBudget },
|
|
43974
|
+
retention: { ...base?.retention, ...override?.retention },
|
|
43975
|
+
rateLimit: { ...base?.rateLimit, ...override?.rateLimit }
|
|
43976
|
+
};
|
|
43977
|
+
}
|
|
43978
|
+
function runtimeContextToMetadata(context) {
|
|
43979
|
+
if (!context) return {};
|
|
43980
|
+
return {
|
|
43981
|
+
surface: context.surface,
|
|
43982
|
+
channel: context.channel,
|
|
43983
|
+
correlationId: context.correlationId,
|
|
43984
|
+
tenantId: context.tenant?.id,
|
|
43985
|
+
tenantName: context.tenant?.name,
|
|
43986
|
+
userId: context.user?.id,
|
|
43987
|
+
userRoles: context.user?.roles,
|
|
43988
|
+
dataClassification: context.policy?.dataBoundary?.classification
|
|
43989
|
+
};
|
|
43990
|
+
}
|
|
43991
|
+
function evaluateRuntimeToolPolicy(policy, input) {
|
|
43992
|
+
if (policy?.allowedTools && !policy.allowedTools.includes(input.toolName)) {
|
|
43993
|
+
return {
|
|
43994
|
+
allowed: false,
|
|
43995
|
+
reason: `Runtime policy does not allow tool: ${input.toolName}`,
|
|
43996
|
+
risk: input.risk
|
|
43997
|
+
};
|
|
43998
|
+
}
|
|
43999
|
+
if (policy?.maxToolRisk && riskRank(input.risk) > riskRank(policy.maxToolRisk)) {
|
|
44000
|
+
return {
|
|
44001
|
+
allowed: false,
|
|
44002
|
+
reason: `Runtime policy allows tools up to ${policy.maxToolRisk} risk; ${input.toolName} is ${input.risk}.`,
|
|
44003
|
+
risk: input.risk
|
|
44004
|
+
};
|
|
44005
|
+
}
|
|
44006
|
+
if (policy?.requireHumanApprovalFor?.includes(input.risk) && input.confirmed !== true) {
|
|
44007
|
+
return {
|
|
44008
|
+
allowed: false,
|
|
44009
|
+
requiresConfirmation: true,
|
|
44010
|
+
reason: `Runtime policy requires human approval for ${input.risk} tools.`,
|
|
44011
|
+
risk: input.risk
|
|
44012
|
+
};
|
|
44013
|
+
}
|
|
44014
|
+
return { allowed: true, risk: input.risk };
|
|
44015
|
+
}
|
|
44016
|
+
function evaluateRuntimeRiskPolicy(policy, input) {
|
|
44017
|
+
if (policy?.maxToolRisk && riskRank(input.risk) > riskRank(policy.maxToolRisk)) {
|
|
44018
|
+
return {
|
|
44019
|
+
allowed: false,
|
|
44020
|
+
reason: `Runtime policy allows work up to ${policy.maxToolRisk} risk; ${input.subject} is ${input.risk}.`,
|
|
44021
|
+
risk: input.risk
|
|
44022
|
+
};
|
|
44023
|
+
}
|
|
44024
|
+
if (policy?.requireHumanApprovalFor?.includes(input.risk) && input.confirmed !== true) {
|
|
44025
|
+
return {
|
|
44026
|
+
allowed: false,
|
|
44027
|
+
requiresConfirmation: true,
|
|
44028
|
+
reason: `Runtime policy requires human approval for ${input.risk} work.`,
|
|
44029
|
+
risk: input.risk
|
|
44030
|
+
};
|
|
44031
|
+
}
|
|
44032
|
+
return { allowed: true, risk: input.risk };
|
|
44033
|
+
}
|
|
44034
|
+
function assertRuntimeUsageWithinPolicy(policy, usage) {
|
|
44035
|
+
const budget = policy?.costBudget;
|
|
44036
|
+
if (!budget) return;
|
|
44037
|
+
if (budget.maxInputTokens !== void 0 && (usage.inputTokens ?? 0) > budget.maxInputTokens) {
|
|
44038
|
+
throw new Error(
|
|
44039
|
+
`Runtime policy input token budget exceeded: ${usage.inputTokens ?? 0}/${budget.maxInputTokens}`
|
|
44040
|
+
);
|
|
44041
|
+
}
|
|
44042
|
+
if (budget.maxOutputTokens !== void 0 && (usage.outputTokens ?? 0) > budget.maxOutputTokens) {
|
|
44043
|
+
throw new Error(
|
|
44044
|
+
`Runtime policy output token budget exceeded: ${usage.outputTokens ?? 0}/${budget.maxOutputTokens}`
|
|
44045
|
+
);
|
|
44046
|
+
}
|
|
44047
|
+
}
|
|
44048
|
+
function cloneRuntimePolicy(policy) {
|
|
44049
|
+
return mergeRuntimePolicy(void 0, policy) ?? {};
|
|
44050
|
+
}
|
|
44051
|
+
function riskRank(risk) {
|
|
44052
|
+
switch (risk) {
|
|
44053
|
+
case "read-only":
|
|
44054
|
+
return 0;
|
|
44055
|
+
case "network":
|
|
44056
|
+
return 1;
|
|
44057
|
+
case "write":
|
|
44058
|
+
return 2;
|
|
44059
|
+
case "destructive":
|
|
44060
|
+
return 3;
|
|
44061
|
+
case "secrets-sensitive":
|
|
44062
|
+
return 4;
|
|
44063
|
+
}
|
|
44064
|
+
}
|
|
44065
|
+
var InMemoryEventLog = class {
|
|
44066
|
+
events = [];
|
|
44067
|
+
record(type, data = {}) {
|
|
44068
|
+
const event = {
|
|
44069
|
+
id: randomUUID(),
|
|
44070
|
+
type,
|
|
44071
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44072
|
+
data
|
|
44073
|
+
};
|
|
44074
|
+
this.events.push(event);
|
|
44075
|
+
return event;
|
|
44076
|
+
}
|
|
44077
|
+
list() {
|
|
44078
|
+
return [...this.events];
|
|
44079
|
+
}
|
|
44080
|
+
count() {
|
|
44081
|
+
return this.events.length;
|
|
44082
|
+
}
|
|
44083
|
+
clear() {
|
|
44084
|
+
this.events = [];
|
|
44085
|
+
}
|
|
44086
|
+
};
|
|
44087
|
+
var FileEventLog = class {
|
|
44088
|
+
constructor(filePath) {
|
|
44089
|
+
this.filePath = filePath;
|
|
44090
|
+
try {
|
|
44091
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
44092
|
+
} catch {
|
|
44093
|
+
this.writable = false;
|
|
44094
|
+
}
|
|
44095
|
+
}
|
|
44096
|
+
filePath;
|
|
44097
|
+
memory = new InMemoryEventLog();
|
|
44098
|
+
writable = true;
|
|
44099
|
+
record(type, data = {}) {
|
|
44100
|
+
const event = this.memory.record(type, data);
|
|
44101
|
+
if (this.writable) {
|
|
44102
|
+
try {
|
|
44103
|
+
appendFileSync(this.filePath, JSON.stringify(event) + "\n", "utf-8");
|
|
44104
|
+
} catch {
|
|
44105
|
+
this.writable = false;
|
|
44106
|
+
}
|
|
44107
|
+
}
|
|
44108
|
+
return event;
|
|
44109
|
+
}
|
|
44110
|
+
list() {
|
|
44111
|
+
if (!this.writable) return this.memory.list();
|
|
44112
|
+
try {
|
|
44113
|
+
const raw = readFileSync(this.filePath, "utf-8");
|
|
44114
|
+
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
44115
|
+
try {
|
|
44116
|
+
return [JSON.parse(line)];
|
|
44117
|
+
} catch {
|
|
44118
|
+
return [];
|
|
44119
|
+
}
|
|
44120
|
+
});
|
|
44121
|
+
} catch {
|
|
44122
|
+
return this.memory.list();
|
|
44123
|
+
}
|
|
44124
|
+
}
|
|
44125
|
+
count() {
|
|
44126
|
+
return this.list().length;
|
|
44127
|
+
}
|
|
44128
|
+
clear() {
|
|
44129
|
+
this.memory.clear();
|
|
44130
|
+
if (this.writable) {
|
|
44131
|
+
try {
|
|
44132
|
+
writeFileSync(this.filePath, "", "utf-8");
|
|
44133
|
+
} catch {
|
|
44134
|
+
this.writable = false;
|
|
44135
|
+
}
|
|
44136
|
+
}
|
|
44137
|
+
}
|
|
44138
|
+
};
|
|
44139
|
+
function createEventLog() {
|
|
44140
|
+
return new InMemoryEventLog();
|
|
44141
|
+
}
|
|
44142
|
+
function createFileEventLog(filePath) {
|
|
44143
|
+
return new FileEventLog(filePath);
|
|
44144
|
+
}
|
|
44145
|
+
|
|
44146
|
+
// src/runtime/agent-modes.ts
|
|
44147
|
+
var AGENT_MODES = {
|
|
44148
|
+
ask: {
|
|
44149
|
+
id: "ask",
|
|
44150
|
+
label: "Ask",
|
|
44151
|
+
description: "Answer questions and explain code without modifying files.",
|
|
44152
|
+
readOnly: true,
|
|
44153
|
+
preferredTools: ["read_file", "grep", "glob", "codebase_map", "lsp_definition"],
|
|
44154
|
+
requiresVerification: false
|
|
44155
|
+
},
|
|
44156
|
+
plan: {
|
|
44157
|
+
id: "plan",
|
|
44158
|
+
label: "Plan",
|
|
44159
|
+
description: "Explore and produce an implementation plan with read-only tools.",
|
|
44160
|
+
readOnly: true,
|
|
44161
|
+
preferredTools: ["read_file", "grep", "glob", "codebase_map", "lsp_workspace_symbols"],
|
|
44162
|
+
requiresVerification: false
|
|
44163
|
+
},
|
|
44164
|
+
build: {
|
|
44165
|
+
id: "build",
|
|
44166
|
+
label: "Build",
|
|
44167
|
+
description: "Implement code changes and verify them.",
|
|
44168
|
+
readOnly: false,
|
|
44169
|
+
preferredTools: ["read_file", "edit_file", "write_file", "bash_exec", "run_tests"],
|
|
44170
|
+
requiresVerification: true
|
|
44171
|
+
},
|
|
44172
|
+
debug: {
|
|
44173
|
+
id: "debug",
|
|
44174
|
+
label: "Debug",
|
|
44175
|
+
description: "Reproduce failures, trace root cause, patch, and verify.",
|
|
44176
|
+
readOnly: false,
|
|
44177
|
+
preferredTools: ["bash_exec", "read_file", "grep", "lsp_references", "edit_file"],
|
|
44178
|
+
requiresVerification: true
|
|
44179
|
+
},
|
|
44180
|
+
review: {
|
|
44181
|
+
id: "review",
|
|
44182
|
+
label: "Review",
|
|
44183
|
+
description: "Inspect code quality, security, behavior changes, and test gaps.",
|
|
44184
|
+
readOnly: true,
|
|
44185
|
+
preferredTools: ["git_diff", "read_file", "grep", "review_code", "calculate_quality"],
|
|
44186
|
+
requiresVerification: false
|
|
44187
|
+
},
|
|
44188
|
+
architect: {
|
|
44189
|
+
id: "architect",
|
|
44190
|
+
label: "Architect",
|
|
44191
|
+
description: "Design architecture and split work for architect/editor execution.",
|
|
44192
|
+
readOnly: true,
|
|
44193
|
+
preferredTools: ["codebase_map", "lsp_workspace_symbols", "grep", "create_agent_plan"],
|
|
44194
|
+
requiresVerification: false
|
|
44195
|
+
}
|
|
44196
|
+
};
|
|
44197
|
+
function getAgentMode(mode) {
|
|
44198
|
+
return AGENT_MODES[mode];
|
|
44199
|
+
}
|
|
44200
|
+
function listAgentModes() {
|
|
44201
|
+
return Object.values(AGENT_MODES);
|
|
44202
|
+
}
|
|
44203
|
+
function isAgentMode(value) {
|
|
44204
|
+
return value in AGENT_MODES;
|
|
44205
|
+
}
|
|
44206
|
+
|
|
44207
|
+
// src/runtime/permission-policy.ts
|
|
44208
|
+
var READ_ONLY_CATEGORIES = /* @__PURE__ */ new Set(["search", "web", "document"]);
|
|
44209
|
+
var WRITE_CATEGORIES = /* @__PURE__ */ new Set(["file", "git", "test", "build", "memory"]);
|
|
44210
|
+
var READ_ONLY_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
44211
|
+
"glob",
|
|
44212
|
+
"read_file",
|
|
44213
|
+
"list_dir",
|
|
44214
|
+
"tree",
|
|
44215
|
+
"grep",
|
|
44216
|
+
"find_in_file",
|
|
44217
|
+
"semantic_search",
|
|
44218
|
+
"codebase_map",
|
|
44219
|
+
"repo_context",
|
|
44220
|
+
"lsp_status",
|
|
44221
|
+
"lsp_document_symbols",
|
|
44222
|
+
"lsp_workspace_symbols",
|
|
44223
|
+
"lsp_definition",
|
|
44224
|
+
"lsp_references",
|
|
44225
|
+
"git_status",
|
|
44226
|
+
"git_log",
|
|
44227
|
+
"git_diff",
|
|
44228
|
+
"git_show",
|
|
44229
|
+
"git_branch",
|
|
44230
|
+
"recall_memory",
|
|
44231
|
+
"list_memories",
|
|
44232
|
+
"list_checkpoints",
|
|
44233
|
+
"checkAgentCapability"
|
|
44234
|
+
]);
|
|
44235
|
+
var WRITE_CAPABLE_TOOL_NAMES = /* @__PURE__ */ new Set(["run_linter"]);
|
|
44236
|
+
var DESTRUCTIVE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
44237
|
+
"bash_exec",
|
|
44238
|
+
"write_file",
|
|
44239
|
+
"edit_file",
|
|
44240
|
+
"delete_file",
|
|
44241
|
+
"restore_checkpoint",
|
|
44242
|
+
"git_commit",
|
|
44243
|
+
"git_push",
|
|
44244
|
+
"request_human_escalation"
|
|
44245
|
+
]);
|
|
44246
|
+
function riskForTool(tool) {
|
|
44247
|
+
if (READ_ONLY_TOOL_NAMES.has(tool.name)) return "read-only";
|
|
44248
|
+
if (DESTRUCTIVE_TOOL_NAMES.has(tool.name)) return "destructive";
|
|
44249
|
+
if (WRITE_CAPABLE_TOOL_NAMES.has(tool.name)) return "write";
|
|
44250
|
+
if (tool.category === "web") return "network";
|
|
44251
|
+
if (WRITE_CATEGORIES.has(tool.category)) return "write";
|
|
44252
|
+
if (tool.category === "quality") return "write";
|
|
44253
|
+
return "read-only";
|
|
44254
|
+
}
|
|
44255
|
+
var DefaultPermissionPolicy = class {
|
|
44256
|
+
canExecuteTool(mode, tool) {
|
|
44257
|
+
const definition = getAgentMode(mode);
|
|
44258
|
+
const risk = riskForTool(tool);
|
|
44259
|
+
const readOnlyTool = READ_ONLY_TOOL_NAMES.has(tool.name) || READ_ONLY_CATEGORIES.has(tool.category);
|
|
44260
|
+
if (definition.readOnly && !readOnlyTool) {
|
|
44261
|
+
return {
|
|
44262
|
+
allowed: false,
|
|
44263
|
+
reason: `${definition.label} mode is read-only; ${tool.name} is a ${tool.category} tool.`,
|
|
44264
|
+
risk
|
|
44265
|
+
};
|
|
44266
|
+
}
|
|
44267
|
+
if (risk === "destructive") {
|
|
44268
|
+
return {
|
|
44269
|
+
allowed: true,
|
|
44270
|
+
requiresConfirmation: true,
|
|
44271
|
+
reason: `${tool.name} can change repository state and should be confirmed.`,
|
|
44272
|
+
risk
|
|
44273
|
+
};
|
|
44274
|
+
}
|
|
44275
|
+
return { allowed: true, risk };
|
|
44276
|
+
}
|
|
44277
|
+
canExecuteToolInput(mode, tool, input) {
|
|
44278
|
+
if (tool.name === "spawnSimpleAgent") {
|
|
44279
|
+
const risk = riskForSpawnedAgent(input);
|
|
44280
|
+
const definition2 = getAgentMode(mode);
|
|
44281
|
+
if (definition2.readOnly && risk !== "read-only" && risk !== "network") {
|
|
44282
|
+
return {
|
|
44283
|
+
allowed: false,
|
|
44284
|
+
reason: `${definition2.label} mode is read-only; spawnSimpleAgent with this role can perform ${risk} work.`,
|
|
44285
|
+
risk
|
|
44286
|
+
};
|
|
44287
|
+
}
|
|
44288
|
+
return {
|
|
44289
|
+
allowed: true,
|
|
44290
|
+
requiresConfirmation: risk === "destructive" || risk === "secrets-sensitive",
|
|
44291
|
+
risk
|
|
44292
|
+
};
|
|
44293
|
+
}
|
|
44294
|
+
if (tool.name !== "run_linter") {
|
|
44295
|
+
return this.canExecuteTool(mode, tool);
|
|
44296
|
+
}
|
|
44297
|
+
const definition = getAgentMode(mode);
|
|
44298
|
+
const fixEnabled = input["fix"] === true;
|
|
44299
|
+
const decision = fixEnabled ? { allowed: true, risk: "write" } : { allowed: true, risk: "read-only" };
|
|
44300
|
+
if (definition.readOnly && fixEnabled) {
|
|
44301
|
+
return {
|
|
44302
|
+
allowed: false,
|
|
44303
|
+
reason: `${definition.label} mode is read-only; run_linter with fix=true can modify files.`,
|
|
44304
|
+
risk: "write"
|
|
44305
|
+
};
|
|
44306
|
+
}
|
|
44307
|
+
return decision;
|
|
44308
|
+
}
|
|
44309
|
+
};
|
|
44310
|
+
function createPermissionPolicy() {
|
|
44311
|
+
return new DefaultPermissionPolicy();
|
|
44312
|
+
}
|
|
44313
|
+
function riskForSpawnedAgent(input) {
|
|
44314
|
+
const type = typeof input["type"] === "string" ? input["type"] : void 0;
|
|
44315
|
+
const role = typeof input["role"] === "string" ? input["role"] : void 0;
|
|
44316
|
+
const resolved = type ?? role;
|
|
44317
|
+
switch (resolved) {
|
|
44318
|
+
case "explore":
|
|
44319
|
+
case "plan":
|
|
44320
|
+
case "review":
|
|
44321
|
+
case "architect":
|
|
44322
|
+
case "security":
|
|
44323
|
+
case "docs":
|
|
44324
|
+
case "researcher":
|
|
44325
|
+
case "reviewer":
|
|
44326
|
+
case "planner":
|
|
44327
|
+
return "read-only";
|
|
44328
|
+
case "database":
|
|
44329
|
+
return "secrets-sensitive";
|
|
44330
|
+
case "test":
|
|
44331
|
+
case "tdd":
|
|
44332
|
+
case "e2e":
|
|
44333
|
+
case "tester":
|
|
44334
|
+
return "destructive";
|
|
44335
|
+
case "debug":
|
|
44336
|
+
case "refactor":
|
|
44337
|
+
case "coder":
|
|
44338
|
+
case "optimizer":
|
|
44339
|
+
return "write";
|
|
44340
|
+
default:
|
|
44341
|
+
return "read-only";
|
|
44342
|
+
}
|
|
44343
|
+
}
|
|
44344
|
+
|
|
44345
|
+
// src/runtime/runtime-tool-executor.ts
|
|
44346
|
+
var RuntimeToolExecutor = class {
|
|
44347
|
+
toolRegistry;
|
|
44348
|
+
eventLog;
|
|
44349
|
+
permissionPolicy;
|
|
44350
|
+
defaultMode;
|
|
44351
|
+
runtimePolicy;
|
|
44352
|
+
constructor(options) {
|
|
44353
|
+
this.toolRegistry = options.toolRegistry;
|
|
44354
|
+
this.eventLog = options.eventLog ?? createEventLog();
|
|
44355
|
+
this.permissionPolicy = options.permissionPolicy ?? createPermissionPolicy();
|
|
44356
|
+
this.defaultMode = options.mode ?? "ask";
|
|
44357
|
+
this.runtimePolicy = options.runtimePolicy;
|
|
44358
|
+
}
|
|
44359
|
+
async execute(input) {
|
|
44360
|
+
const startedAt = performance.now();
|
|
44361
|
+
const mode = input.mode ?? this.defaultMode;
|
|
44362
|
+
const allowedTools = input.allowedTools ? new Set(input.allowedTools) : void 0;
|
|
44363
|
+
if (allowedTools && !allowedTools.has(input.toolName)) {
|
|
44364
|
+
const decision2 = {
|
|
44365
|
+
allowed: false,
|
|
44366
|
+
reason: `Tool '${input.toolName}' is not available to this agent.`,
|
|
44367
|
+
risk: "read-only"
|
|
44368
|
+
};
|
|
44369
|
+
return this.block(input, mode, decision2, startedAt);
|
|
44370
|
+
}
|
|
44371
|
+
const tool = this.toolRegistry.get(input.toolName);
|
|
44372
|
+
if (!tool) {
|
|
44373
|
+
const decision2 = {
|
|
44374
|
+
allowed: false,
|
|
44375
|
+
reason: "Tool not registered.",
|
|
44376
|
+
risk: "read-only"
|
|
44377
|
+
};
|
|
44378
|
+
return this.block(input, mode, decision2, startedAt);
|
|
44379
|
+
}
|
|
44380
|
+
const decision = this.permissionPolicy.canExecuteToolInput ? this.permissionPolicy.canExecuteToolInput(mode, tool, input.input) : this.permissionPolicy.canExecuteTool(mode, tool);
|
|
44381
|
+
const runtimeDecision = decision.allowed ? evaluateRuntimeToolPolicy(this.runtimePolicy, {
|
|
44382
|
+
toolName: input.toolName,
|
|
44383
|
+
risk: decision.risk,
|
|
44384
|
+
confirmed: input.confirmed
|
|
44385
|
+
}) : void 0;
|
|
44386
|
+
if (!decision.allowed || runtimeDecision?.allowed === false || decision.requiresConfirmation && input.confirmed !== true) {
|
|
44387
|
+
const reason = runtimeDecision?.reason ?? decision.reason ?? (decision.requiresConfirmation ? "Tool requires explicit runtime confirmation." : "Tool is not allowed.");
|
|
44388
|
+
return this.block(
|
|
44389
|
+
input,
|
|
44390
|
+
mode,
|
|
44391
|
+
{
|
|
44392
|
+
...decision,
|
|
44393
|
+
allowed: false,
|
|
44394
|
+
reason,
|
|
44395
|
+
requiresConfirmation: runtimeDecision?.requiresConfirmation ?? decision.requiresConfirmation,
|
|
44396
|
+
risk: runtimeDecision?.risk ?? decision.risk
|
|
44397
|
+
},
|
|
44398
|
+
startedAt,
|
|
44399
|
+
{ runtimePolicyBlocked: runtimeDecision ? !runtimeDecision.allowed : false }
|
|
44400
|
+
);
|
|
44401
|
+
}
|
|
44402
|
+
this.eventLog.record("agent.tool.called", {
|
|
44403
|
+
mode,
|
|
44404
|
+
tool: input.toolName,
|
|
44405
|
+
risk: decision.risk,
|
|
44406
|
+
metadata: input.metadata
|
|
44407
|
+
});
|
|
44408
|
+
this.eventLog.record("tool.started", {
|
|
44409
|
+
mode,
|
|
44410
|
+
tool: input.toolName,
|
|
44411
|
+
risk: decision.risk,
|
|
44412
|
+
runtimeApi: true,
|
|
44413
|
+
metadataKeys: Object.keys(input.metadata ?? {}).sort()
|
|
44414
|
+
});
|
|
44415
|
+
const result = await this.toolRegistry.execute(input.toolName, input.input);
|
|
44416
|
+
this.eventLog.record("tool.completed", {
|
|
44417
|
+
mode,
|
|
44418
|
+
tool: input.toolName,
|
|
44419
|
+
success: result.success,
|
|
44420
|
+
duration: result.duration,
|
|
44421
|
+
runtimeApi: true
|
|
44422
|
+
});
|
|
44423
|
+
return {
|
|
44424
|
+
toolName: input.toolName,
|
|
44425
|
+
success: result.success,
|
|
44426
|
+
output: result.data,
|
|
44427
|
+
error: result.error,
|
|
44428
|
+
duration: result.duration,
|
|
44429
|
+
decision
|
|
44430
|
+
};
|
|
44431
|
+
}
|
|
44432
|
+
block(input, mode, decision, startedAt, extraData = {}) {
|
|
44433
|
+
this.eventLog.record("tool.blocked", {
|
|
44434
|
+
mode,
|
|
44435
|
+
tool: input.toolName,
|
|
44436
|
+
reason: decision.reason,
|
|
44437
|
+
risk: decision.risk,
|
|
44438
|
+
requiresConfirmation: decision.requiresConfirmation,
|
|
44439
|
+
runtimeApi: true,
|
|
44440
|
+
metadata: input.metadata,
|
|
44441
|
+
...extraData
|
|
44442
|
+
});
|
|
44443
|
+
return {
|
|
44444
|
+
toolName: input.toolName,
|
|
44445
|
+
success: false,
|
|
44446
|
+
error: decision.reason ?? "Tool is not allowed.",
|
|
44447
|
+
duration: performance.now() - startedAt,
|
|
44448
|
+
decision
|
|
44449
|
+
};
|
|
44450
|
+
}
|
|
44451
|
+
};
|
|
44452
|
+
function createRuntimeToolExecutor(options) {
|
|
44453
|
+
return new RuntimeToolExecutor(options);
|
|
44454
|
+
}
|
|
44455
|
+
|
|
43786
44456
|
// src/agents/executor.ts
|
|
43787
44457
|
var AgentExecutor = class {
|
|
43788
|
-
constructor(provider, toolRegistry) {
|
|
44458
|
+
constructor(provider, toolRegistry, runtimeToolExecutor) {
|
|
43789
44459
|
this.provider = provider;
|
|
43790
44460
|
this.toolRegistry = toolRegistry;
|
|
44461
|
+
this.runtimeToolExecutor = runtimeToolExecutor ?? createRuntimeToolExecutor({ toolRegistry, mode: "ask" });
|
|
43791
44462
|
}
|
|
43792
44463
|
provider;
|
|
43793
44464
|
toolRegistry;
|
|
44465
|
+
runtimeToolExecutor;
|
|
43794
44466
|
/**
|
|
43795
44467
|
* Execute an agent on a task with multi-turn tool use
|
|
43796
44468
|
*/
|
|
@@ -43858,11 +44530,21 @@ var AgentExecutor = class {
|
|
|
43858
44530
|
for (const toolCall of response.toolCalls) {
|
|
43859
44531
|
toolsUsed.add(toolCall.name);
|
|
43860
44532
|
try {
|
|
43861
|
-
const result = await this.
|
|
44533
|
+
const result = await this.runtimeToolExecutor.execute({
|
|
44534
|
+
toolName: toolCall.name,
|
|
44535
|
+
input: toolCall.input,
|
|
44536
|
+
allowedTools: agent.allowedTools.length > 0 ? agent.allowedTools : void 0,
|
|
44537
|
+
mode: runtimeModeForAgent(agent.role),
|
|
44538
|
+
metadata: {
|
|
44539
|
+
agentRole: agent.role,
|
|
44540
|
+
taskId: task.id,
|
|
44541
|
+
toolCallId: toolCall.id
|
|
44542
|
+
}
|
|
44543
|
+
});
|
|
43862
44544
|
toolResults.push({
|
|
43863
44545
|
type: "tool_result",
|
|
43864
44546
|
tool_use_id: toolCall.id,
|
|
43865
|
-
content: result.success ? JSON.stringify(result.
|
|
44547
|
+
content: result.success ? JSON.stringify(result.output) : `Error: ${result.error}`,
|
|
43866
44548
|
is_error: !result.success
|
|
43867
44549
|
});
|
|
43868
44550
|
} catch (error) {
|
|
@@ -44073,6 +44755,22 @@ Use tools to analyze requirements and explore the codebase.`,
|
|
|
44073
44755
|
allowedTools: ["read_file", "grep", "glob", "codebase_map"]
|
|
44074
44756
|
}
|
|
44075
44757
|
};
|
|
44758
|
+
function runtimeModeForAgent(role) {
|
|
44759
|
+
switch (role) {
|
|
44760
|
+
case "researcher":
|
|
44761
|
+
case "planner":
|
|
44762
|
+
return "plan";
|
|
44763
|
+
case "architect":
|
|
44764
|
+
return "architect";
|
|
44765
|
+
case "reviewer":
|
|
44766
|
+
return "review";
|
|
44767
|
+
case "tester":
|
|
44768
|
+
case "editor":
|
|
44769
|
+
case "coder":
|
|
44770
|
+
case "optimizer":
|
|
44771
|
+
return "build";
|
|
44772
|
+
}
|
|
44773
|
+
}
|
|
44076
44774
|
var DEFAULTS = {
|
|
44077
44775
|
maxConcurrency: os4__default.cpus().length,
|
|
44078
44776
|
minConcurrency: 1,
|
|
@@ -46392,16 +47090,18 @@ var AgentManager = class extends EventEmitter {
|
|
|
46392
47090
|
abortControllers = /* @__PURE__ */ new Map();
|
|
46393
47091
|
provider;
|
|
46394
47092
|
toolRegistry;
|
|
47093
|
+
runtimeToolExecutor;
|
|
46395
47094
|
logger = getLogger();
|
|
46396
47095
|
/**
|
|
46397
47096
|
* Create a new AgentManager
|
|
46398
47097
|
* @param provider - LLM provider for agent execution
|
|
46399
47098
|
* @param toolRegistry - Tool registry for agent tool access
|
|
46400
47099
|
*/
|
|
46401
|
-
constructor(provider, toolRegistry) {
|
|
47100
|
+
constructor(provider, toolRegistry, runtimeToolExecutor) {
|
|
46402
47101
|
super();
|
|
46403
47102
|
this.provider = provider;
|
|
46404
47103
|
this.toolRegistry = toolRegistry;
|
|
47104
|
+
this.runtimeToolExecutor = runtimeToolExecutor ?? createRuntimeToolExecutor({ toolRegistry, mode: "ask" });
|
|
46405
47105
|
}
|
|
46406
47106
|
/**
|
|
46407
47107
|
* Spawn a new subagent for a specific task
|
|
@@ -46716,11 +47416,20 @@ var AgentManager = class extends EventEmitter {
|
|
|
46716
47416
|
continue;
|
|
46717
47417
|
}
|
|
46718
47418
|
try {
|
|
46719
|
-
const result = await this.
|
|
47419
|
+
const result = await this.runtimeToolExecutor.execute({
|
|
47420
|
+
toolName: toolCall.name,
|
|
47421
|
+
input: toolCall.input,
|
|
47422
|
+
allowedTools: config.tools,
|
|
47423
|
+
mode: runtimeModeForAgentType(config.type),
|
|
47424
|
+
metadata: {
|
|
47425
|
+
agentType: config.type,
|
|
47426
|
+
toolCallId: toolCall.id
|
|
47427
|
+
}
|
|
47428
|
+
});
|
|
46720
47429
|
results.push({
|
|
46721
47430
|
type: "tool_result",
|
|
46722
47431
|
tool_use_id: toolCall.id,
|
|
46723
|
-
content: result.success ? String(result.
|
|
47432
|
+
content: result.success ? String(result.output ?? "Success") : `Error: ${result.error}`,
|
|
46724
47433
|
is_error: !result.success
|
|
46725
47434
|
});
|
|
46726
47435
|
} catch (error) {
|
|
@@ -46785,6 +47494,27 @@ var AgentManager = class extends EventEmitter {
|
|
|
46785
47494
|
function agentTypeToRuntimeRole(type) {
|
|
46786
47495
|
return mapLegacyAgentRole(type);
|
|
46787
47496
|
}
|
|
47497
|
+
function runtimeModeForAgentType(type) {
|
|
47498
|
+
switch (type) {
|
|
47499
|
+
case "explore":
|
|
47500
|
+
case "plan":
|
|
47501
|
+
case "docs":
|
|
47502
|
+
return "plan";
|
|
47503
|
+
case "review":
|
|
47504
|
+
case "security":
|
|
47505
|
+
return "review";
|
|
47506
|
+
case "architect":
|
|
47507
|
+
return "architect";
|
|
47508
|
+
case "debug":
|
|
47509
|
+
return "debug";
|
|
47510
|
+
case "test":
|
|
47511
|
+
case "tdd":
|
|
47512
|
+
case "e2e":
|
|
47513
|
+
case "refactor":
|
|
47514
|
+
case "database":
|
|
47515
|
+
return "build";
|
|
47516
|
+
}
|
|
47517
|
+
}
|
|
46788
47518
|
|
|
46789
47519
|
// src/agents/provider-bridge.ts
|
|
46790
47520
|
var agentProvider = null;
|
|
@@ -50656,7 +51386,7 @@ async function validateCode(code, filePath, _language) {
|
|
|
50656
51386
|
const errors = [];
|
|
50657
51387
|
const warnings = [];
|
|
50658
51388
|
try {
|
|
50659
|
-
const ast = parse
|
|
51389
|
+
const ast = parse(code, {
|
|
50660
51390
|
loc: true,
|
|
50661
51391
|
range: true,
|
|
50662
51392
|
comment: true,
|
|
@@ -50783,7 +51513,7 @@ async function analyzeFile(filePath, includeAst = false) {
|
|
|
50783
51513
|
const exports$1 = [];
|
|
50784
51514
|
let ast;
|
|
50785
51515
|
try {
|
|
50786
|
-
ast = parse
|
|
51516
|
+
ast = parse(content, {
|
|
50787
51517
|
loc: true,
|
|
50788
51518
|
range: true,
|
|
50789
51519
|
comment: true,
|
|
@@ -53261,69 +53991,6 @@ var repoMapCommand = {
|
|
|
53261
53991
|
return false;
|
|
53262
53992
|
}
|
|
53263
53993
|
};
|
|
53264
|
-
|
|
53265
|
-
// src/runtime/agent-modes.ts
|
|
53266
|
-
var AGENT_MODES = {
|
|
53267
|
-
ask: {
|
|
53268
|
-
id: "ask",
|
|
53269
|
-
label: "Ask",
|
|
53270
|
-
description: "Answer questions and explain code without modifying files.",
|
|
53271
|
-
readOnly: true,
|
|
53272
|
-
preferredTools: ["read_file", "grep", "glob", "codebase_map", "lsp_definition"],
|
|
53273
|
-
requiresVerification: false
|
|
53274
|
-
},
|
|
53275
|
-
plan: {
|
|
53276
|
-
id: "plan",
|
|
53277
|
-
label: "Plan",
|
|
53278
|
-
description: "Explore and produce an implementation plan with read-only tools.",
|
|
53279
|
-
readOnly: true,
|
|
53280
|
-
preferredTools: ["read_file", "grep", "glob", "codebase_map", "lsp_workspace_symbols"],
|
|
53281
|
-
requiresVerification: false
|
|
53282
|
-
},
|
|
53283
|
-
build: {
|
|
53284
|
-
id: "build",
|
|
53285
|
-
label: "Build",
|
|
53286
|
-
description: "Implement code changes and verify them.",
|
|
53287
|
-
readOnly: false,
|
|
53288
|
-
preferredTools: ["read_file", "edit_file", "write_file", "bash_exec", "run_tests"],
|
|
53289
|
-
requiresVerification: true
|
|
53290
|
-
},
|
|
53291
|
-
debug: {
|
|
53292
|
-
id: "debug",
|
|
53293
|
-
label: "Debug",
|
|
53294
|
-
description: "Reproduce failures, trace root cause, patch, and verify.",
|
|
53295
|
-
readOnly: false,
|
|
53296
|
-
preferredTools: ["bash_exec", "read_file", "grep", "lsp_references", "edit_file"],
|
|
53297
|
-
requiresVerification: true
|
|
53298
|
-
},
|
|
53299
|
-
review: {
|
|
53300
|
-
id: "review",
|
|
53301
|
-
label: "Review",
|
|
53302
|
-
description: "Inspect code quality, security, behavior changes, and test gaps.",
|
|
53303
|
-
readOnly: true,
|
|
53304
|
-
preferredTools: ["git_diff", "read_file", "grep", "review_code", "calculate_quality"],
|
|
53305
|
-
requiresVerification: false
|
|
53306
|
-
},
|
|
53307
|
-
architect: {
|
|
53308
|
-
id: "architect",
|
|
53309
|
-
label: "Architect",
|
|
53310
|
-
description: "Design architecture and split work for architect/editor execution.",
|
|
53311
|
-
readOnly: true,
|
|
53312
|
-
preferredTools: ["codebase_map", "lsp_workspace_symbols", "grep", "create_agent_plan"],
|
|
53313
|
-
requiresVerification: false
|
|
53314
|
-
}
|
|
53315
|
-
};
|
|
53316
|
-
function getAgentMode(mode) {
|
|
53317
|
-
return AGENT_MODES[mode];
|
|
53318
|
-
}
|
|
53319
|
-
function listAgentModes() {
|
|
53320
|
-
return Object.values(AGENT_MODES);
|
|
53321
|
-
}
|
|
53322
|
-
function isAgentMode(value) {
|
|
53323
|
-
return value in AGENT_MODES;
|
|
53324
|
-
}
|
|
53325
|
-
|
|
53326
|
-
// src/cli/repl/commands/mode.ts
|
|
53327
53994
|
function currentMode(session) {
|
|
53328
53995
|
return session.agentMode ?? (session.planMode ? "plan" : "build");
|
|
53329
53996
|
}
|
|
@@ -58030,6 +58697,7 @@ init_providers();
|
|
|
58030
58697
|
|
|
58031
58698
|
// src/runtime/agent-runtime.ts
|
|
58032
58699
|
init_env();
|
|
58700
|
+
init_registry4();
|
|
58033
58701
|
|
|
58034
58702
|
// src/runtime/default-turn-runner.ts
|
|
58035
58703
|
var DefaultRuntimeTurnRunner = class {
|
|
@@ -58063,224 +58731,6 @@ var DefaultRuntimeTurnRunner = class {
|
|
|
58063
58731
|
function createDefaultRuntimeTurnRunner() {
|
|
58064
58732
|
return new DefaultRuntimeTurnRunner();
|
|
58065
58733
|
}
|
|
58066
|
-
var InMemoryEventLog = class {
|
|
58067
|
-
events = [];
|
|
58068
|
-
record(type, data = {}) {
|
|
58069
|
-
const event = {
|
|
58070
|
-
id: randomUUID(),
|
|
58071
|
-
type,
|
|
58072
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
58073
|
-
data
|
|
58074
|
-
};
|
|
58075
|
-
this.events.push(event);
|
|
58076
|
-
return event;
|
|
58077
|
-
}
|
|
58078
|
-
list() {
|
|
58079
|
-
return [...this.events];
|
|
58080
|
-
}
|
|
58081
|
-
count() {
|
|
58082
|
-
return this.events.length;
|
|
58083
|
-
}
|
|
58084
|
-
clear() {
|
|
58085
|
-
this.events = [];
|
|
58086
|
-
}
|
|
58087
|
-
};
|
|
58088
|
-
var FileEventLog = class {
|
|
58089
|
-
constructor(filePath) {
|
|
58090
|
-
this.filePath = filePath;
|
|
58091
|
-
try {
|
|
58092
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
58093
|
-
} catch {
|
|
58094
|
-
this.writable = false;
|
|
58095
|
-
}
|
|
58096
|
-
}
|
|
58097
|
-
filePath;
|
|
58098
|
-
memory = new InMemoryEventLog();
|
|
58099
|
-
writable = true;
|
|
58100
|
-
record(type, data = {}) {
|
|
58101
|
-
const event = this.memory.record(type, data);
|
|
58102
|
-
if (this.writable) {
|
|
58103
|
-
try {
|
|
58104
|
-
appendFileSync(this.filePath, JSON.stringify(event) + "\n", "utf-8");
|
|
58105
|
-
} catch {
|
|
58106
|
-
this.writable = false;
|
|
58107
|
-
}
|
|
58108
|
-
}
|
|
58109
|
-
return event;
|
|
58110
|
-
}
|
|
58111
|
-
list() {
|
|
58112
|
-
if (!this.writable) return this.memory.list();
|
|
58113
|
-
try {
|
|
58114
|
-
const raw = readFileSync(this.filePath, "utf-8");
|
|
58115
|
-
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
58116
|
-
try {
|
|
58117
|
-
return [JSON.parse(line)];
|
|
58118
|
-
} catch {
|
|
58119
|
-
return [];
|
|
58120
|
-
}
|
|
58121
|
-
});
|
|
58122
|
-
} catch {
|
|
58123
|
-
return this.memory.list();
|
|
58124
|
-
}
|
|
58125
|
-
}
|
|
58126
|
-
count() {
|
|
58127
|
-
return this.list().length;
|
|
58128
|
-
}
|
|
58129
|
-
clear() {
|
|
58130
|
-
this.memory.clear();
|
|
58131
|
-
if (this.writable) {
|
|
58132
|
-
try {
|
|
58133
|
-
writeFileSync(this.filePath, "", "utf-8");
|
|
58134
|
-
} catch {
|
|
58135
|
-
this.writable = false;
|
|
58136
|
-
}
|
|
58137
|
-
}
|
|
58138
|
-
}
|
|
58139
|
-
};
|
|
58140
|
-
function createEventLog() {
|
|
58141
|
-
return new InMemoryEventLog();
|
|
58142
|
-
}
|
|
58143
|
-
function createFileEventLog(filePath) {
|
|
58144
|
-
return new FileEventLog(filePath);
|
|
58145
|
-
}
|
|
58146
|
-
|
|
58147
|
-
// src/runtime/permission-policy.ts
|
|
58148
|
-
var READ_ONLY_CATEGORIES = /* @__PURE__ */ new Set(["search", "web", "document"]);
|
|
58149
|
-
var WRITE_CATEGORIES = /* @__PURE__ */ new Set(["file", "git", "test", "build", "memory"]);
|
|
58150
|
-
var READ_ONLY_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
58151
|
-
"glob",
|
|
58152
|
-
"read_file",
|
|
58153
|
-
"list_dir",
|
|
58154
|
-
"tree",
|
|
58155
|
-
"grep",
|
|
58156
|
-
"find_in_file",
|
|
58157
|
-
"semantic_search",
|
|
58158
|
-
"codebase_map",
|
|
58159
|
-
"repo_context",
|
|
58160
|
-
"lsp_status",
|
|
58161
|
-
"lsp_document_symbols",
|
|
58162
|
-
"lsp_workspace_symbols",
|
|
58163
|
-
"lsp_definition",
|
|
58164
|
-
"lsp_references",
|
|
58165
|
-
"git_status",
|
|
58166
|
-
"git_log",
|
|
58167
|
-
"git_diff",
|
|
58168
|
-
"git_show",
|
|
58169
|
-
"git_branch",
|
|
58170
|
-
"recall_memory",
|
|
58171
|
-
"list_memories",
|
|
58172
|
-
"list_checkpoints",
|
|
58173
|
-
"checkAgentCapability"
|
|
58174
|
-
]);
|
|
58175
|
-
var WRITE_CAPABLE_TOOL_NAMES = /* @__PURE__ */ new Set(["run_linter"]);
|
|
58176
|
-
var DESTRUCTIVE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
58177
|
-
"bash_exec",
|
|
58178
|
-
"write_file",
|
|
58179
|
-
"edit_file",
|
|
58180
|
-
"delete_file",
|
|
58181
|
-
"restore_checkpoint",
|
|
58182
|
-
"git_commit",
|
|
58183
|
-
"git_push",
|
|
58184
|
-
"request_human_escalation"
|
|
58185
|
-
]);
|
|
58186
|
-
function riskForTool(tool) {
|
|
58187
|
-
if (READ_ONLY_TOOL_NAMES.has(tool.name)) return "read-only";
|
|
58188
|
-
if (DESTRUCTIVE_TOOL_NAMES.has(tool.name)) return "destructive";
|
|
58189
|
-
if (WRITE_CAPABLE_TOOL_NAMES.has(tool.name)) return "write";
|
|
58190
|
-
if (tool.category === "web") return "network";
|
|
58191
|
-
if (WRITE_CATEGORIES.has(tool.category)) return "write";
|
|
58192
|
-
if (tool.category === "quality") return "write";
|
|
58193
|
-
return "read-only";
|
|
58194
|
-
}
|
|
58195
|
-
var DefaultPermissionPolicy = class {
|
|
58196
|
-
canExecuteTool(mode, tool) {
|
|
58197
|
-
const definition = getAgentMode(mode);
|
|
58198
|
-
const risk = riskForTool(tool);
|
|
58199
|
-
const readOnlyTool = READ_ONLY_TOOL_NAMES.has(tool.name) || READ_ONLY_CATEGORIES.has(tool.category);
|
|
58200
|
-
if (definition.readOnly && !readOnlyTool) {
|
|
58201
|
-
return {
|
|
58202
|
-
allowed: false,
|
|
58203
|
-
reason: `${definition.label} mode is read-only; ${tool.name} is a ${tool.category} tool.`,
|
|
58204
|
-
risk
|
|
58205
|
-
};
|
|
58206
|
-
}
|
|
58207
|
-
if (risk === "destructive") {
|
|
58208
|
-
return {
|
|
58209
|
-
allowed: true,
|
|
58210
|
-
requiresConfirmation: true,
|
|
58211
|
-
reason: `${tool.name} can change repository state and should be confirmed.`,
|
|
58212
|
-
risk
|
|
58213
|
-
};
|
|
58214
|
-
}
|
|
58215
|
-
return { allowed: true, risk };
|
|
58216
|
-
}
|
|
58217
|
-
canExecuteToolInput(mode, tool, input) {
|
|
58218
|
-
if (tool.name === "spawnSimpleAgent") {
|
|
58219
|
-
const risk = riskForSpawnedAgent(input);
|
|
58220
|
-
const definition2 = getAgentMode(mode);
|
|
58221
|
-
if (definition2.readOnly && risk !== "read-only" && risk !== "network") {
|
|
58222
|
-
return {
|
|
58223
|
-
allowed: false,
|
|
58224
|
-
reason: `${definition2.label} mode is read-only; spawnSimpleAgent with this role can perform ${risk} work.`,
|
|
58225
|
-
risk
|
|
58226
|
-
};
|
|
58227
|
-
}
|
|
58228
|
-
return {
|
|
58229
|
-
allowed: true,
|
|
58230
|
-
requiresConfirmation: risk === "destructive" || risk === "secrets-sensitive",
|
|
58231
|
-
risk
|
|
58232
|
-
};
|
|
58233
|
-
}
|
|
58234
|
-
if (tool.name !== "run_linter") {
|
|
58235
|
-
return this.canExecuteTool(mode, tool);
|
|
58236
|
-
}
|
|
58237
|
-
const definition = getAgentMode(mode);
|
|
58238
|
-
const fixEnabled = input["fix"] === true;
|
|
58239
|
-
const decision = fixEnabled ? { allowed: true, risk: "write" } : { allowed: true, risk: "read-only" };
|
|
58240
|
-
if (definition.readOnly && fixEnabled) {
|
|
58241
|
-
return {
|
|
58242
|
-
allowed: false,
|
|
58243
|
-
reason: `${definition.label} mode is read-only; run_linter with fix=true can modify files.`,
|
|
58244
|
-
risk: "write"
|
|
58245
|
-
};
|
|
58246
|
-
}
|
|
58247
|
-
return decision;
|
|
58248
|
-
}
|
|
58249
|
-
};
|
|
58250
|
-
function createPermissionPolicy() {
|
|
58251
|
-
return new DefaultPermissionPolicy();
|
|
58252
|
-
}
|
|
58253
|
-
function riskForSpawnedAgent(input) {
|
|
58254
|
-
const type = typeof input["type"] === "string" ? input["type"] : void 0;
|
|
58255
|
-
const role = typeof input["role"] === "string" ? input["role"] : void 0;
|
|
58256
|
-
const resolved = type ?? role;
|
|
58257
|
-
switch (resolved) {
|
|
58258
|
-
case "explore":
|
|
58259
|
-
case "plan":
|
|
58260
|
-
case "review":
|
|
58261
|
-
case "architect":
|
|
58262
|
-
case "security":
|
|
58263
|
-
case "docs":
|
|
58264
|
-
case "researcher":
|
|
58265
|
-
case "reviewer":
|
|
58266
|
-
case "planner":
|
|
58267
|
-
return "read-only";
|
|
58268
|
-
case "database":
|
|
58269
|
-
return "secrets-sensitive";
|
|
58270
|
-
case "test":
|
|
58271
|
-
case "tdd":
|
|
58272
|
-
case "e2e":
|
|
58273
|
-
case "tester":
|
|
58274
|
-
return "destructive";
|
|
58275
|
-
case "debug":
|
|
58276
|
-
case "refactor":
|
|
58277
|
-
case "coder":
|
|
58278
|
-
case "optimizer":
|
|
58279
|
-
return "write";
|
|
58280
|
-
default:
|
|
58281
|
-
return "read-only";
|
|
58282
|
-
}
|
|
58283
|
-
}
|
|
58284
58734
|
|
|
58285
58735
|
// src/runtime/provider-registry.ts
|
|
58286
58736
|
init_providers();
|
|
@@ -58447,6 +58897,109 @@ var WorkflowCatalog = class {
|
|
|
58447
58897
|
}
|
|
58448
58898
|
};
|
|
58449
58899
|
var DEFAULT_WORKFLOWS = [
|
|
58900
|
+
{
|
|
58901
|
+
id: "enterprise-rag-answer",
|
|
58902
|
+
name: "Enterprise RAG Answer",
|
|
58903
|
+
description: "Retrieve tenant-scoped knowledge, draft a cited answer, and review for policy compliance.",
|
|
58904
|
+
inputSchema: "question: string; tenantId: string; userId?: string",
|
|
58905
|
+
outputKind: "json",
|
|
58906
|
+
replayable: true,
|
|
58907
|
+
checks: ["retrieval citations", "policy review", "answer quality"],
|
|
58908
|
+
steps: [],
|
|
58909
|
+
parallelism: 2,
|
|
58910
|
+
gates: [
|
|
58911
|
+
{
|
|
58912
|
+
id: "quality",
|
|
58913
|
+
kind: "quality-score",
|
|
58914
|
+
description: "Answer meets tenant quality and citation requirements.",
|
|
58915
|
+
required: true
|
|
58916
|
+
}
|
|
58917
|
+
],
|
|
58918
|
+
nodes: [
|
|
58919
|
+
{
|
|
58920
|
+
id: "retrieve",
|
|
58921
|
+
agentRole: "researcher",
|
|
58922
|
+
description: "Retrieve tenant-scoped sources and produce citations.",
|
|
58923
|
+
requiredTools: ["knowledge_search"],
|
|
58924
|
+
risk: "read-only",
|
|
58925
|
+
timeoutMs: 3e4
|
|
58926
|
+
},
|
|
58927
|
+
{
|
|
58928
|
+
id: "draft-answer",
|
|
58929
|
+
agentRole: "docs",
|
|
58930
|
+
description: "Draft a concise answer grounded only in retrieved sources.",
|
|
58931
|
+
dependsOn: ["retrieve"],
|
|
58932
|
+
risk: "read-only",
|
|
58933
|
+
timeoutMs: 3e4
|
|
58934
|
+
},
|
|
58935
|
+
{
|
|
58936
|
+
id: "policy-review",
|
|
58937
|
+
agentRole: "reviewer",
|
|
58938
|
+
description: "Review citations, data boundary, and unsupported claims.",
|
|
58939
|
+
dependsOn: ["draft-answer"],
|
|
58940
|
+
gates: ["quality"],
|
|
58941
|
+
risk: "read-only",
|
|
58942
|
+
timeoutMs: 3e4
|
|
58943
|
+
}
|
|
58944
|
+
]
|
|
58945
|
+
},
|
|
58946
|
+
{
|
|
58947
|
+
id: "whatsapp-support-assistant",
|
|
58948
|
+
name: "WhatsApp Support Assistant",
|
|
58949
|
+
description: "Handle a WhatsApp customer message with retrieval, support draft, and optional escalation.",
|
|
58950
|
+
inputSchema: "message: string; phoneNumber: string; tenantId: string",
|
|
58951
|
+
outputKind: "json",
|
|
58952
|
+
replayable: true,
|
|
58953
|
+
checks: ["retrieval citations", "support policy", "human escalation when needed"],
|
|
58954
|
+
steps: [],
|
|
58955
|
+
parallelism: 2,
|
|
58956
|
+
gates: [
|
|
58957
|
+
{
|
|
58958
|
+
id: "human-escalation",
|
|
58959
|
+
kind: "human-approval",
|
|
58960
|
+
description: "Human review is required before sensitive or external follow-up.",
|
|
58961
|
+
required: false
|
|
58962
|
+
}
|
|
58963
|
+
],
|
|
58964
|
+
nodes: [
|
|
58965
|
+
{
|
|
58966
|
+
id: "classify-message",
|
|
58967
|
+
agentRole: "planner",
|
|
58968
|
+
description: "Classify intent, urgency, and required data boundary.",
|
|
58969
|
+
risk: "read-only",
|
|
58970
|
+
timeoutMs: 15e3
|
|
58971
|
+
},
|
|
58972
|
+
{
|
|
58973
|
+
id: "retrieve-context",
|
|
58974
|
+
agentRole: "researcher",
|
|
58975
|
+
description: "Retrieve tenant support knowledge relevant to the customer message.",
|
|
58976
|
+
dependsOn: ["classify-message"],
|
|
58977
|
+
requiredTools: ["knowledge_search"],
|
|
58978
|
+
risk: "read-only",
|
|
58979
|
+
timeoutMs: 3e4
|
|
58980
|
+
},
|
|
58981
|
+
{
|
|
58982
|
+
id: "draft-response",
|
|
58983
|
+
agentRole: "docs",
|
|
58984
|
+
description: "Draft a WhatsApp-safe response with concise citations for audit.",
|
|
58985
|
+
dependsOn: ["retrieve-context"],
|
|
58986
|
+
requiredTools: ["create_support_draft"],
|
|
58987
|
+
risk: "read-only",
|
|
58988
|
+
timeoutMs: 3e4
|
|
58989
|
+
},
|
|
58990
|
+
{
|
|
58991
|
+
id: "escalate-if-needed",
|
|
58992
|
+
agentRole: "integrator",
|
|
58993
|
+
description: "Create a human escalation request when classification requires it.",
|
|
58994
|
+
dependsOn: ["draft-response"],
|
|
58995
|
+
requiredTools: ["request_human_escalation"],
|
|
58996
|
+
gates: ["human-escalation"],
|
|
58997
|
+
condition: "input.requiresEscalation",
|
|
58998
|
+
risk: "network",
|
|
58999
|
+
timeoutMs: 3e4
|
|
59000
|
+
}
|
|
59001
|
+
]
|
|
59002
|
+
},
|
|
58450
59003
|
{
|
|
58451
59004
|
id: "architect-editor-verifier",
|
|
58452
59005
|
name: "Architect / Editor / Verifier",
|
|
@@ -58592,11 +59145,13 @@ var WorkflowEngine = class {
|
|
|
58592
59145
|
this.eventLog = eventLog;
|
|
58593
59146
|
this.sharedState = options.sharedState ?? new InMemorySharedWorkspaceStore();
|
|
58594
59147
|
this.nodeExecutor = options.nodeExecutor;
|
|
59148
|
+
this.runtimePolicy = options.runtimePolicy;
|
|
58595
59149
|
}
|
|
58596
59150
|
catalog;
|
|
58597
59151
|
eventLog;
|
|
58598
59152
|
handlers = /* @__PURE__ */ new Map();
|
|
58599
59153
|
sharedState;
|
|
59154
|
+
runtimePolicy;
|
|
58600
59155
|
nodeExecutor;
|
|
58601
59156
|
registerHandler(workflowId, handler) {
|
|
58602
59157
|
if (!this.catalog.get(workflowId)) {
|
|
@@ -58627,6 +59182,8 @@ var WorkflowEngine = class {
|
|
|
58627
59182
|
trace
|
|
58628
59183
|
});
|
|
58629
59184
|
try {
|
|
59185
|
+
const graph = workflowToAgentGraph(workflow);
|
|
59186
|
+
assertWorkflowAllowedByRuntimePolicy(graph, this.runtimePolicy);
|
|
58630
59187
|
const graphResult = handler ? void 0 : await new AgentGraphEngine({
|
|
58631
59188
|
eventLog: this.eventLog,
|
|
58632
59189
|
sharedState: this.sharedState,
|
|
@@ -58634,7 +59191,7 @@ var WorkflowEngine = class {
|
|
|
58634
59191
|
trace
|
|
58635
59192
|
}).run({
|
|
58636
59193
|
workflowRunId: runId,
|
|
58637
|
-
graph
|
|
59194
|
+
graph,
|
|
58638
59195
|
input: request.input
|
|
58639
59196
|
});
|
|
58640
59197
|
const output = graphResult ?? await handler(request.input, {
|
|
@@ -58686,6 +59243,29 @@ var WorkflowEngine = class {
|
|
|
58686
59243
|
}
|
|
58687
59244
|
}
|
|
58688
59245
|
};
|
|
59246
|
+
function assertWorkflowAllowedByRuntimePolicy(graph, policy) {
|
|
59247
|
+
if (!policy) return;
|
|
59248
|
+
for (const node of graph.nodes) {
|
|
59249
|
+
const risk = node.risk ?? "read-only";
|
|
59250
|
+
const riskDecision = evaluateRuntimeRiskPolicy(policy, {
|
|
59251
|
+
subject: `workflow node ${node.id}`,
|
|
59252
|
+
risk
|
|
59253
|
+
});
|
|
59254
|
+
if (!riskDecision.allowed) {
|
|
59255
|
+
throw new Error(
|
|
59256
|
+
`Workflow node ${node.id} is blocked by runtime policy: ${riskDecision.reason}`
|
|
59257
|
+
);
|
|
59258
|
+
}
|
|
59259
|
+
for (const toolName of node.requiredTools ?? []) {
|
|
59260
|
+
const decision = evaluateRuntimeToolPolicy(policy, { toolName, risk });
|
|
59261
|
+
if (!decision.allowed) {
|
|
59262
|
+
throw new Error(
|
|
59263
|
+
`Workflow node ${node.id} is blocked by runtime policy: ${decision.reason}`
|
|
59264
|
+
);
|
|
59265
|
+
}
|
|
59266
|
+
}
|
|
59267
|
+
}
|
|
59268
|
+
}
|
|
58689
59269
|
function createWorkflowEngine(catalog, eventLog, options) {
|
|
58690
59270
|
return new WorkflowEngine(catalog, eventLog, options);
|
|
58691
59271
|
}
|
|
@@ -58695,15 +59275,17 @@ var AgentRuntime = class {
|
|
|
58695
59275
|
constructor(options) {
|
|
58696
59276
|
this.options = options;
|
|
58697
59277
|
this.providerRegistry = createProviderRegistry();
|
|
58698
|
-
this.toolRegistry = options.toolRegistry ??
|
|
59278
|
+
this.toolRegistry = options.toolRegistry ?? new ToolRegistry();
|
|
58699
59279
|
this.sessionStore = options.sessionStore;
|
|
58700
59280
|
this.runtimeSessionStore = options.runtimeSessionStore ?? createRuntimeSessionStore();
|
|
58701
59281
|
this.eventLog = options.eventLog ?? (options.eventLogPath ? createFileEventLog(options.eventLogPath) : createEventLog());
|
|
58702
|
-
this.workflowEngine = options.workflowEngine ?? createWorkflowEngine(void 0, this.eventLog);
|
|
58703
59282
|
this.permissionPolicy = options.permissionPolicy ?? createPermissionPolicy();
|
|
58704
59283
|
this.turnRunner = options.turnRunner ?? createDefaultRuntimeTurnRunner();
|
|
58705
59284
|
this.providerType = options.providerType;
|
|
58706
59285
|
this.model = options.model ?? options.providerConfig?.model ?? getDefaultModel(options.providerType);
|
|
59286
|
+
this.runtimeContext = options.runtimeContext ? createRuntimeRequestContext(options.runtimeContext) : void 0;
|
|
59287
|
+
this.runtimePolicy = mergeRuntimePolicy(this.runtimeContext?.policy, options.runtimePolicy);
|
|
59288
|
+
this.workflowEngine = options.workflowEngine ?? createWorkflowEngine(void 0, this.eventLog, { runtimePolicy: this.runtimePolicy });
|
|
58707
59289
|
}
|
|
58708
59290
|
options;
|
|
58709
59291
|
providerRegistry;
|
|
@@ -58717,6 +59299,8 @@ var AgentRuntime = class {
|
|
|
58717
59299
|
providerType;
|
|
58718
59300
|
model;
|
|
58719
59301
|
provider;
|
|
59302
|
+
runtimeContext;
|
|
59303
|
+
runtimePolicy;
|
|
58720
59304
|
async initialize() {
|
|
58721
59305
|
const providerInjected = Boolean(this.options.provider);
|
|
58722
59306
|
const provider = this.options.provider ?? await this.providerRegistry.createProvider(this.providerType, {
|
|
@@ -58747,8 +59331,8 @@ var AgentRuntime = class {
|
|
|
58747
59331
|
}
|
|
58748
59332
|
publishToGlobalBridge(provider) {
|
|
58749
59333
|
if (this.options.publishToGlobalBridge !== true) return;
|
|
58750
|
-
setAgentProvider(provider);
|
|
58751
|
-
setAgentToolRegistry(this.toolRegistry);
|
|
59334
|
+
this.options.legacyAgentBridge?.setAgentProvider(provider);
|
|
59335
|
+
this.options.legacyAgentBridge?.setAgentToolRegistry(this.toolRegistry);
|
|
58752
59336
|
}
|
|
58753
59337
|
snapshot() {
|
|
58754
59338
|
const capability = this.providerRegistry.getCapability(this.providerType, this.getModel());
|
|
@@ -58763,14 +59347,25 @@ var AgentRuntime = class {
|
|
|
58763
59347
|
count: toolNames.length,
|
|
58764
59348
|
names: toolNames
|
|
58765
59349
|
},
|
|
58766
|
-
modes: listAgentModes()
|
|
59350
|
+
modes: listAgentModes(),
|
|
59351
|
+
context: this.runtimeContext,
|
|
59352
|
+
policy: this.runtimePolicy
|
|
58767
59353
|
};
|
|
58768
59354
|
}
|
|
58769
59355
|
createSession(options = {}) {
|
|
58770
|
-
const session = this.runtimeSessionStore.create(
|
|
59356
|
+
const session = this.runtimeSessionStore.create({
|
|
59357
|
+
...options,
|
|
59358
|
+
metadata: {
|
|
59359
|
+
...runtimeContextToMetadata(this.runtimeContext),
|
|
59360
|
+
...options.metadata
|
|
59361
|
+
}
|
|
59362
|
+
});
|
|
58771
59363
|
this.eventLog.record("session.created", {
|
|
58772
59364
|
sessionId: session.id,
|
|
58773
59365
|
mode: session.mode,
|
|
59366
|
+
...session.metadata["tenantId"] ? { tenantId: session.metadata["tenantId"] } : {},
|
|
59367
|
+
...session.metadata["surface"] ? { surface: session.metadata["surface"] } : {},
|
|
59368
|
+
...session.metadata["correlationId"] ? { correlationId: session.metadata["correlationId"] } : {},
|
|
58774
59369
|
metadataKeys: Object.keys(session.metadata).sort()
|
|
58775
59370
|
});
|
|
58776
59371
|
return session;
|
|
@@ -58807,6 +59402,7 @@ var AgentRuntime = class {
|
|
|
58807
59402
|
permissionPolicy: this.permissionPolicy,
|
|
58808
59403
|
eventLog: this.eventLog
|
|
58809
59404
|
});
|
|
59405
|
+
assertRuntimeUsageWithinPolicy(this.runtimePolicy, result.usage);
|
|
58810
59406
|
const updatedSession = this.runtimeSessionStore.update({
|
|
58811
59407
|
...effectiveSession,
|
|
58812
59408
|
messages: [
|
|
@@ -58884,16 +59480,8 @@ var AgentRuntime = class {
|
|
|
58884
59480
|
};
|
|
58885
59481
|
}
|
|
58886
59482
|
}
|
|
58887
|
-
const updatedSession = this.runtimeSessionStore.update({
|
|
58888
|
-
...effectiveSession,
|
|
58889
|
-
messages: [
|
|
58890
|
-
...effectiveSession.messages,
|
|
58891
|
-
{ role: "user", content: input.content },
|
|
58892
|
-
{ role: "assistant", content }
|
|
58893
|
-
]
|
|
58894
|
-
});
|
|
58895
59483
|
const result = {
|
|
58896
|
-
sessionId:
|
|
59484
|
+
sessionId: effectiveSession.id,
|
|
58897
59485
|
content,
|
|
58898
59486
|
usage: {
|
|
58899
59487
|
inputTokens: provider.countTokens(input.content),
|
|
@@ -58901,8 +59489,19 @@ var AgentRuntime = class {
|
|
|
58901
59489
|
estimated: true
|
|
58902
59490
|
},
|
|
58903
59491
|
model: input.options?.model ?? this.getModel(),
|
|
58904
|
-
mode:
|
|
59492
|
+
mode: effectiveSession.mode
|
|
58905
59493
|
};
|
|
59494
|
+
assertRuntimeUsageWithinPolicy(this.runtimePolicy, result.usage);
|
|
59495
|
+
const updatedSession = this.runtimeSessionStore.update({
|
|
59496
|
+
...effectiveSession,
|
|
59497
|
+
messages: [
|
|
59498
|
+
...effectiveSession.messages,
|
|
59499
|
+
{ role: "user", content: input.content },
|
|
59500
|
+
{ role: "assistant", content }
|
|
59501
|
+
]
|
|
59502
|
+
});
|
|
59503
|
+
result.sessionId = updatedSession.id;
|
|
59504
|
+
result.mode = updatedSession.mode;
|
|
58906
59505
|
this.eventLog.record("session.updated", {
|
|
58907
59506
|
sessionId: updatedSession.id,
|
|
58908
59507
|
messages: updatedSession.messages.length
|
|
@@ -58990,15 +59589,22 @@ var AgentRuntime = class {
|
|
|
58990
59589
|
};
|
|
58991
59590
|
}
|
|
58992
59591
|
const decision = this.permissionPolicy.canExecuteToolInput ? this.permissionPolicy.canExecuteToolInput(mode, tool, input.input) : this.permissionPolicy.canExecuteTool(mode, tool);
|
|
58993
|
-
|
|
58994
|
-
|
|
59592
|
+
const runtimeDecision = decision.allowed ? evaluateRuntimeToolPolicy(this.runtimePolicy, {
|
|
59593
|
+
toolName: input.toolName,
|
|
59594
|
+
risk: decision.risk,
|
|
59595
|
+
confirmed: input.confirmed
|
|
59596
|
+
}) : void 0;
|
|
59597
|
+
const effectiveDecision = runtimeDecision ?? decision;
|
|
59598
|
+
if (!decision.allowed || !effectiveDecision.allowed || decision.requiresConfirmation && input.confirmed !== true) {
|
|
59599
|
+
const reason = effectiveDecision.reason ?? decision.reason ?? (decision.requiresConfirmation ? "Tool requires explicit runtime confirmation." : "Tool is not allowed.");
|
|
58995
59600
|
this.eventLog.record("tool.blocked", {
|
|
58996
59601
|
sessionId: input.sessionId,
|
|
58997
59602
|
mode,
|
|
58998
59603
|
tool: input.toolName,
|
|
58999
59604
|
reason,
|
|
59000
|
-
risk:
|
|
59001
|
-
requiresConfirmation: decision.requiresConfirmation,
|
|
59605
|
+
risk: effectiveDecision.risk,
|
|
59606
|
+
requiresConfirmation: effectiveDecision.requiresConfirmation ?? decision.requiresConfirmation,
|
|
59607
|
+
runtimePolicyBlocked: runtimeDecision ? !runtimeDecision.allowed : false,
|
|
59002
59608
|
runtimeApi: true
|
|
59003
59609
|
});
|
|
59004
59610
|
return {
|
|
@@ -59006,14 +59612,20 @@ var AgentRuntime = class {
|
|
|
59006
59612
|
success: false,
|
|
59007
59613
|
error: reason,
|
|
59008
59614
|
duration: performance.now() - startedAt,
|
|
59009
|
-
decision
|
|
59615
|
+
decision: {
|
|
59616
|
+
...decision,
|
|
59617
|
+
allowed: false,
|
|
59618
|
+
reason,
|
|
59619
|
+
requiresConfirmation: effectiveDecision.requiresConfirmation ?? decision.requiresConfirmation,
|
|
59620
|
+
risk: effectiveDecision.risk
|
|
59621
|
+
}
|
|
59010
59622
|
};
|
|
59011
59623
|
}
|
|
59012
59624
|
this.eventLog.record("tool.started", {
|
|
59013
59625
|
sessionId: input.sessionId,
|
|
59014
59626
|
mode,
|
|
59015
59627
|
tool: input.toolName,
|
|
59016
|
-
risk:
|
|
59628
|
+
risk: effectiveDecision.risk,
|
|
59017
59629
|
runtimeApi: true,
|
|
59018
59630
|
metadataKeys: Object.keys(input.metadata ?? {}).sort()
|
|
59019
59631
|
});
|
|
@@ -59032,7 +59644,11 @@ var AgentRuntime = class {
|
|
|
59032
59644
|
output: result.data,
|
|
59033
59645
|
error: result.error,
|
|
59034
59646
|
duration: result.duration,
|
|
59035
|
-
decision
|
|
59647
|
+
decision: {
|
|
59648
|
+
...decision,
|
|
59649
|
+
risk: effectiveDecision.risk,
|
|
59650
|
+
requiresConfirmation: decision.requiresConfirmation
|
|
59651
|
+
}
|
|
59036
59652
|
};
|
|
59037
59653
|
}
|
|
59038
59654
|
assertToolAllowed(mode, toolName, input) {
|
|
@@ -59046,12 +59662,24 @@ var AgentRuntime = class {
|
|
|
59046
59662
|
return false;
|
|
59047
59663
|
}
|
|
59048
59664
|
const decision = input && this.permissionPolicy.canExecuteToolInput ? this.permissionPolicy.canExecuteToolInput(mode, tool, input) : this.permissionPolicy.canExecuteTool(mode, tool);
|
|
59049
|
-
|
|
59665
|
+
const runtimeDecision = decision.allowed ? evaluateRuntimeToolPolicy(this.runtimePolicy, {
|
|
59666
|
+
toolName,
|
|
59667
|
+
risk: decision.risk,
|
|
59668
|
+
confirmed: false
|
|
59669
|
+
}) : void 0;
|
|
59670
|
+
const allowed = decision.allowed && runtimeDecision?.allowed !== false;
|
|
59671
|
+
this.eventLog.record(allowed ? "tool.allowed" : "tool.blocked", {
|
|
59050
59672
|
mode,
|
|
59051
59673
|
tool: toolName,
|
|
59052
|
-
...decision
|
|
59674
|
+
...decision,
|
|
59675
|
+
...runtimeDecision && !runtimeDecision.allowed ? {
|
|
59676
|
+
allowed: false,
|
|
59677
|
+
reason: runtimeDecision.reason,
|
|
59678
|
+
requiresConfirmation: runtimeDecision.requiresConfirmation,
|
|
59679
|
+
runtimePolicyBlocked: true
|
|
59680
|
+
} : {}
|
|
59053
59681
|
});
|
|
59054
|
-
return
|
|
59682
|
+
return allowed;
|
|
59055
59683
|
}
|
|
59056
59684
|
};
|
|
59057
59685
|
async function createAgentRuntime(options) {
|
|
@@ -59729,8 +60357,10 @@ async function startRepl(options = {}) {
|
|
|
59729
60357
|
providerType: internalProviderId,
|
|
59730
60358
|
model: session.config.provider.model || void 0,
|
|
59731
60359
|
provider,
|
|
60360
|
+
toolRegistry: createFullToolRegistry(),
|
|
59732
60361
|
eventLogPath: path39__default.join(projectPath, ".coco", "events", `${session.id}.jsonl`),
|
|
59733
|
-
publishToGlobalBridge: true
|
|
60362
|
+
publishToGlobalBridge: true,
|
|
60363
|
+
legacyAgentBridge: { setAgentProvider, setAgentToolRegistry }
|
|
59734
60364
|
});
|
|
59735
60365
|
session.runtime = runtime;
|
|
59736
60366
|
const toolRegistry = runtime.toolRegistry;
|
|
@@ -61005,9 +61635,11 @@ ${stdinContent}
|
|
|
61005
61635
|
providerType,
|
|
61006
61636
|
model: session.config.provider.model || void 0,
|
|
61007
61637
|
provider,
|
|
61638
|
+
toolRegistry: createFullToolRegistry(),
|
|
61008
61639
|
eventLogPath: path39__default.join(options.projectPath, ".coco", "events", `${session.id}.jsonl`),
|
|
61009
61640
|
turnRunner: options.useRuntimeRunner ? createToolCallingRuntimeTurnRunner() : void 0,
|
|
61010
|
-
publishToGlobalBridge: true
|
|
61641
|
+
publishToGlobalBridge: true,
|
|
61642
|
+
legacyAgentBridge: { setAgentProvider, setAgentToolRegistry }
|
|
61011
61643
|
});
|
|
61012
61644
|
session.runtime = runtime;
|
|
61013
61645
|
const toolRegistry = runtime.toolRegistry;
|