@wrongstack/core 0.54.1 → 0.66.13
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/{agent-bridge-Dnhw4tnM.d.ts → agent-bridge-D-j6OOBT.d.ts} +1 -1
- package/dist/agent-subagent-runner-DRZ9-NnR.d.ts +1042 -0
- package/dist/{compactor-Duhsf0ge.d.ts → compactor-D_ExJajC.d.ts} +1 -1
- package/dist/{config-bht0txXS.d.ts → config--86aHSln.d.ts} +112 -2
- package/dist/{context-DtPKqKYV.d.ts → context-y87Jc5ei.d.ts} +8 -8
- package/dist/coordination/index.d.ts +12 -12
- package/dist/coordination/index.js +87 -69
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +22 -22
- package/dist/defaults/index.js +365 -174
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-CbHTS4ZZ.d.ts → events-CIplI98R.d.ts} +20 -1
- package/dist/execution/index.d.ts +16 -385
- package/dist/execution/index.js +129 -61
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +7 -7
- package/dist/goal-store-C7jcumEh.d.ts +96 -0
- package/dist/index-DKUvyTvV.d.ts +560 -0
- package/dist/{index-ge5F2dnc.d.ts → index-b5uhfTSl.d.ts} +10 -8
- package/dist/index.d.ts +59 -33
- package/dist/index.js +1138 -733
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +1 -1
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +9 -9
- package/dist/kernel/index.js +3 -1
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-DE6gzBry.d.ts → mcp-servers-DwoNBf6r.d.ts} +3 -3
- package/dist/models/index.d.ts +2 -2
- package/dist/{multi-agent-coordinator-CjNX4uBD.d.ts → multi-agent-coordinator-CWnH-CiX.d.ts} +10 -2
- package/dist/{null-fleet-bus-BNiSlTna.d.ts → null-fleet-bus-VApKRxcp.d.ts} +6 -7
- package/dist/observability/index.d.ts +2 -2
- package/dist/parallel-eternal-engine-0UwotoSx.d.ts +483 -0
- package/dist/{path-resolver-Bax85amb.d.ts → path-resolver-DVkEcIw8.d.ts} +2 -2
- package/dist/{permission-Drm7LpPo.d.ts → permission-C1A5whY5.d.ts} +17 -1
- package/dist/{permission-policy-CU6sqWxF.d.ts → permission-policy-B2dK-T5N.d.ts} +28 -7
- package/dist/{plan-templates-CLRcurWN.d.ts → plan-templates-Bprrzhbu.d.ts} +4 -4
- package/dist/{provider-runner-BikCxGCx.d.ts → provider-runner-mXvXGSIw.d.ts} +3 -3
- package/dist/{retry-policy-Chtlvr5b.d.ts → retry-policy-CG3qvH_e.d.ts} +1 -1
- package/dist/sdd/index.d.ts +9 -9
- package/dist/sdd/index.js +59 -52
- package/dist/sdd/index.js.map +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/security/index.js +144 -33
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-BvSPdJj6.d.ts → selector-RvBR_YRW.d.ts} +1 -1
- package/dist/session-event-bridge-CDHxcmQU.d.ts +93 -0
- package/dist/{session-reader-BGhzMir4.d.ts → session-reader-BIpwM60D.d.ts} +1 -1
- package/dist/storage/index.d.ts +7 -6
- package/dist/{system-prompt-dtzV_mLm.d.ts → system-prompt-b61lOd49.d.ts} +32 -2
- package/dist/types/index.d.ts +23 -14
- package/dist/types/index.js +62 -6
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/multi-agent/SKILL.md +0 -2
- package/dist/agent-subagent-runner-By7jruZ_.d.ts +0 -182
- package/dist/goal-store-DwcTDDiX.d.ts +0 -188
- package/dist/index-CI271MjL.d.ts +0 -903
- package/dist/multi-agent-BmC_xiog.d.ts +0 -554
- package/dist/tool-executor-CgU0yWpB.d.ts +0 -110
package/dist/index.js
CHANGED
|
@@ -93,7 +93,7 @@ async function renameWithRetry(from, to) {
|
|
|
93
93
|
if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
|
|
94
94
|
throw err;
|
|
95
95
|
}
|
|
96
|
-
await new Promise((
|
|
96
|
+
await new Promise((resolve13) => setTimeout(resolve13, delays[i]));
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
throw lastErr;
|
|
@@ -884,7 +884,9 @@ var TOKENS = {
|
|
|
884
884
|
/** Optional git-worktree lifecycle manager (per-phase isolation in AutoPhase). */
|
|
885
885
|
WorktreeManager: t("WorktreeManager"),
|
|
886
886
|
/** Optional global Brain arbiter for policy/decision escalation. */
|
|
887
|
-
BrainArbiter: t("BrainArbiter")
|
|
887
|
+
BrainArbiter: t("BrainArbiter"),
|
|
888
|
+
/** Lifecycle hook registry (shell + in-process hooks). */
|
|
889
|
+
HookRegistry: t("HookRegistry")
|
|
888
890
|
};
|
|
889
891
|
|
|
890
892
|
// src/kernel/run-controller.ts
|
|
@@ -2058,7 +2060,7 @@ var DefaultPathResolver = class {
|
|
|
2058
2060
|
var NETWORK_ERR_RE = /ECONN|ETIMEDOUT|ETIME|ENOTFOUND|EAI_AGAIN|fetch failed/i;
|
|
2059
2061
|
|
|
2060
2062
|
// src/execution/error-handler.ts
|
|
2061
|
-
var CONTEXT_OVERFLOW_RE = /context|too long|tokens/i;
|
|
2063
|
+
var CONTEXT_OVERFLOW_RE = /context|too long|tokens|exceeds the context window|context window/i;
|
|
2062
2064
|
function buildRecoveryStrategies(opts) {
|
|
2063
2065
|
return [
|
|
2064
2066
|
{
|
|
@@ -2066,7 +2068,7 @@ function buildRecoveryStrategies(opts) {
|
|
|
2066
2068
|
compactor: opts?.compactor,
|
|
2067
2069
|
async attempt(err, ctx) {
|
|
2068
2070
|
if (!(err instanceof ProviderError)) return null;
|
|
2069
|
-
if (err.status !== 413 && !
|
|
2071
|
+
if (err.status !== 413 && !isContextOverflowError(err)) return null;
|
|
2070
2072
|
if (this.compactor) {
|
|
2071
2073
|
try {
|
|
2072
2074
|
const report = await this.compactor.compact(ctx, { aggressive: true });
|
|
@@ -2129,6 +2131,14 @@ function buildRecoveryStrategies(opts) {
|
|
|
2129
2131
|
];
|
|
2130
2132
|
}
|
|
2131
2133
|
var DEFAULT_RECOVERY_STRATEGIES = buildRecoveryStrategies();
|
|
2134
|
+
function isContextOverflowError(err) {
|
|
2135
|
+
return CONTEXT_OVERFLOW_RE.test([
|
|
2136
|
+
err.message,
|
|
2137
|
+
err.body?.message,
|
|
2138
|
+
err.body?.type,
|
|
2139
|
+
err.body?.raw
|
|
2140
|
+
].filter(Boolean).join("\n"));
|
|
2141
|
+
}
|
|
2132
2142
|
var DefaultErrorHandler = class {
|
|
2133
2143
|
strategies;
|
|
2134
2144
|
constructor(strategies = DEFAULT_RECOVERY_STRATEGIES) {
|
|
@@ -2145,7 +2155,7 @@ var DefaultErrorHandler = class {
|
|
|
2145
2155
|
if (err.status === 429) return { kind: "rate_limit", retryable: true };
|
|
2146
2156
|
if (err.status === 529) return { kind: "overloaded", retryable: true };
|
|
2147
2157
|
if (err.status >= 500) return { kind: "server", retryable: true };
|
|
2148
|
-
if (err.status === 413 ||
|
|
2158
|
+
if (err.status === 413 || isContextOverflowError(err)) {
|
|
2149
2159
|
return { kind: "context_overflow", retryable: false };
|
|
2150
2160
|
}
|
|
2151
2161
|
if (err.status >= 400) return { kind: "client", retryable: false };
|
|
@@ -3049,7 +3059,7 @@ var InMemoryAgentBridge = class {
|
|
|
3049
3059
|
);
|
|
3050
3060
|
}
|
|
3051
3061
|
this.inflightGuards.add(correlationId);
|
|
3052
|
-
return new Promise((
|
|
3062
|
+
return new Promise((resolve13, reject) => {
|
|
3053
3063
|
const timer = setTimeout(() => {
|
|
3054
3064
|
this.inflightGuards.delete(correlationId);
|
|
3055
3065
|
this.pendingRequests.delete(correlationId);
|
|
@@ -3061,7 +3071,7 @@ var InMemoryAgentBridge = class {
|
|
|
3061
3071
|
return;
|
|
3062
3072
|
}
|
|
3063
3073
|
this.pendingRequests.set(correlationId, {
|
|
3064
|
-
resolve:
|
|
3074
|
+
resolve: resolve13,
|
|
3065
3075
|
reject,
|
|
3066
3076
|
timer
|
|
3067
3077
|
});
|
|
@@ -3254,11 +3264,11 @@ function validateAgainstSchema(value, schema) {
|
|
|
3254
3264
|
walk2(value, schema, "", errors);
|
|
3255
3265
|
return { ok: errors.length === 0, errors };
|
|
3256
3266
|
}
|
|
3257
|
-
function walk2(value, schema,
|
|
3267
|
+
function walk2(value, schema, path37, errors) {
|
|
3258
3268
|
if (schema.enum !== void 0) {
|
|
3259
3269
|
if (!schema.enum.some((e) => deepEqual(e, value))) {
|
|
3260
3270
|
errors.push({
|
|
3261
|
-
path:
|
|
3271
|
+
path: path37 || "<root>",
|
|
3262
3272
|
message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
|
|
3263
3273
|
});
|
|
3264
3274
|
return;
|
|
@@ -3267,7 +3277,7 @@ function walk2(value, schema, path36, errors) {
|
|
|
3267
3277
|
if (typeof schema.type === "string") {
|
|
3268
3278
|
if (!checkType(value, schema.type)) {
|
|
3269
3279
|
errors.push({
|
|
3270
|
-
path:
|
|
3280
|
+
path: path37 || "<root>",
|
|
3271
3281
|
message: `expected ${schema.type}, got ${describeType(value)}`
|
|
3272
3282
|
});
|
|
3273
3283
|
return;
|
|
@@ -3277,19 +3287,19 @@ function walk2(value, schema, path36, errors) {
|
|
|
3277
3287
|
const obj = value;
|
|
3278
3288
|
for (const req of schema.required ?? []) {
|
|
3279
3289
|
if (!(req in obj)) {
|
|
3280
|
-
errors.push({ path: joinPath(
|
|
3290
|
+
errors.push({ path: joinPath(path37, req), message: "required property missing" });
|
|
3281
3291
|
}
|
|
3282
3292
|
}
|
|
3283
3293
|
if (schema.properties) {
|
|
3284
3294
|
for (const [key, subSchema] of Object.entries(schema.properties)) {
|
|
3285
3295
|
if (key in obj) {
|
|
3286
|
-
walk2(obj[key], subSchema, joinPath(
|
|
3296
|
+
walk2(obj[key], subSchema, joinPath(path37, key), errors);
|
|
3287
3297
|
}
|
|
3288
3298
|
}
|
|
3289
3299
|
}
|
|
3290
3300
|
}
|
|
3291
3301
|
if (schema.type === "array" && Array.isArray(value) && schema.items) {
|
|
3292
|
-
value.forEach((item, i) => walk2(item, schema.items, `${
|
|
3302
|
+
value.forEach((item, i) => walk2(item, schema.items, `${path37}[${i}]`, errors));
|
|
3293
3303
|
}
|
|
3294
3304
|
}
|
|
3295
3305
|
function checkType(value, type) {
|
|
@@ -3385,6 +3395,29 @@ function createToolOutputSerializer(opts = {}) {
|
|
|
3385
3395
|
}
|
|
3386
3396
|
return { serialize, enforceCap, capBytes };
|
|
3387
3397
|
}
|
|
3398
|
+
function truncateForEvent(content, max = 400) {
|
|
3399
|
+
if (!content) return "";
|
|
3400
|
+
return content.length <= max ? content : `${content.slice(0, max - 1)}\u2026`;
|
|
3401
|
+
}
|
|
3402
|
+
function sizeSignals(toolName, content) {
|
|
3403
|
+
if (!content || content.length === 0) {
|
|
3404
|
+
return { outputBytes: 0, outputTokens: 0, outputLines: void 0 };
|
|
3405
|
+
}
|
|
3406
|
+
const outputBytes = Buffer.byteLength(content, "utf8");
|
|
3407
|
+
const outputTokens = Math.max(1, Math.round(outputBytes / 3.5));
|
|
3408
|
+
let outputLines;
|
|
3409
|
+
if (toolName === "read") {
|
|
3410
|
+
const lineRe = /^\s*\d+→/gm;
|
|
3411
|
+
let count = 0;
|
|
3412
|
+
while (lineRe.exec(content) !== null) count++;
|
|
3413
|
+
if (count > 0) outputLines = count;
|
|
3414
|
+
} else if (toolName === "bash" || toolName === "shell" || toolName === "grep" || toolName === "logs") {
|
|
3415
|
+
let nl = 0;
|
|
3416
|
+
for (let i = 0; i < content.length; i++) if (content.charCodeAt(i) === 10) nl++;
|
|
3417
|
+
outputLines = nl + (content.endsWith("\n") ? 0 : 1);
|
|
3418
|
+
}
|
|
3419
|
+
return { outputBytes, outputTokens, outputLines };
|
|
3420
|
+
}
|
|
3388
3421
|
|
|
3389
3422
|
// src/execution/tool-executor.ts
|
|
3390
3423
|
var ToolExecutor = class {
|
|
@@ -3415,8 +3448,9 @@ var ToolExecutor = class {
|
|
|
3415
3448
|
*/
|
|
3416
3449
|
async executeBatch(toolUses, ctx, strategy) {
|
|
3417
3450
|
let budget = this.opts.perIterationOutputCapBytes ?? 1e5;
|
|
3418
|
-
const runOne = async (
|
|
3451
|
+
const runOne = async (use0) => {
|
|
3419
3452
|
const start = Date.now();
|
|
3453
|
+
let use = use0;
|
|
3420
3454
|
const tool = this.registry.get(use.name);
|
|
3421
3455
|
if (!tool) {
|
|
3422
3456
|
const result = this.unknownToolResult(use, () => this.registry.list().map((t2) => t2.name));
|
|
@@ -3449,10 +3483,36 @@ Please call the tool again with arguments that match its inputSchema. You can us
|
|
|
3449
3483
|
budget = this.decrementBudget(result, budget);
|
|
3450
3484
|
return { result, tool, durationMs: Date.now() - start };
|
|
3451
3485
|
}
|
|
3486
|
+
if (this.opts.hookRunner?.has("PreToolUse")) {
|
|
3487
|
+
const pre = await this.opts.hookRunner.preToolUse(tool.name, use.input, ctx);
|
|
3488
|
+
if (pre.block) {
|
|
3489
|
+
const result = this.blockedByHookResult(use, pre.reason);
|
|
3490
|
+
budget = this.decrementBudget(result, budget);
|
|
3491
|
+
return { result, tool, durationMs: Date.now() - start };
|
|
3492
|
+
}
|
|
3493
|
+
if (pre.input) {
|
|
3494
|
+
const reval = validateAgainstSchema(pre.input, tool.inputSchema);
|
|
3495
|
+
if (!reval.ok) {
|
|
3496
|
+
const errorDetails = reval.errors.map((e) => ` - ${e.path || "input"}: ${e.message}`).join("\n");
|
|
3497
|
+
const result = {
|
|
3498
|
+
type: "tool_result",
|
|
3499
|
+
tool_use_id: use.id,
|
|
3500
|
+
content: `A PreToolUse hook rewrote the arguments for "${tool.name}" into an invalid shape.
|
|
3501
|
+
|
|
3502
|
+
Validation errors:
|
|
3503
|
+
${errorDetails}`,
|
|
3504
|
+
is_error: true
|
|
3505
|
+
};
|
|
3506
|
+
budget = this.decrementBudget(result, budget);
|
|
3507
|
+
return { result, tool, durationMs: Date.now() - start };
|
|
3508
|
+
}
|
|
3509
|
+
use = { ...use, input: pre.input };
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3452
3512
|
const decision = await this.opts.permissionPolicy.evaluate(tool, use.input, ctx);
|
|
3453
3513
|
let effectivePermission = decision.permission;
|
|
3454
3514
|
const policy = this.opts.permissionPolicy;
|
|
3455
|
-
const yolo = policy.getYolo?.() === true || policy.getForceAllYolo?.() === true;
|
|
3515
|
+
const yolo = policy.getYolo?.() === true || policy.getYoloDestructive?.() === true || policy.getForceAllYolo?.() === true;
|
|
3456
3516
|
if (toolDangerousCaps.length > 0 && effectivePermission === "auto" && !yolo) {
|
|
3457
3517
|
effectivePermission = "confirm";
|
|
3458
3518
|
}
|
|
@@ -3495,7 +3555,20 @@ Please call the tool again with arguments that match its inputSchema. You can us
|
|
|
3495
3555
|
"tool.has_dangerous_capabilities": toolCapsForAudit.length > 0
|
|
3496
3556
|
});
|
|
3497
3557
|
try {
|
|
3498
|
-
|
|
3558
|
+
let result = await this.executeTool(tool, use, ctx, budget);
|
|
3559
|
+
if (this.opts.hookRunner?.has("PostToolUse")) {
|
|
3560
|
+
const post = await this.opts.hookRunner.postToolUse(
|
|
3561
|
+
tool.name,
|
|
3562
|
+
use.input,
|
|
3563
|
+
{ content: String(result.content), isError: !!result.is_error },
|
|
3564
|
+
ctx
|
|
3565
|
+
);
|
|
3566
|
+
if (post.additionalContext) {
|
|
3567
|
+
result = { ...result, content: `${result.content}
|
|
3568
|
+
|
|
3569
|
+
${post.additionalContext}` };
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3499
3572
|
budget = this.decrementBudget(result, budget);
|
|
3500
3573
|
span?.setAttribute("tool.is_error", !!result.is_error);
|
|
3501
3574
|
span?.setAttribute(
|
|
@@ -3684,6 +3757,14 @@ ${excerpt}`;
|
|
|
3684
3757
|
is_error: true
|
|
3685
3758
|
};
|
|
3686
3759
|
}
|
|
3760
|
+
blockedByHookResult(use, reason) {
|
|
3761
|
+
return {
|
|
3762
|
+
type: "tool_result",
|
|
3763
|
+
tool_use_id: use.id,
|
|
3764
|
+
content: `Tool "${use.name}" was blocked by a PreToolUse hook: ${reason ?? "no reason given"}`,
|
|
3765
|
+
is_error: true
|
|
3766
|
+
};
|
|
3767
|
+
}
|
|
3687
3768
|
decrementBudget(result, budget) {
|
|
3688
3769
|
const contentBytes = typeof result.content === "string" ? Buffer.byteLength(result.content, "utf8") : Buffer.byteLength(JSON.stringify(result.content), "utf8");
|
|
3689
3770
|
return Math.max(0, budget - contentBytes);
|
|
@@ -6933,12 +7014,97 @@ var DirectorStateCheckpoint = class {
|
|
|
6933
7014
|
}
|
|
6934
7015
|
};
|
|
6935
7016
|
init_atomic_write();
|
|
7017
|
+
var DESTRUCTIVE_BASH_PATTERNS = [
|
|
7018
|
+
/\bgit\s+(?:clean\s+-[^\s]*[xdf]|reset\s+--hard)\b/i,
|
|
7019
|
+
/\b(?:drop|truncate)\s+(?:table|database|schema)\b/i,
|
|
7020
|
+
/\bdelete\s+from\b/i,
|
|
7021
|
+
/\b(?:mkfs|format|diskpart|shutdown|reboot)\b/i,
|
|
7022
|
+
/\bchmod\s+-R\s+777\b/i,
|
|
7023
|
+
/\bchown\s+-R\b/i,
|
|
7024
|
+
/\b(?:curl|wget)\b.*\|\s*(?:sh|bash|zsh|pwsh|powershell)\b/i,
|
|
7025
|
+
/\b(?:powershell|pwsh)\b.*(?:-encodedcommand|-enc)\b/i,
|
|
7026
|
+
/:\(\)\s*\{\s*:\|:&\s*}\s*;/
|
|
7027
|
+
];
|
|
7028
|
+
var PROJECT_ESCAPE_PATTERN = /(?:^|[\s"'])\.\.(?:[\\/]|$)/;
|
|
7029
|
+
var ABSOLUTE_PATH_PATTERN = /(?:^|[\s"'])(?:~[\\/]|\/[A-Za-z0-9_.-]|[A-Za-z]:[\\/])/;
|
|
7030
|
+
var SHELL_OPERATORS = /* @__PURE__ */ new Set(["&&", "||", "|", ";", ">", ">>", "<", "2>", "2>>"]);
|
|
7031
|
+
function getInputString(input, key) {
|
|
7032
|
+
if (!input || typeof input !== "object") return void 0;
|
|
7033
|
+
const value = input[key];
|
|
7034
|
+
return typeof value === "string" ? value : void 0;
|
|
7035
|
+
}
|
|
7036
|
+
function pathLooksInsideProject(rawPath, projectRoot) {
|
|
7037
|
+
if (!projectRoot) return false;
|
|
7038
|
+
if (rawPath === "~" || rawPath.startsWith("~/") || rawPath.startsWith("~\\")) return false;
|
|
7039
|
+
const resolved = path6.resolve(projectRoot, rawPath);
|
|
7040
|
+
const relative8 = path6.relative(projectRoot, resolved);
|
|
7041
|
+
return !!relative8 && !relative8.startsWith("..") && !path6.isAbsolute(relative8);
|
|
7042
|
+
}
|
|
7043
|
+
function tokenizeShell(command) {
|
|
7044
|
+
return command.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, "")) ?? [];
|
|
7045
|
+
}
|
|
7046
|
+
function pathTokenIsOutsideProject(token, projectRoot) {
|
|
7047
|
+
if (!token || SHELL_OPERATORS.has(token) || token.startsWith("-")) return false;
|
|
7048
|
+
if (token === "/" || token === "~" || token === "." || token === "..") return token !== ".";
|
|
7049
|
+
if (token.includes("*")) return true;
|
|
7050
|
+
if (token.startsWith("..") || token.includes("../") || token.includes("..\\")) return true;
|
|
7051
|
+
if (path6.isAbsolute(token) || token.startsWith("~/")) return !pathLooksInsideProject(token, projectRoot);
|
|
7052
|
+
return false;
|
|
7053
|
+
}
|
|
7054
|
+
function hasDangerousDeleteTarget(tokens, start, projectRoot) {
|
|
7055
|
+
const targets = tokens.slice(start).filter((token) => !token.startsWith("-") && !SHELL_OPERATORS.has(token));
|
|
7056
|
+
if (targets.length === 0) return true;
|
|
7057
|
+
return targets.some((target) => pathTokenIsOutsideProject(target, projectRoot));
|
|
7058
|
+
}
|
|
7059
|
+
function hasDestructiveDelete(command, projectRoot) {
|
|
7060
|
+
const tokens = tokenizeShell(command);
|
|
7061
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
7062
|
+
const token = tokens[i]?.toLowerCase();
|
|
7063
|
+
if (!token) continue;
|
|
7064
|
+
if (token === "rm") {
|
|
7065
|
+
const args = tokens.slice(i + 1);
|
|
7066
|
+
const recursiveOrForce = args.some(
|
|
7067
|
+
(arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force"
|
|
7068
|
+
);
|
|
7069
|
+
if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
|
|
7070
|
+
}
|
|
7071
|
+
if (token === "rmdir" || token === "rd") {
|
|
7072
|
+
const args = tokens.slice(i + 1);
|
|
7073
|
+
const recursive = args.some((arg) => arg.toLowerCase() === "/s");
|
|
7074
|
+
if (recursive && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
|
|
7075
|
+
}
|
|
7076
|
+
if (token === "del" || token === "erase") {
|
|
7077
|
+
if (hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
|
|
7078
|
+
}
|
|
7079
|
+
if (token === "remove-item") {
|
|
7080
|
+
const args = tokens.slice(i + 1).map((arg) => arg.toLowerCase());
|
|
7081
|
+
const recursiveOrForce = args.includes("-recurse") || args.includes("-force");
|
|
7082
|
+
if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
return false;
|
|
7086
|
+
}
|
|
7087
|
+
function isClearlyDestructiveBashCommand(command, projectRoot) {
|
|
7088
|
+
const trimmed = command.trim();
|
|
7089
|
+
if (!trimmed) return false;
|
|
7090
|
+
if (hasDestructiveDelete(trimmed, projectRoot)) return true;
|
|
7091
|
+
if (DESTRUCTIVE_BASH_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
|
|
7092
|
+
if (/\bcd\s+(?:\.\.|~|\/|[A-Za-z]:[\\/])/i.test(trimmed)) return true;
|
|
7093
|
+
if (PROJECT_ESCAPE_PATTERN.test(trimmed)) return true;
|
|
7094
|
+
const absolute = trimmed.match(ABSOLUTE_PATH_PATTERN)?.[0]?.trim().replace(/^['"]|['"]$/g, "");
|
|
7095
|
+
if (absolute && !pathLooksInsideProject(absolute, projectRoot)) return true;
|
|
7096
|
+
return false;
|
|
7097
|
+
}
|
|
7098
|
+
|
|
7099
|
+
// src/security/permission-policy.ts
|
|
6936
7100
|
var DefaultPermissionPolicy = class {
|
|
6937
7101
|
policy = {};
|
|
6938
7102
|
loaded = false;
|
|
6939
7103
|
trustFile;
|
|
6940
7104
|
yolo;
|
|
6941
|
-
|
|
7105
|
+
yoloDestructive;
|
|
7106
|
+
/** When true, destructive ops still require confirmation even in YOLO mode. */
|
|
7107
|
+
confirmDestructive;
|
|
6942
7108
|
/**
|
|
6943
7109
|
* Session-scoped "soft deny" map. When the user presses 'n' (block once),
|
|
6944
7110
|
* the tool+pattern is added here. If the LLM retries in the same session,
|
|
@@ -6971,7 +7137,8 @@ var DefaultPermissionPolicy = class {
|
|
|
6971
7137
|
constructor(opts) {
|
|
6972
7138
|
this.trustFile = opts.trustFile;
|
|
6973
7139
|
this.yolo = opts.yolo ?? false;
|
|
6974
|
-
this.
|
|
7140
|
+
this.yoloDestructive = opts.yoloDestructive ?? opts.forceAllYolo ?? false;
|
|
7141
|
+
this.confirmDestructive = opts.confirmDestructive ?? false;
|
|
6975
7142
|
this.promptDelegate = opts.promptDelegate;
|
|
6976
7143
|
}
|
|
6977
7144
|
/**
|
|
@@ -6991,13 +7158,29 @@ var DefaultPermissionPolicy = class {
|
|
|
6991
7158
|
getYolo() {
|
|
6992
7159
|
return this.yolo;
|
|
6993
7160
|
}
|
|
6994
|
-
/** Toggle
|
|
7161
|
+
/** Toggle the destructive YOLO override at runtime. */
|
|
7162
|
+
setYoloDestructive(enabled) {
|
|
7163
|
+
this.yoloDestructive = enabled;
|
|
7164
|
+
}
|
|
7165
|
+
/** Check whether the destructive YOLO override is active. */
|
|
7166
|
+
getYoloDestructive() {
|
|
7167
|
+
return this.yoloDestructive;
|
|
7168
|
+
}
|
|
7169
|
+
/** Toggle destructive confirmation gate (only meaningful when yolo is active). */
|
|
7170
|
+
setConfirmDestructive(enabled) {
|
|
7171
|
+
this.confirmDestructive = enabled;
|
|
7172
|
+
}
|
|
7173
|
+
/** Check whether destructive confirmation gate is active. */
|
|
7174
|
+
getConfirmDestructive() {
|
|
7175
|
+
return this.confirmDestructive;
|
|
7176
|
+
}
|
|
7177
|
+
/** @deprecated Use `setYoloDestructive`. */
|
|
6995
7178
|
setForceAllYolo(enabled) {
|
|
6996
|
-
this.
|
|
7179
|
+
this.setYoloDestructive(enabled);
|
|
6997
7180
|
}
|
|
6998
|
-
/**
|
|
7181
|
+
/** @deprecated Use `getYoloDestructive`. */
|
|
6999
7182
|
getForceAllYolo() {
|
|
7000
|
-
return this.
|
|
7183
|
+
return this.getYoloDestructive();
|
|
7001
7184
|
}
|
|
7002
7185
|
async reload() {
|
|
7003
7186
|
try {
|
|
@@ -7044,29 +7227,28 @@ var DefaultPermissionPolicy = class {
|
|
|
7044
7227
|
return { permission: "auto", source: "trust" };
|
|
7045
7228
|
}
|
|
7046
7229
|
if (this.yolo) {
|
|
7047
|
-
if (
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
if (
|
|
7051
|
-
await this.
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
source: "user",
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
return { permission: "
|
|
7230
|
+
if (this.confirmDestructive) {
|
|
7231
|
+
const destructive = this.isDestructiveYoloCall(tool, input, ctx);
|
|
7232
|
+
if (destructive) {
|
|
7233
|
+
if (this.promptDelegate) {
|
|
7234
|
+
const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
|
|
7235
|
+
if (decision === "always") {
|
|
7236
|
+
await this.trust({ tool: tool.name, pattern: subject ?? tool.name });
|
|
7237
|
+
return { permission: "auto", source: "user", reason: "destructive yolo always-allowed" };
|
|
7238
|
+
}
|
|
7239
|
+
if (decision === "deny") {
|
|
7240
|
+
await this.deny({ tool: tool.name, pattern: subject ?? tool.name });
|
|
7241
|
+
return { permission: "deny", source: "user", reason: "user denied destructive yolo" };
|
|
7242
|
+
}
|
|
7243
|
+
return { permission: decision === "yes" ? "auto" : "deny", source: "user" };
|
|
7061
7244
|
}
|
|
7062
|
-
return {
|
|
7245
|
+
return {
|
|
7246
|
+
permission: "confirm",
|
|
7247
|
+
source: "yolo_destructive",
|
|
7248
|
+
riskTier: "destructive",
|
|
7249
|
+
reason: "destructive tool needs explicit approval (confirmDestructive is on)"
|
|
7250
|
+
};
|
|
7063
7251
|
}
|
|
7064
|
-
return {
|
|
7065
|
-
permission: "confirm",
|
|
7066
|
-
source: "yolo_destructive",
|
|
7067
|
-
riskTier: "destructive",
|
|
7068
|
-
reason: "destructive tool needs explicit approval even in yolo mode"
|
|
7069
|
-
};
|
|
7070
7252
|
}
|
|
7071
7253
|
return { permission: "auto", source: "yolo" };
|
|
7072
7254
|
}
|
|
@@ -7096,6 +7278,18 @@ var DefaultPermissionPolicy = class {
|
|
|
7096
7278
|
}
|
|
7097
7279
|
return { permission: "confirm", source: "default" };
|
|
7098
7280
|
}
|
|
7281
|
+
isDestructiveYoloCall(tool, input, ctx) {
|
|
7282
|
+
if (tool.name === "bash") {
|
|
7283
|
+
const command = getInputString(input, "command");
|
|
7284
|
+
return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;
|
|
7285
|
+
}
|
|
7286
|
+
if (tool.name === "write" || tool.name === "edit" || tool.name === "replace" || tool.name === "patch") {
|
|
7287
|
+
const targetPath = getInputString(input, "path") ?? getInputString(input, "file");
|
|
7288
|
+
if (!targetPath || !ctx.projectRoot) return false;
|
|
7289
|
+
return !pathLooksInsideProject(targetPath, ctx.projectRoot);
|
|
7290
|
+
}
|
|
7291
|
+
return tool.riskTier === "destructive";
|
|
7292
|
+
}
|
|
7099
7293
|
async trust(rule) {
|
|
7100
7294
|
if (!this.loaded) await this.reload();
|
|
7101
7295
|
const entry = this.policy[rule.tool] ?? {};
|
|
@@ -7566,8 +7760,8 @@ async function streamProviderToResponse(provider, req, signal, ctx, events) {
|
|
|
7566
7760
|
try {
|
|
7567
7761
|
await Promise.race([
|
|
7568
7762
|
Promise.resolve(iter.return?.()),
|
|
7569
|
-
new Promise((
|
|
7570
|
-
drainTimer = setTimeout(
|
|
7763
|
+
new Promise((resolve13) => {
|
|
7764
|
+
drainTimer = setTimeout(resolve13, 500);
|
|
7571
7765
|
})
|
|
7572
7766
|
]);
|
|
7573
7767
|
} finally {
|
|
@@ -7628,7 +7822,7 @@ async function runProviderWithRetry(opts) {
|
|
|
7628
7822
|
description
|
|
7629
7823
|
});
|
|
7630
7824
|
}
|
|
7631
|
-
await new Promise((
|
|
7825
|
+
await new Promise((resolve13, reject) => {
|
|
7632
7826
|
let settled = false;
|
|
7633
7827
|
const onAbort = () => {
|
|
7634
7828
|
if (settled) return;
|
|
@@ -7641,7 +7835,7 @@ async function runProviderWithRetry(opts) {
|
|
|
7641
7835
|
settled = true;
|
|
7642
7836
|
clearTimeout(t2);
|
|
7643
7837
|
signal.removeEventListener("abort", onAbort);
|
|
7644
|
-
|
|
7838
|
+
resolve13();
|
|
7645
7839
|
}, delay);
|
|
7646
7840
|
if (signal.aborted) {
|
|
7647
7841
|
onAbort();
|
|
@@ -9191,7 +9385,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
9191
9385
|
" \u2022 When this iteration's Task is finished (real artifact / passing",
|
|
9192
9386
|
" test / applied diff / clean output), emit `[done]` on its own line.",
|
|
9193
9387
|
" \u2022 Do not stop on the first obstacle \u2014 try at least 3 distinct",
|
|
9194
|
-
" approaches before giving up. YOLO is active
|
|
9388
|
+
" approaches before giving up. YOLO is active for normal project work;",
|
|
9389
|
+
" destructive-gated confirmations still belong to the permission flow.",
|
|
9195
9390
|
"",
|
|
9196
9391
|
"2. UPDATE TODO STATE (when Source is `todo`)",
|
|
9197
9392
|
" \u2022 Mark this todo `in_progress` via the todos tool before tool work.",
|
|
@@ -9320,7 +9515,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
9320
9515
|
}
|
|
9321
9516
|
};
|
|
9322
9517
|
function sleep(ms) {
|
|
9323
|
-
return new Promise((
|
|
9518
|
+
return new Promise((resolve13) => setTimeout(resolve13, ms));
|
|
9324
9519
|
}
|
|
9325
9520
|
|
|
9326
9521
|
// src/coordination/subagent-budget.ts
|
|
@@ -9536,12 +9731,12 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
9536
9731
|
if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
|
|
9537
9732
|
return Promise.resolve("stop");
|
|
9538
9733
|
}
|
|
9539
|
-
return new Promise((
|
|
9734
|
+
return new Promise((resolve13) => {
|
|
9540
9735
|
let resolved = false;
|
|
9541
9736
|
const respond = (d) => {
|
|
9542
9737
|
if (resolved) return;
|
|
9543
9738
|
resolved = true;
|
|
9544
|
-
|
|
9739
|
+
resolve13(d);
|
|
9545
9740
|
};
|
|
9546
9741
|
const fallback = setTimeout(
|
|
9547
9742
|
() => respond("stop"),
|
|
@@ -9612,15 +9807,22 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
9612
9807
|
void this.checkLimits();
|
|
9613
9808
|
}
|
|
9614
9809
|
/**
|
|
9615
|
-
* Wall-clock budget check.
|
|
9616
|
-
*
|
|
9617
|
-
*
|
|
9810
|
+
* Wall-clock / idle budget check. Delegates to `checkLimits(elapsed)`, so
|
|
9811
|
+
* `timeout` and `idle_timeout` follow the SAME negotiation path as the other
|
|
9812
|
+
* kinds — they are NOT a special-cased hard stop. This is deliberate: a
|
|
9813
|
+
* heartbeat-aware policy (see `attachAutoExtend` and `CollabSession`) grants
|
|
9814
|
+
* a timeout extension only while the agent is making progress and denies it
|
|
9815
|
+
* once the agent is genuinely stuck, which is safer than an unconditional
|
|
9816
|
+
* hard kill of a long-but-working agent. The runner translates the resulting
|
|
9817
|
+
* `BudgetThresholdSignal` decision (`extend` → patch limits in place,
|
|
9818
|
+
* `stop` → abort) just like every other kind.
|
|
9618
9819
|
*
|
|
9619
|
-
* Decision table:
|
|
9620
|
-
* - no `onThreshold` handler
|
|
9621
|
-
* - `mode === 'sync'` → throw `BudgetExceededError`
|
|
9622
|
-
* - `mode === 'auto'` + no listener
|
|
9623
|
-
* - `mode === 'auto'` + listener
|
|
9820
|
+
* Decision table (same as `checkLimits`):
|
|
9821
|
+
* - no `onThreshold` handler → throw `BudgetExceededError` (hard stop)
|
|
9822
|
+
* - `mode === 'sync'` → throw `BudgetExceededError` (hard stop)
|
|
9823
|
+
* - `mode === 'auto'` + no listener → throw `BudgetExceededError` (no one to ask)
|
|
9824
|
+
* - `mode === 'auto'` + listener → throw `BudgetThresholdSignal` (negotiated;
|
|
9825
|
+
* a heartbeat-aware policy may extend the timeout)
|
|
9624
9826
|
*/
|
|
9625
9827
|
checkTimeout() {
|
|
9626
9828
|
if (this.startTime === null) return;
|
|
@@ -12486,7 +12688,10 @@ var NICKNAME_POOL = {
|
|
|
12486
12688
|
"lavoisier": { name: "Lavoisier", domain: "chemistry" },
|
|
12487
12689
|
"mendeleev": { name: "Mendeleev", domain: "chemistry" }
|
|
12488
12690
|
};
|
|
12489
|
-
var ALL_NICKNAMES = Object.
|
|
12691
|
+
var ALL_NICKNAMES = Object.entries(NICKNAME_POOL);
|
|
12692
|
+
var NAME_TO_KEY = Object.fromEntries(
|
|
12693
|
+
ALL_NICKNAMES.map(([key, entry]) => [entry.name, key])
|
|
12694
|
+
);
|
|
12490
12695
|
var DOMAIN_PREFERENCES = {
|
|
12491
12696
|
"security": ["shannon", "turing", "lamarr", "stallman"],
|
|
12492
12697
|
"bug-hunter": ["darwin", "curie", "feynman", "fermi"],
|
|
@@ -12519,17 +12724,23 @@ function assignNickname(role, used) {
|
|
|
12519
12724
|
for (const key of preferences) {
|
|
12520
12725
|
const entry = NICKNAME_POOL[key];
|
|
12521
12726
|
if (entry && !used.has(key)) {
|
|
12522
|
-
return `${entry.name} (${formatRole(role)})
|
|
12727
|
+
return { key, display: `${entry.name} (${formatRole(role)})` };
|
|
12523
12728
|
}
|
|
12524
12729
|
}
|
|
12525
|
-
for (const entry of ALL_NICKNAMES) {
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
return `${entry.name} (${formatRole(role)})`;
|
|
12730
|
+
for (const [key, entry] of ALL_NICKNAMES) {
|
|
12731
|
+
if (!used.has(key)) {
|
|
12732
|
+
return { key, display: `${entry.name} (${formatRole(role)})` };
|
|
12529
12733
|
}
|
|
12530
12734
|
}
|
|
12531
12735
|
const counter = used.size + 1;
|
|
12532
|
-
return `Scientist #${counter} (${formatRole(role)})
|
|
12736
|
+
return { key: `scientist-${counter}`, display: `Scientist #${counter} (${formatRole(role)})` };
|
|
12737
|
+
}
|
|
12738
|
+
function nicknameKeyFromDisplay(display) {
|
|
12739
|
+
const base = display.replace(/\s*\([^)]*\)\s*$/, "").trim();
|
|
12740
|
+
const key = NAME_TO_KEY[base];
|
|
12741
|
+
if (key) return key;
|
|
12742
|
+
const synthesized = base.match(/^Scientist #(\d+)$/);
|
|
12743
|
+
return synthesized ? `scientist-${synthesized[1]}` : void 0;
|
|
12533
12744
|
}
|
|
12534
12745
|
function formatRole(role) {
|
|
12535
12746
|
return role.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
@@ -12616,11 +12827,10 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
12616
12827
|
const name = subagent.name?.trim() ?? "";
|
|
12617
12828
|
const isPlaceholder = name === "" || name.toLowerCase() === role.toLowerCase() || name === "subagent" || name === "adhoc" || name === "generic" || /^slot-/.test(name);
|
|
12618
12829
|
if (!isPlaceholder) return subagent;
|
|
12619
|
-
const
|
|
12620
|
-
|
|
12621
|
-
this.
|
|
12622
|
-
|
|
12623
|
-
return { ...subagent, name: nickname };
|
|
12830
|
+
const { key, display } = assignNickname(role, this.usedNicknames);
|
|
12831
|
+
this.usedNicknames.add(key);
|
|
12832
|
+
this.subagentNicknames.set(subagentId, key);
|
|
12833
|
+
return { ...subagent, name: display };
|
|
12624
12834
|
}
|
|
12625
12835
|
async spawn(subagent) {
|
|
12626
12836
|
const id = subagent.id || randomUUID();
|
|
@@ -12768,7 +12978,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
12768
12978
|
taskIds.map((id) => {
|
|
12769
12979
|
const cached = this.completedResults.find((r) => r.taskId === id);
|
|
12770
12980
|
if (cached) return cached;
|
|
12771
|
-
return new Promise((
|
|
12981
|
+
return new Promise((resolve13, reject) => {
|
|
12772
12982
|
const timeout = setTimeout(() => {
|
|
12773
12983
|
this.off("task.completed", handler);
|
|
12774
12984
|
reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
|
|
@@ -12777,7 +12987,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
12777
12987
|
if (result.taskId === id) {
|
|
12778
12988
|
clearTimeout(timeout);
|
|
12779
12989
|
this.off("task.completed", handler);
|
|
12780
|
-
|
|
12990
|
+
resolve13(result);
|
|
12781
12991
|
}
|
|
12782
12992
|
};
|
|
12783
12993
|
this.on("task.completed", handler);
|
|
@@ -12872,23 +13082,32 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
12872
13082
|
*/
|
|
12873
13083
|
drainPendingAsAborted(message) {
|
|
12874
13084
|
const dropped = this.pendingTasks.splice(0, this.pendingTasks.length);
|
|
12875
|
-
for (const t2 of dropped)
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
|
|
12889
|
-
|
|
12890
|
-
|
|
12891
|
-
|
|
13085
|
+
for (const t2 of dropped) this.emitPendingAborted(t2, message);
|
|
13086
|
+
}
|
|
13087
|
+
/**
|
|
13088
|
+
* Emit a synthetic `stopped`/`aborted_by_parent` completion for a single
|
|
13089
|
+
* PENDING task — one that was never counted in `inFlight`. This MUST bypass
|
|
13090
|
+
* `recordCompletion`: that path does `inFlight--`, which for a pending task
|
|
13091
|
+
* steals a decrement from a genuinely in-flight task and trips the underflow
|
|
13092
|
+
* guard — suppressing that real task's `task.completed` and hanging its
|
|
13093
|
+
* `awaitTasks()` caller. Pushes the result and fires the event directly.
|
|
13094
|
+
*/
|
|
13095
|
+
emitPendingAborted(task, message) {
|
|
13096
|
+
const synthetic = {
|
|
13097
|
+
subagentId: task.subagentId ?? "unassigned",
|
|
13098
|
+
taskId: task.id,
|
|
13099
|
+
status: "stopped",
|
|
13100
|
+
error: {
|
|
13101
|
+
kind: "aborted_by_parent",
|
|
13102
|
+
message,
|
|
13103
|
+
retryable: false
|
|
13104
|
+
},
|
|
13105
|
+
iterations: 0,
|
|
13106
|
+
toolCalls: 0,
|
|
13107
|
+
durationMs: 0
|
|
13108
|
+
};
|
|
13109
|
+
this.completedResults.push(synthetic);
|
|
13110
|
+
this.emit("task.completed", { task, result: synthetic });
|
|
12892
13111
|
}
|
|
12893
13112
|
async runDispatched(subagentId, task) {
|
|
12894
13113
|
const subagent = this.subagents.get(subagentId);
|
|
@@ -13149,20 +13368,10 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
13149
13368
|
const orphaned = this.pendingTasks.filter((t2) => t2.subagentId === subagentId);
|
|
13150
13369
|
this.pendingTasks = this.pendingTasks.filter((t2) => t2.subagentId !== subagentId);
|
|
13151
13370
|
for (const t2 of orphaned) {
|
|
13152
|
-
|
|
13153
|
-
|
|
13154
|
-
|
|
13155
|
-
|
|
13156
|
-
error: {
|
|
13157
|
-
kind: "aborted_by_parent",
|
|
13158
|
-
message: `Subagent "${subagentId}" was removed while task "${t2.id}" was pending`,
|
|
13159
|
-
retryable: false
|
|
13160
|
-
},
|
|
13161
|
-
iterations: 0,
|
|
13162
|
-
toolCalls: 0,
|
|
13163
|
-
durationMs: 0
|
|
13164
|
-
};
|
|
13165
|
-
this.recordCompletion(synthetic);
|
|
13371
|
+
this.emitPendingAborted(
|
|
13372
|
+
t2,
|
|
13373
|
+
`Subagent "${subagentId}" was removed while task "${t2.id}" was pending`
|
|
13374
|
+
);
|
|
13166
13375
|
}
|
|
13167
13376
|
this.fleetBus?.emit({
|
|
13168
13377
|
subagentId,
|
|
@@ -13280,7 +13489,7 @@ function providerErrorToSubagentError(err, message, cause) {
|
|
|
13280
13489
|
|
|
13281
13490
|
// src/execution/parallel-eternal-engine.ts
|
|
13282
13491
|
function sleep2(ms) {
|
|
13283
|
-
return new Promise((
|
|
13492
|
+
return new Promise((resolve13) => setTimeout(resolve13, ms));
|
|
13284
13493
|
}
|
|
13285
13494
|
var GOAL_COMPLETE_MARKER2 = /^\s*\[goal[_\s-]?complete\]\s*$/im;
|
|
13286
13495
|
var ParallelEternalEngine = class {
|
|
@@ -13459,7 +13668,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
13459
13668
|
"\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
|
|
13460
13669
|
"\u2022 Execute the assigned task end-to-end using multiple tool calls.",
|
|
13461
13670
|
"\u2022 Emit `[done]` on its own line when the task is complete.",
|
|
13462
|
-
"\u2022 Do not ask
|
|
13671
|
+
"\u2022 Do not ask before routine in-project tool use \u2014 YOLO is active for normal project work.",
|
|
13672
|
+
"\u2022 If a destructive-gated confirmation appears, wait for the permission flow.",
|
|
13463
13673
|
"\u2022 If the overall Mission is accomplished, emit `[GOAL_COMPLETE]` followed by a verification recipe.",
|
|
13464
13674
|
"\u2022 Keep output concise \u2014 summarize findings, do not transcribe files."
|
|
13465
13675
|
].join("\n");
|
|
@@ -13539,6 +13749,7 @@ ${personaLine}Task: ${task}
|
|
|
13539
13749
|
} catch {
|
|
13540
13750
|
results = coordinator.results().slice(-taskIds.length);
|
|
13541
13751
|
}
|
|
13752
|
+
await Promise.allSettled(subagentIds.map((id) => coordinator.remove(id)));
|
|
13542
13753
|
const allSuccessful = results.length > 0 && results.every((r) => r.status === "success");
|
|
13543
13754
|
const goalComplete = results.some(
|
|
13544
13755
|
(r) => r.status === "success" && typeof r.result === "string" && GOAL_COMPLETE_MARKER2.test(r.result)
|
|
@@ -13716,8 +13927,10 @@ ${journalTail.join("\n")}` : "Recent journal: (none \u2014 this is the first ite
|
|
|
13716
13927
|
" decide.",
|
|
13717
13928
|
"",
|
|
13718
13929
|
"### Operating principles",
|
|
13719
|
-
"- YOLO is active
|
|
13720
|
-
"
|
|
13930
|
+
"- YOLO is active for normal project work. Proceed with routine",
|
|
13931
|
+
" in-project tool use without pre-confirming; pick the best path and execute it.",
|
|
13932
|
+
" If the permission system raises a destructive-gated confirmation, wait",
|
|
13933
|
+
" for that flow instead of trying to bypass it.",
|
|
13721
13934
|
"- Use tools freely; multiple calls per turn are normal and expected.",
|
|
13722
13935
|
"- When working on a todo, mark it `in_progress` via the todos tool",
|
|
13723
13936
|
" before tool work and `completed` (or `cancelled` with a reason)",
|
|
@@ -14332,6 +14545,10 @@ Emit each evaluation immediately. Do not wait until you have read all reports.`;
|
|
|
14332
14545
|
return lines.join("\n");
|
|
14333
14546
|
}
|
|
14334
14547
|
cleanup() {
|
|
14548
|
+
if (this._timeoutTimer) {
|
|
14549
|
+
clearTimeout(this._timeoutTimer);
|
|
14550
|
+
this._timeoutTimer = void 0;
|
|
14551
|
+
}
|
|
14335
14552
|
for (const dispose of this.disposers) dispose();
|
|
14336
14553
|
this.disposers.length = 0;
|
|
14337
14554
|
}
|
|
@@ -15461,18 +15678,20 @@ var Director = class _Director {
|
|
|
15461
15678
|
if (e.subagentId.startsWith("bug-hunter-") || e.subagentId.startsWith("refactor-planner-") || e.subagentId.startsWith("critic-")) {
|
|
15462
15679
|
return;
|
|
15463
15680
|
}
|
|
15464
|
-
if (payload.kind === "timeout") {
|
|
15681
|
+
if (payload.kind === "timeout" || payload.kind === "idle_timeout") {
|
|
15682
|
+
const heartbeatKey = `${e.subagentId}:${payload.kind}`;
|
|
15465
15683
|
const progress = progressBySubagent.get(e.subagentId) ?? 0;
|
|
15466
|
-
const lastProgress = lastTimeoutProgress.get(
|
|
15684
|
+
const lastProgress = lastTimeoutProgress.get(heartbeatKey) ?? -1;
|
|
15467
15685
|
if (progress <= lastProgress) {
|
|
15468
15686
|
payload.deny();
|
|
15469
15687
|
return;
|
|
15470
15688
|
}
|
|
15471
|
-
lastTimeoutProgress.set(
|
|
15689
|
+
lastTimeoutProgress.set(heartbeatKey, progress);
|
|
15690
|
+
const field = payload.kind === "timeout" ? "timeoutMs" : "idleTimeoutMs";
|
|
15472
15691
|
setImmediate(() => {
|
|
15473
15692
|
const newLimit = Math.min(Math.ceil(payload.limit * 2), 24 * 60 * 6e4);
|
|
15474
|
-
this.recordExtension(e.subagentId, e.taskId,
|
|
15475
|
-
payload.extend({
|
|
15693
|
+
this.recordExtension(e.subagentId, e.taskId, payload.kind, newLimit);
|
|
15694
|
+
payload.extend({ [field]: newLimit });
|
|
15476
15695
|
});
|
|
15477
15696
|
return;
|
|
15478
15697
|
}
|
|
@@ -15788,10 +16007,9 @@ var Director = class _Director {
|
|
|
15788
16007
|
if (this.fleetManager) {
|
|
15789
16008
|
this.fleetManager.assignNicknameAndRecord(config);
|
|
15790
16009
|
} else {
|
|
15791
|
-
|
|
15792
|
-
|
|
15793
|
-
|
|
15794
|
-
);
|
|
16010
|
+
const { key, display } = assignNickname(role, this._usedNicknames);
|
|
16011
|
+
config.name = display;
|
|
16012
|
+
this._usedNicknames.add(key);
|
|
15795
16013
|
}
|
|
15796
16014
|
}
|
|
15797
16015
|
result = await this.coordinator.spawn(config);
|
|
@@ -16085,11 +16303,11 @@ var Director = class _Director {
|
|
|
16085
16303
|
if (cached) return cached;
|
|
16086
16304
|
const existing = this.taskWaiters.get(id);
|
|
16087
16305
|
if (existing) return existing.promise;
|
|
16088
|
-
let
|
|
16306
|
+
let resolve13;
|
|
16089
16307
|
const promise = new Promise((res) => {
|
|
16090
|
-
|
|
16308
|
+
resolve13 = res;
|
|
16091
16309
|
});
|
|
16092
|
-
this.taskWaiters.set(id, { promise, resolve:
|
|
16310
|
+
this.taskWaiters.set(id, { promise, resolve: resolve13 });
|
|
16093
16311
|
return promise;
|
|
16094
16312
|
})
|
|
16095
16313
|
);
|
|
@@ -16113,8 +16331,8 @@ var Director = class _Director {
|
|
|
16113
16331
|
} else {
|
|
16114
16332
|
const entry = this.manifestEntries.get(subagentId);
|
|
16115
16333
|
if (entry?.name) {
|
|
16116
|
-
const nicknameKey = entry.name
|
|
16117
|
-
this._usedNicknames.delete(nicknameKey);
|
|
16334
|
+
const nicknameKey = nicknameKeyFromDisplay(entry.name);
|
|
16335
|
+
if (nicknameKey) this._usedNicknames.delete(nicknameKey);
|
|
16118
16336
|
}
|
|
16119
16337
|
}
|
|
16120
16338
|
this.manifestEntries.delete(subagentId);
|
|
@@ -16474,7 +16692,7 @@ function createDelegateTool(opts) {
|
|
|
16474
16692
|
subagentId
|
|
16475
16693
|
});
|
|
16476
16694
|
const dir = director;
|
|
16477
|
-
const result = await new Promise((
|
|
16695
|
+
const result = await new Promise((resolve13) => {
|
|
16478
16696
|
let settled = false;
|
|
16479
16697
|
let timer;
|
|
16480
16698
|
const finish = (value) => {
|
|
@@ -16484,7 +16702,7 @@ function createDelegateTool(opts) {
|
|
|
16484
16702
|
offTool();
|
|
16485
16703
|
offIter();
|
|
16486
16704
|
offProgress();
|
|
16487
|
-
|
|
16705
|
+
resolve13(value);
|
|
16488
16706
|
};
|
|
16489
16707
|
const arm = () => {
|
|
16490
16708
|
if (timer) clearTimeout(timer);
|
|
@@ -18114,9 +18332,9 @@ var AISpecBuilder = class {
|
|
|
18114
18332
|
if (!this.sessionPath) return;
|
|
18115
18333
|
try {
|
|
18116
18334
|
const fsp20 = await import('fs/promises');
|
|
18117
|
-
const
|
|
18335
|
+
const path37 = await import('path');
|
|
18118
18336
|
const { atomicWrite: atomicWrite2 } = await Promise.resolve().then(() => (init_atomic_write(), atomic_write_exports));
|
|
18119
|
-
await fsp20.mkdir(
|
|
18337
|
+
await fsp20.mkdir(path37.dirname(this.sessionPath), { recursive: true });
|
|
18120
18338
|
await atomicWrite2(this.sessionPath, JSON.stringify(this.session, null, 2));
|
|
18121
18339
|
} catch {
|
|
18122
18340
|
}
|
|
@@ -18826,15 +19044,15 @@ function computeCriticalPath(graph, _topoOrder, blockedByMap) {
|
|
|
18826
19044
|
maxId = id;
|
|
18827
19045
|
}
|
|
18828
19046
|
}
|
|
18829
|
-
const
|
|
19047
|
+
const path37 = [];
|
|
18830
19048
|
let current = maxId;
|
|
18831
19049
|
const visited = /* @__PURE__ */ new Set();
|
|
18832
19050
|
while (current && !visited.has(current)) {
|
|
18833
19051
|
visited.add(current);
|
|
18834
|
-
|
|
19052
|
+
path37.unshift(current);
|
|
18835
19053
|
current = prev.get(current) ?? null;
|
|
18836
19054
|
}
|
|
18837
|
-
return
|
|
19055
|
+
return path37;
|
|
18838
19056
|
}
|
|
18839
19057
|
function computeParallelGroups(graph, blockedByMap) {
|
|
18840
19058
|
const groups = [];
|
|
@@ -19384,7 +19602,7 @@ var SddParallelRun = class {
|
|
|
19384
19602
|
"\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
|
|
19385
19603
|
"\u2022 Execute the assigned SDD task end-to-end using multiple tool calls.",
|
|
19386
19604
|
"\u2022 Mark the task [done] in the tracker when complete.",
|
|
19387
|
-
"\u2022 Do not ask for
|
|
19605
|
+
"\u2022 Do not ask before routine in-project tool use; if a permission gate appears, wait for that flow.",
|
|
19388
19606
|
"\u2022 Keep output concise \u2014 summarize changes, do not transcribe files."
|
|
19389
19607
|
].join("\n");
|
|
19390
19608
|
const spawns = subagentIds.map(
|
|
@@ -19627,9 +19845,9 @@ var DefaultHealthRegistry = class {
|
|
|
19627
19845
|
}
|
|
19628
19846
|
async runOne(check) {
|
|
19629
19847
|
let timer = null;
|
|
19630
|
-
const timeout = new Promise((
|
|
19848
|
+
const timeout = new Promise((resolve13) => {
|
|
19631
19849
|
timer = setTimeout(
|
|
19632
|
-
() =>
|
|
19850
|
+
() => resolve13({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
|
|
19633
19851
|
this.timeoutMs
|
|
19634
19852
|
);
|
|
19635
19853
|
});
|
|
@@ -19812,7 +20030,7 @@ async function startMetricsServer(opts) {
|
|
|
19812
20030
|
const tls = opts.tls;
|
|
19813
20031
|
const useHttps = !!(tls?.cert && tls?.key);
|
|
19814
20032
|
const host = opts.host ?? "127.0.0.1";
|
|
19815
|
-
const
|
|
20033
|
+
const path37 = opts.path ?? "/metrics";
|
|
19816
20034
|
const healthPath = opts.healthPath ?? "/healthz";
|
|
19817
20035
|
const healthRegistry = opts.healthRegistry;
|
|
19818
20036
|
const listener = (req, res) => {
|
|
@@ -19822,7 +20040,7 @@ async function startMetricsServer(opts) {
|
|
|
19822
20040
|
return;
|
|
19823
20041
|
}
|
|
19824
20042
|
const url = req.url.split("?")[0];
|
|
19825
|
-
if (url ===
|
|
20043
|
+
if (url === path37) {
|
|
19826
20044
|
let body;
|
|
19827
20045
|
try {
|
|
19828
20046
|
body = renderPrometheus(opts.sink.snapshot());
|
|
@@ -19868,14 +20086,14 @@ async function startMetricsServer(opts) {
|
|
|
19868
20086
|
const { createServer } = await import('http');
|
|
19869
20087
|
server = createServer(listener);
|
|
19870
20088
|
}
|
|
19871
|
-
await new Promise((
|
|
20089
|
+
await new Promise((resolve13, reject) => {
|
|
19872
20090
|
const onError = (err) => {
|
|
19873
20091
|
server.off("listening", onListening);
|
|
19874
20092
|
reject(err);
|
|
19875
20093
|
};
|
|
19876
20094
|
const onListening = () => {
|
|
19877
20095
|
server.off("error", onError);
|
|
19878
|
-
|
|
20096
|
+
resolve13();
|
|
19879
20097
|
};
|
|
19880
20098
|
server.once("error", onError);
|
|
19881
20099
|
server.once("listening", onListening);
|
|
@@ -19886,9 +20104,9 @@ async function startMetricsServer(opts) {
|
|
|
19886
20104
|
const protocol = useHttps ? "https" : "http";
|
|
19887
20105
|
return {
|
|
19888
20106
|
port: boundPort,
|
|
19889
|
-
url: `${protocol}://${host}:${boundPort}${
|
|
19890
|
-
close: () => new Promise((
|
|
19891
|
-
server.close((err) => err ? reject(err) :
|
|
20107
|
+
url: `${protocol}://${host}:${boundPort}${path37}`,
|
|
20108
|
+
close: () => new Promise((resolve13, reject) => {
|
|
20109
|
+
server.close((err) => err ? reject(err) : resolve13());
|
|
19892
20110
|
})
|
|
19893
20111
|
};
|
|
19894
20112
|
}
|
|
@@ -20437,7 +20655,7 @@ var context7Server = () => ({
|
|
|
20437
20655
|
name: "context7",
|
|
20438
20656
|
description: "Codebase-aware documentation and Q&A (context7.ai)",
|
|
20439
20657
|
transport: "streamable-http",
|
|
20440
|
-
url: "https://
|
|
20658
|
+
url: "https://mcp.context7.com/mcp",
|
|
20441
20659
|
permission: "confirm"
|
|
20442
20660
|
});
|
|
20443
20661
|
var braveSearchServer = () => ({
|
|
@@ -22215,8 +22433,8 @@ function resolvePulledCategoryPath(cat, localPath, rel, remotePath) {
|
|
|
22215
22433
|
}
|
|
22216
22434
|
const dest = path6.resolve(localPath, normalizedRel);
|
|
22217
22435
|
const root = path6.resolve(localPath);
|
|
22218
|
-
const
|
|
22219
|
-
if (
|
|
22436
|
+
const relative8 = path6.relative(root, dest);
|
|
22437
|
+
if (relative8.startsWith("..") || path6.isAbsolute(relative8)) {
|
|
22220
22438
|
throw new Error(`Refusing CloudSync path outside category root: ${remotePath}`);
|
|
22221
22439
|
}
|
|
22222
22440
|
return dest;
|
|
@@ -23389,7 +23607,7 @@ var SecurityScannerOrchestrator = class {
|
|
|
23389
23607
|
const delay = Math.round(policy.delayMs(attempt));
|
|
23390
23608
|
const status = isProviderErr ? err.status : 0;
|
|
23391
23609
|
console.warn(`[SecurityScanner] retry ${attempt + 1} after ${delay}ms (status=${status}) \u2014 ${errAsErr.message}`);
|
|
23392
|
-
await new Promise((
|
|
23610
|
+
await new Promise((resolve13) => setTimeout(resolve13, delay));
|
|
23393
23611
|
return this.completeWithRetry(provider, request, abortController, attempt + 1);
|
|
23394
23612
|
}
|
|
23395
23613
|
}
|
|
@@ -24248,11 +24466,10 @@ var FleetManager = class {
|
|
|
24248
24466
|
*/
|
|
24249
24467
|
assignNicknameAndRecord(config) {
|
|
24250
24468
|
const role = config.role ?? "subagent";
|
|
24251
|
-
const
|
|
24252
|
-
|
|
24253
|
-
|
|
24254
|
-
|
|
24255
|
-
return nickname;
|
|
24469
|
+
const { key, display } = assignNickname(role, this._usedNicknames);
|
|
24470
|
+
this._usedNicknames.add(key);
|
|
24471
|
+
config.name = display;
|
|
24472
|
+
return display;
|
|
24256
24473
|
}
|
|
24257
24474
|
/**
|
|
24258
24475
|
* Returns the set of already-assigned nickname keys — useful for debugging
|
|
@@ -24437,8 +24654,8 @@ var FleetManager = class {
|
|
|
24437
24654
|
removeSubagent(subagentId) {
|
|
24438
24655
|
const entry = this.manifestEntries.get(subagentId);
|
|
24439
24656
|
if (entry?.name) {
|
|
24440
|
-
const nicknameKey = entry.name
|
|
24441
|
-
this._usedNicknames.delete(nicknameKey);
|
|
24657
|
+
const nicknameKey = nicknameKeyFromDisplay(entry.name);
|
|
24658
|
+
if (nicknameKey) this._usedNicknames.delete(nicknameKey);
|
|
24442
24659
|
}
|
|
24443
24660
|
for (const [taskId, task] of this.pendingTasks) {
|
|
24444
24661
|
if (task.subagentId === subagentId) {
|
|
@@ -24885,37 +25102,146 @@ var ExtensionRegistry = class {
|
|
|
24885
25102
|
}
|
|
24886
25103
|
};
|
|
24887
25104
|
|
|
24888
|
-
// src/core/
|
|
24889
|
-
|
|
24890
|
-
function
|
|
24891
|
-
|
|
24892
|
-
|
|
24893
|
-
|
|
24894
|
-
|
|
24895
|
-
|
|
24896
|
-
|
|
24897
|
-
|
|
24898
|
-
|
|
24899
|
-
|
|
24900
|
-
}
|
|
24901
|
-
|
|
24902
|
-
|
|
24903
|
-
|
|
24904
|
-
|
|
24905
|
-
|
|
24906
|
-
|
|
24907
|
-
|
|
24908
|
-
}
|
|
24909
|
-
|
|
24910
|
-
|
|
24911
|
-
|
|
24912
|
-
|
|
24913
|
-
|
|
24914
|
-
|
|
24915
|
-
|
|
24916
|
-
|
|
24917
|
-
|
|
24918
|
-
|
|
25105
|
+
// src/core/agent-tools.ts
|
|
25106
|
+
function createAgentToolHandler(a) {
|
|
25107
|
+
async function executeSingleWithDecision(tool, use) {
|
|
25108
|
+
const start = Date.now();
|
|
25109
|
+
try {
|
|
25110
|
+
const result = await a.toolExecutor.executeTool(
|
|
25111
|
+
tool,
|
|
25112
|
+
use,
|
|
25113
|
+
a.ctx,
|
|
25114
|
+
a.perIterationOutputCapBytes
|
|
25115
|
+
);
|
|
25116
|
+
return { result, durationMs: Date.now() - start };
|
|
25117
|
+
} catch (err) {
|
|
25118
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
25119
|
+
return {
|
|
25120
|
+
result: {
|
|
25121
|
+
type: "tool_result",
|
|
25122
|
+
tool_use_id: use.id,
|
|
25123
|
+
content: `Tool "${tool.name}" threw: ${msg}`,
|
|
25124
|
+
is_error: true
|
|
25125
|
+
},
|
|
25126
|
+
durationMs: Date.now() - start
|
|
25127
|
+
};
|
|
25128
|
+
}
|
|
25129
|
+
}
|
|
25130
|
+
function waitForConfirm(info) {
|
|
25131
|
+
return new Promise((resolve13) => {
|
|
25132
|
+
a.events.emit("tool.confirm_needed", {
|
|
25133
|
+
tool: info.tool,
|
|
25134
|
+
input: info.input,
|
|
25135
|
+
toolUseId: info.toolUseId,
|
|
25136
|
+
suggestedPattern: info.suggestedPattern,
|
|
25137
|
+
resolve: resolve13
|
|
25138
|
+
});
|
|
25139
|
+
});
|
|
25140
|
+
}
|
|
25141
|
+
function emitToolExecuted(toolUseId, toolName, durationMs, ok, input, content) {
|
|
25142
|
+
const sig = sizeSignals(toolName, content);
|
|
25143
|
+
a.events.emit("tool.executed", {
|
|
25144
|
+
id: toolUseId,
|
|
25145
|
+
name: toolName,
|
|
25146
|
+
durationMs,
|
|
25147
|
+
ok,
|
|
25148
|
+
input,
|
|
25149
|
+
output: truncateForEvent(content),
|
|
25150
|
+
outputBytes: sig.outputBytes,
|
|
25151
|
+
outputTokens: sig.outputTokens,
|
|
25152
|
+
outputLines: sig.outputLines
|
|
25153
|
+
});
|
|
25154
|
+
}
|
|
25155
|
+
async function executeTools(toolUses) {
|
|
25156
|
+
const selectedToolUses = await a.extensions.runBeforeToolExecution(a.ctx, toolUses);
|
|
25157
|
+
const { outputs } = await a.toolExecutor.executeBatch(
|
|
25158
|
+
selectedToolUses,
|
|
25159
|
+
a.ctx,
|
|
25160
|
+
a.executionStrategy
|
|
25161
|
+
);
|
|
25162
|
+
const useById = new Map(selectedToolUses.map((u) => [u.id, u]));
|
|
25163
|
+
const resultsForMessage = [];
|
|
25164
|
+
for (const { result, tool, durationMs } of outputs) {
|
|
25165
|
+
if (result.type === "tool_confirm_pending") {
|
|
25166
|
+
const decision = await waitForConfirm({
|
|
25167
|
+
tool,
|
|
25168
|
+
input: result.input,
|
|
25169
|
+
toolUseId: result.toolUseId,
|
|
25170
|
+
suggestedPattern: result.suggestedPattern
|
|
25171
|
+
});
|
|
25172
|
+
if (decision === "always") {
|
|
25173
|
+
try {
|
|
25174
|
+
await a.permission.trust({ tool: tool.name, pattern: result.suggestedPattern });
|
|
25175
|
+
a.events.emit("trust.persisted", { tool: tool.name, pattern: result.suggestedPattern, decision });
|
|
25176
|
+
} catch {
|
|
25177
|
+
}
|
|
25178
|
+
} else if (decision === "deny") {
|
|
25179
|
+
try {
|
|
25180
|
+
await a.permission.deny({ tool: tool.name, pattern: result.suggestedPattern });
|
|
25181
|
+
a.events.emit("trust.persisted", { tool: tool.name, pattern: result.suggestedPattern, decision });
|
|
25182
|
+
} catch {
|
|
25183
|
+
}
|
|
25184
|
+
}
|
|
25185
|
+
if (decision === "yes") {
|
|
25186
|
+
const p = a.permission;
|
|
25187
|
+
p.allowOnce?.({ tool: tool.name, pattern: result.suggestedPattern });
|
|
25188
|
+
} else if (decision === "no") {
|
|
25189
|
+
const p = a.permission;
|
|
25190
|
+
p.denyOnce?.({ tool: tool.name, pattern: result.suggestedPattern });
|
|
25191
|
+
}
|
|
25192
|
+
const reRunResult = decision === "yes" || decision === "always" ? await executeSingleWithDecision(tool, {
|
|
25193
|
+
id: result.toolUseId,
|
|
25194
|
+
name: tool.name,
|
|
25195
|
+
input: result.input
|
|
25196
|
+
}) : {
|
|
25197
|
+
result: {
|
|
25198
|
+
type: "tool_result",
|
|
25199
|
+
tool_use_id: result.toolUseId,
|
|
25200
|
+
content: decision === "deny" ? `Tool "${tool.name}" denied and blocked for this pattern.` : `Tool "${tool.name}" denied by user.`,
|
|
25201
|
+
is_error: true
|
|
25202
|
+
},
|
|
25203
|
+
durationMs: 0
|
|
25204
|
+
};
|
|
25205
|
+
const use2 = useById.get(reRunResult.result.tool_use_id);
|
|
25206
|
+
if (use2) {
|
|
25207
|
+
await a.pipelines.toolCall.run({ toolUse: use2, result: reRunResult.result, ctx: a.ctx, tool });
|
|
25208
|
+
await a.ctx.session.append({
|
|
25209
|
+
type: "tool_result",
|
|
25210
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25211
|
+
id: reRunResult.result.tool_use_id,
|
|
25212
|
+
content: reRunResult.result.content,
|
|
25213
|
+
isError: !!reRunResult.result.is_error
|
|
25214
|
+
});
|
|
25215
|
+
emitToolExecuted(
|
|
25216
|
+
reRunResult.result.tool_use_id,
|
|
25217
|
+
tool.name,
|
|
25218
|
+
reRunResult.durationMs,
|
|
25219
|
+
!reRunResult.result.is_error,
|
|
25220
|
+
result.input,
|
|
25221
|
+
reRunResult.result.content
|
|
25222
|
+
);
|
|
25223
|
+
}
|
|
25224
|
+
resultsForMessage.push(reRunResult.result);
|
|
25225
|
+
continue;
|
|
25226
|
+
}
|
|
25227
|
+
resultsForMessage.push(result);
|
|
25228
|
+
const use = useById.get(result.tool_use_id);
|
|
25229
|
+
if (!use) continue;
|
|
25230
|
+
await a.pipelines.toolCall.run({ toolUse: use, result, ctx: a.ctx, tool: tool ?? void 0 });
|
|
25231
|
+
await a.ctx.session.append({
|
|
25232
|
+
type: "tool_result",
|
|
25233
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25234
|
+
id: result.tool_use_id,
|
|
25235
|
+
content: result.content,
|
|
25236
|
+
isError: !!result.is_error
|
|
25237
|
+
});
|
|
25238
|
+
emitToolExecuted(result.tool_use_id, use.name, durationMs, !result.is_error, use.input, result.content);
|
|
25239
|
+
}
|
|
25240
|
+
a.ctx.state.appendMessage({ role: "user", content: resultsForMessage });
|
|
25241
|
+
await a.extensions.runAfterToolExecution(a.ctx, outputs);
|
|
25242
|
+
return resultsForMessage;
|
|
25243
|
+
}
|
|
25244
|
+
return { executeTools, executeSingleWithDecision };
|
|
24919
25245
|
}
|
|
24920
25246
|
|
|
24921
25247
|
// src/core/continue-to-next-iteration.ts
|
|
@@ -24933,13 +25259,13 @@ function parseContinueDirective(text) {
|
|
|
24933
25259
|
}
|
|
24934
25260
|
return lastDirective;
|
|
24935
25261
|
}
|
|
24936
|
-
var
|
|
25262
|
+
var META_KEY = "_autonomousContinue";
|
|
24937
25263
|
function setAutonomousContinue(ctx) {
|
|
24938
|
-
ctx.meta[
|
|
25264
|
+
ctx.meta[META_KEY] = true;
|
|
24939
25265
|
}
|
|
24940
25266
|
function consumeAutonomousContinue(ctx) {
|
|
24941
|
-
const val = ctx.meta[
|
|
24942
|
-
delete ctx.meta[
|
|
25267
|
+
const val = ctx.meta[META_KEY] === true;
|
|
25268
|
+
delete ctx.meta[META_KEY];
|
|
24943
25269
|
return val;
|
|
24944
25270
|
}
|
|
24945
25271
|
function makeContinueToNextIterationTool() {
|
|
@@ -24962,31 +25288,129 @@ function makeContinueToNextIterationTool() {
|
|
|
24962
25288
|
};
|
|
24963
25289
|
}
|
|
24964
25290
|
|
|
24965
|
-
// src/core/
|
|
24966
|
-
function
|
|
24967
|
-
|
|
24968
|
-
|
|
24969
|
-
|
|
24970
|
-
|
|
24971
|
-
|
|
24972
|
-
|
|
24973
|
-
|
|
24974
|
-
}
|
|
24975
|
-
|
|
24976
|
-
|
|
24977
|
-
|
|
24978
|
-
|
|
24979
|
-
|
|
24980
|
-
|
|
24981
|
-
|
|
24982
|
-
|
|
24983
|
-
|
|
25291
|
+
// src/core/agent-response.ts
|
|
25292
|
+
function createAgentResponseHandler(a) {
|
|
25293
|
+
async function buildAndRunRequestPipeline(opts) {
|
|
25294
|
+
const repaired = repairToolUseAdjacency(a.ctx.messages);
|
|
25295
|
+
if (repaired.report.changed) {
|
|
25296
|
+
a.ctx.state.replaceMessages(repaired.messages);
|
|
25297
|
+
a.events.emit("context.repaired", {
|
|
25298
|
+
ctx: a.ctx,
|
|
25299
|
+
...repaired.report
|
|
25300
|
+
});
|
|
25301
|
+
a.logger.warn(
|
|
25302
|
+
`Repaired context tool adjacency: removed ${repaired.report.removedToolUses.length} tool_use block(s), ${repaired.report.removedToolResults.length} tool_result block(s), ${repaired.report.removedMessages} empty message(s)`
|
|
25303
|
+
);
|
|
25304
|
+
}
|
|
25305
|
+
const baseReq = {
|
|
25306
|
+
model: opts.model ?? a.ctx.model,
|
|
25307
|
+
system: a.ctx.systemPrompt,
|
|
25308
|
+
messages: a.ctx.messages,
|
|
25309
|
+
tools: a.tools.list(),
|
|
25310
|
+
maxTokens: 8192
|
|
24984
25311
|
};
|
|
24985
|
-
|
|
24986
|
-
|
|
24987
|
-
|
|
25312
|
+
return a.pipelines.request.run(baseReq);
|
|
25313
|
+
}
|
|
25314
|
+
async function processResponse(raw, req) {
|
|
25315
|
+
let res = raw;
|
|
25316
|
+
res = await a.pipelines.response.run(res);
|
|
25317
|
+
a.events.emit("provider.response", {
|
|
25318
|
+
ctx: a.ctx,
|
|
25319
|
+
usage: res.usage,
|
|
25320
|
+
stopReason: res.stopReason
|
|
25321
|
+
});
|
|
25322
|
+
a.ctx.tokenCounter.account(res.usage, req.model);
|
|
25323
|
+
a.ctx.state.appendMessage({ role: "assistant", content: res.content });
|
|
25324
|
+
await a.ctx.session.append({
|
|
25325
|
+
type: "llm_response",
|
|
25326
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25327
|
+
content: res.content,
|
|
25328
|
+
stopReason: res.stopReason,
|
|
25329
|
+
usage: res.usage
|
|
25330
|
+
});
|
|
25331
|
+
if (a.ctx.signal.aborted) {
|
|
25332
|
+
let finalText2 = "";
|
|
25333
|
+
for (const block of res.content) {
|
|
25334
|
+
if (isTextBlock(block)) finalText2 += block.text;
|
|
25335
|
+
}
|
|
25336
|
+
return { finalText: finalText2, aborted: true, done: false };
|
|
25337
|
+
}
|
|
25338
|
+
let finalText = "";
|
|
25339
|
+
const streamed = a.ctx.provider.capabilities.streaming;
|
|
25340
|
+
for (const block of res.content) {
|
|
25341
|
+
if (isTextBlock(block)) {
|
|
25342
|
+
const rendered = await a.pipelines.assistantOutput.run(block);
|
|
25343
|
+
finalText += rendered.text;
|
|
25344
|
+
if (!streamed) a.renderer?.write(rendered);
|
|
25345
|
+
}
|
|
25346
|
+
}
|
|
25347
|
+
let directive = "none";
|
|
25348
|
+
if (finalText) {
|
|
25349
|
+
directive = parseContinueDirective(finalText);
|
|
25350
|
+
}
|
|
25351
|
+
return { finalText, aborted: false, done: false, directive };
|
|
25352
|
+
}
|
|
25353
|
+
return { buildAndRunRequestPipeline, processResponse };
|
|
25354
|
+
}
|
|
25355
|
+
|
|
25356
|
+
// src/core/btw.ts
|
|
25357
|
+
var META_KEY2 = "_btwNotes";
|
|
25358
|
+
function readQueue(ctx) {
|
|
25359
|
+
const raw = ctx.meta[META_KEY2];
|
|
25360
|
+
return Array.isArray(raw) ? raw : [];
|
|
25361
|
+
}
|
|
25362
|
+
function setBtwNote(ctx, text) {
|
|
25363
|
+
const trimmed = text.trim();
|
|
25364
|
+
if (!trimmed) return readQueue(ctx).length;
|
|
25365
|
+
const next = [...readQueue(ctx), trimmed].slice(-20);
|
|
25366
|
+
ctx.meta[META_KEY2] = next;
|
|
25367
|
+
return next.length;
|
|
25368
|
+
}
|
|
25369
|
+
function pendingBtwCount(ctx) {
|
|
25370
|
+
return readQueue(ctx).length;
|
|
25371
|
+
}
|
|
25372
|
+
function consumeBtwNotes(ctx) {
|
|
25373
|
+
const notes = readQueue(ctx);
|
|
25374
|
+
if (notes.length > 0) delete ctx.meta[META_KEY2];
|
|
25375
|
+
return notes;
|
|
25376
|
+
}
|
|
25377
|
+
function buildBtwBlock(notes) {
|
|
25378
|
+
const body = notes.map((n) => `- ${n}`).join("\n");
|
|
25379
|
+
return [
|
|
25380
|
+
"[BY THE WAY \u2014 the user added this while you were working. Fold it into",
|
|
25381
|
+
"your current task; do not restart from scratch unless it contradicts the",
|
|
25382
|
+
"goal:",
|
|
25383
|
+
"",
|
|
25384
|
+
body,
|
|
25385
|
+
"]"
|
|
25386
|
+
].join("\n");
|
|
25387
|
+
}
|
|
25388
|
+
|
|
25389
|
+
// src/core/iteration-limit.ts
|
|
25390
|
+
function requestLimitExtension(opts) {
|
|
25391
|
+
const { events, currentIterations, currentLimit, autoExtend, timeoutMs = 3e4 } = opts;
|
|
25392
|
+
return new Promise((resolve13) => {
|
|
25393
|
+
let resolved = false;
|
|
25394
|
+
const timerFired = () => {
|
|
25395
|
+
if (!resolved) {
|
|
25396
|
+
resolved = true;
|
|
25397
|
+
resolve13(0);
|
|
25398
|
+
}
|
|
25399
|
+
};
|
|
25400
|
+
const timer = setTimeout(timerFired, timeoutMs);
|
|
25401
|
+
timer.unref();
|
|
25402
|
+
const deny = () => {
|
|
25403
|
+
if (!resolved) {
|
|
25404
|
+
resolved = true;
|
|
24988
25405
|
clearTimeout(timer);
|
|
24989
|
-
|
|
25406
|
+
resolve13(0);
|
|
25407
|
+
}
|
|
25408
|
+
};
|
|
25409
|
+
const grant = (extra) => {
|
|
25410
|
+
if (!resolved) {
|
|
25411
|
+
resolved = true;
|
|
25412
|
+
clearTimeout(timer);
|
|
25413
|
+
resolve13(Math.max(0, extra));
|
|
24990
25414
|
}
|
|
24991
25415
|
};
|
|
24992
25416
|
events.emit("iteration.limit_reached", {
|
|
@@ -25000,216 +25424,113 @@ function requestLimitExtension(opts) {
|
|
|
25000
25424
|
if (!resolved) {
|
|
25001
25425
|
resolved = true;
|
|
25002
25426
|
clearTimeout(timer);
|
|
25003
|
-
|
|
25427
|
+
resolve13(100);
|
|
25004
25428
|
}
|
|
25005
25429
|
});
|
|
25006
25430
|
}
|
|
25007
25431
|
});
|
|
25008
25432
|
}
|
|
25009
25433
|
|
|
25010
|
-
// src/core/agent.ts
|
|
25011
|
-
|
|
25012
|
-
|
|
25013
|
-
if (typeof input === "string") {
|
|
25014
|
-
return { blocks: [{ type: "text", text: input }], text: input };
|
|
25015
|
-
}
|
|
25016
|
-
const text = input.filter(isTextBlock).map((b) => b.text).join("");
|
|
25017
|
-
return { blocks: input, text };
|
|
25018
|
-
}
|
|
25019
|
-
function createDefaultPipelines() {
|
|
25020
|
-
return {
|
|
25021
|
-
request: new Pipeline(),
|
|
25022
|
-
response: new Pipeline(),
|
|
25023
|
-
toolCall: new Pipeline(),
|
|
25024
|
-
userInput: new Pipeline(),
|
|
25025
|
-
assistantOutput: new Pipeline(),
|
|
25026
|
-
contextWindow: new Pipeline()
|
|
25027
|
-
};
|
|
25434
|
+
// src/core/agent-loop.ts
|
|
25435
|
+
function toError(err) {
|
|
25436
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
25028
25437
|
}
|
|
25029
|
-
|
|
25030
|
-
|
|
25031
|
-
|
|
25032
|
-
providers;
|
|
25033
|
-
events;
|
|
25034
|
-
pipelines;
|
|
25035
|
-
ctx;
|
|
25036
|
-
maxIterations;
|
|
25037
|
-
executionStrategy;
|
|
25038
|
-
perIterationOutputCapBytes;
|
|
25039
|
-
plugins = [];
|
|
25040
|
-
toolExecutor;
|
|
25041
|
-
autoExtendLimit;
|
|
25042
|
-
/** Enables autonomous continue: model can signal `[continue]` or call continue_to_next_iteration() to re-run. */
|
|
25043
|
-
autonomousContinue;
|
|
25044
|
-
tracer;
|
|
25045
|
-
extensions;
|
|
25046
|
-
constructor(init) {
|
|
25047
|
-
this.container = init.container;
|
|
25048
|
-
this.tools = init.tools;
|
|
25049
|
-
this.providers = init.providers;
|
|
25050
|
-
this.events = init.events;
|
|
25051
|
-
this.pipelines = init.pipelines;
|
|
25052
|
-
this.ctx = init.context;
|
|
25053
|
-
this.maxIterations = init.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
25054
|
-
this.executionStrategy = init.executionStrategy ?? "smart";
|
|
25055
|
-
this.perIterationOutputCapBytes = init.perIterationOutputCapBytes ?? 1e5;
|
|
25056
|
-
this.autoExtendLimit = init.autoExtendLimit ?? true;
|
|
25057
|
-
this.autonomousContinue = init.autonomousContinue ?? false;
|
|
25058
|
-
this.tracer = init.tracer;
|
|
25059
|
-
this.extensions = init.extensions ?? new ExtensionRegistry();
|
|
25060
|
-
this.extensions.setLogger(this.container.resolve(TOKENS.Logger));
|
|
25061
|
-
this.toolExecutor = init.toolExecutor;
|
|
25062
|
-
}
|
|
25063
|
-
get logger() {
|
|
25064
|
-
return this.container.resolve(TOKENS.Logger);
|
|
25065
|
-
}
|
|
25066
|
-
get retry() {
|
|
25067
|
-
return this.container.resolve(TOKENS.RetryPolicy);
|
|
25068
|
-
}
|
|
25069
|
-
get errorHandler() {
|
|
25070
|
-
return this.container.resolve(TOKENS.ErrorHandler);
|
|
25071
|
-
}
|
|
25072
|
-
get permission() {
|
|
25073
|
-
return this.container.resolve(TOKENS.PermissionPolicy);
|
|
25438
|
+
function createAgentLoopHandler(a, handlers) {
|
|
25439
|
+
async function compactContextIfNeeded() {
|
|
25440
|
+
await a.pipelines.contextWindow.run(a.ctx);
|
|
25074
25441
|
}
|
|
25075
|
-
|
|
25076
|
-
|
|
25442
|
+
function emitContextPct() {
|
|
25443
|
+
const maxContext = a.ctx.provider.capabilities.maxContext ?? 2e5;
|
|
25444
|
+
const { total } = estimateRequestTokens(a.ctx.messages, a.ctx.systemPrompt, a.ctx.tools ?? []);
|
|
25445
|
+
a.events.emit("ctx.pct", { load: total / maxContext, tokens: total, maxContext });
|
|
25077
25446
|
}
|
|
25078
|
-
|
|
25079
|
-
|
|
25080
|
-
|
|
25081
|
-
|
|
25082
|
-
|
|
25083
|
-
|
|
25084
|
-
|
|
25085
|
-
|
|
25086
|
-
|
|
25087
|
-
|
|
25088
|
-
|
|
25089
|
-
*/
|
|
25090
|
-
disableInteractiveConfirmation() {
|
|
25091
|
-
this.toolExecutor.clearConfirmAwaiter();
|
|
25092
|
-
const policy = this.permission;
|
|
25093
|
-
if (typeof policy.setPromptDelegate === "function") {
|
|
25094
|
-
policy.setPromptDelegate(void 0);
|
|
25447
|
+
function injectPendingBtwNotes() {
|
|
25448
|
+
const notes = consumeBtwNotes(a.ctx);
|
|
25449
|
+
if (notes.length === 0) return;
|
|
25450
|
+
const block = { type: "text", text: buildBtwBlock(notes) };
|
|
25451
|
+
const messages = a.ctx.messages;
|
|
25452
|
+
const last = messages[messages.length - 1];
|
|
25453
|
+
if (last && last.role === "user") {
|
|
25454
|
+
const content = typeof last.content === "string" ? [{ type: "text", text: last.content }, block] : [...last.content, block];
|
|
25455
|
+
a.ctx.state.replaceMessages([...messages.slice(0, -1), { ...last, content }]);
|
|
25456
|
+
} else {
|
|
25457
|
+
a.ctx.state.appendMessage({ role: "user", content: [block] });
|
|
25095
25458
|
}
|
|
25096
25459
|
}
|
|
25097
|
-
|
|
25098
|
-
|
|
25099
|
-
|
|
25100
|
-
|
|
25101
|
-
|
|
25102
|
-
|
|
25103
|
-
|
|
25104
|
-
|
|
25105
|
-
|
|
25106
|
-
|
|
25107
|
-
|
|
25108
|
-
|
|
25109
|
-
try {
|
|
25110
|
-
await plugin.teardown(api);
|
|
25111
|
-
} catch (err) {
|
|
25112
|
-
errors.push(err);
|
|
25460
|
+
async function checkIterationLimit(iterationIndex, limit, hasHardLimit, currentIterations, delegateSummaries) {
|
|
25461
|
+
if (hasHardLimit && iterationIndex >= limit) {
|
|
25462
|
+
const extendBy = await requestLimitExtension({
|
|
25463
|
+
events: a.events,
|
|
25464
|
+
currentIterations,
|
|
25465
|
+
currentLimit: limit,
|
|
25466
|
+
autoExtend: a.autoExtendLimit
|
|
25467
|
+
});
|
|
25468
|
+
if (extendBy > 0) {
|
|
25469
|
+
const newLimit = limit + extendBy;
|
|
25470
|
+
a.logger.info(`Iteration limit extended by ${extendBy} (new limit: ${newLimit})`);
|
|
25471
|
+
return { limit: newLimit };
|
|
25113
25472
|
}
|
|
25473
|
+
return { limit, exit: { status: "max_iterations", iterations: currentIterations, delegateSummaries } };
|
|
25114
25474
|
}
|
|
25115
|
-
|
|
25116
|
-
if (errors.length > 0) {
|
|
25117
|
-
throw new Error(`Agent teardown failed: ${errors.map(String).join("; ")}`);
|
|
25118
|
-
}
|
|
25119
|
-
}
|
|
25120
|
-
async run(userInput, opts = {}) {
|
|
25121
|
-
const controller = new RunController({ parentSignal: opts.signal });
|
|
25122
|
-
const signal = controller.signal;
|
|
25123
|
-
this.ctx.signal = signal;
|
|
25124
|
-
controller.onAbort(() => this.ctx.drainAbortHooks());
|
|
25125
|
-
const span = this.tracer?.startSpan("agent.run", {
|
|
25126
|
-
"agent.model": opts.model ?? this.ctx.model,
|
|
25127
|
-
"agent.executionStrategy": opts.executionStrategy ?? this.executionStrategy
|
|
25128
|
-
});
|
|
25129
|
-
const { blocks, text } = normalizeInput(userInput);
|
|
25130
|
-
const inputPayload = { content: blocks, text, ctx: this.ctx };
|
|
25131
|
-
await this.extensions.runBeforeRun(this.ctx, inputPayload);
|
|
25132
|
-
try {
|
|
25133
|
-
const result = await this.runInner(inputPayload, opts, controller);
|
|
25134
|
-
span?.setAttribute("agent.status", result.status);
|
|
25135
|
-
span?.setAttribute("agent.iterations", result.iterations);
|
|
25136
|
-
await this.extensions.runAfterRun(this.ctx, result);
|
|
25137
|
-
return result;
|
|
25138
|
-
} catch (err) {
|
|
25139
|
-
const wse = err instanceof AgentError ? err : toWrongStackError(err);
|
|
25140
|
-
this.events.emit("error", { err: toError(err), phase: "agent" });
|
|
25141
|
-
if (err instanceof Error) span?.recordError(err);
|
|
25142
|
-
span?.setAttribute("agent.status", "failed");
|
|
25143
|
-
const result = {
|
|
25144
|
-
status: signal.aborted ? "aborted" : "failed",
|
|
25145
|
-
iterations: 0,
|
|
25146
|
-
error: wse
|
|
25147
|
-
};
|
|
25148
|
-
await this.extensions.runAfterRun(this.ctx, result);
|
|
25149
|
-
return result;
|
|
25150
|
-
} finally {
|
|
25151
|
-
span?.end();
|
|
25152
|
-
await controller.dispose();
|
|
25153
|
-
}
|
|
25475
|
+
return { limit };
|
|
25154
25476
|
}
|
|
25155
|
-
async runInner(inputPayload, opts, controller) {
|
|
25156
|
-
await
|
|
25157
|
-
|
|
25158
|
-
await
|
|
25477
|
+
async function runInner(inputPayload, opts, controller, autonomousContinue) {
|
|
25478
|
+
await a.pipelines.userInput.run(inputPayload);
|
|
25479
|
+
a.ctx.state.appendMessage({ role: "user", content: inputPayload.content });
|
|
25480
|
+
await a.ctx.session.append({
|
|
25159
25481
|
type: "user_input",
|
|
25160
25482
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25161
25483
|
content: inputPayload.content
|
|
25162
25484
|
});
|
|
25163
|
-
const promptIndex =
|
|
25485
|
+
const promptIndex = a.ctx.messages.filter((m) => m.role === "user").length - 1;
|
|
25164
25486
|
const preview = inputPayload.text.slice(0, 80) + (inputPayload.text.length > 80 ? "\u2026" : "");
|
|
25165
|
-
await
|
|
25487
|
+
await a.ctx.session.writeCheckpoint(promptIndex, preview);
|
|
25166
25488
|
let finalText = "";
|
|
25167
25489
|
let iterations = 0;
|
|
25168
25490
|
const delegateSummaries = [];
|
|
25169
|
-
let effectiveLimit = opts.maxIterations ??
|
|
25491
|
+
let effectiveLimit = opts.maxIterations ?? a.maxIterations;
|
|
25170
25492
|
const hasHardLimit = effectiveLimit > 0 && Number.isFinite(effectiveLimit);
|
|
25171
25493
|
let recoveryRetries = 0;
|
|
25172
|
-
const autonomousContinue = opts.autonomousContinue ?? this.autonomousContinue;
|
|
25173
25494
|
const onSubagentDone = ({ summary, ok }) => {
|
|
25174
25495
|
delegateSummaries.push({ summary, ok });
|
|
25175
25496
|
};
|
|
25176
|
-
const offSubagentDone =
|
|
25177
|
-
const diRunner =
|
|
25497
|
+
const offSubagentDone = a.events.on("subagent.done", onSubagentDone);
|
|
25498
|
+
const diRunner = a.container.has(TOKENS.ProviderRunner) ? a.container.resolve(TOKENS.ProviderRunner) : null;
|
|
25178
25499
|
const baseRunner = diRunner ? (ctx, req) => diRunner.run({
|
|
25179
25500
|
provider: ctx.provider,
|
|
25180
25501
|
request: req,
|
|
25181
25502
|
signal: controller.signal,
|
|
25182
25503
|
ctx,
|
|
25183
|
-
events:
|
|
25184
|
-
retry:
|
|
25185
|
-
logger:
|
|
25186
|
-
tracer:
|
|
25504
|
+
events: a.events,
|
|
25505
|
+
retry: a.retry,
|
|
25506
|
+
logger: a.logger,
|
|
25507
|
+
tracer: a.tracer
|
|
25187
25508
|
}) : async (ctx, req) => runProviderWithRetry({
|
|
25188
25509
|
provider: ctx.provider,
|
|
25189
25510
|
request: req,
|
|
25190
25511
|
signal: controller.signal,
|
|
25191
25512
|
ctx,
|
|
25192
|
-
events:
|
|
25193
|
-
retry:
|
|
25194
|
-
logger:
|
|
25195
|
-
tracer:
|
|
25513
|
+
events: a.events,
|
|
25514
|
+
retry: a.retry,
|
|
25515
|
+
logger: a.logger,
|
|
25516
|
+
tracer: a.tracer
|
|
25196
25517
|
});
|
|
25197
|
-
const customRunner =
|
|
25518
|
+
const customRunner = a.extensions.wrapProviderRunner(baseRunner);
|
|
25198
25519
|
try {
|
|
25199
25520
|
for (let i = 0; ; i++) {
|
|
25200
25521
|
iterations = i + 1;
|
|
25201
25522
|
if (controller.signal.aborted) {
|
|
25202
25523
|
return { status: "aborted", iterations };
|
|
25203
25524
|
}
|
|
25204
|
-
await
|
|
25205
|
-
|
|
25525
|
+
await a.ctx.session.writeInFlightMarker(`iteration ${i} / max ${a.maxIterations}`).catch((err) => {
|
|
25526
|
+
a.logger.debug?.(
|
|
25206
25527
|
`in-flight marker write failed: ${err instanceof Error ? err.message : String(err)}`
|
|
25207
25528
|
);
|
|
25208
25529
|
});
|
|
25209
25530
|
if (autonomousContinue) {
|
|
25210
|
-
consumeAutonomousContinue(
|
|
25531
|
+
consumeAutonomousContinue(a.ctx);
|
|
25211
25532
|
}
|
|
25212
|
-
const limitCheck = await
|
|
25533
|
+
const limitCheck = await checkIterationLimit(
|
|
25213
25534
|
i,
|
|
25214
25535
|
effectiveLimit,
|
|
25215
25536
|
hasHardLimit,
|
|
@@ -25220,11 +25541,11 @@ var Agent = class {
|
|
|
25220
25541
|
if (limitCheck.exit) {
|
|
25221
25542
|
return { ...limitCheck.exit, finalText };
|
|
25222
25543
|
}
|
|
25223
|
-
await
|
|
25224
|
-
|
|
25225
|
-
|
|
25226
|
-
const req = await
|
|
25227
|
-
await
|
|
25544
|
+
await a.extensions.runBeforeIteration(a.ctx, i);
|
|
25545
|
+
a.events.emit("iteration.started", { ctx: a.ctx, index: i });
|
|
25546
|
+
injectPendingBtwNotes();
|
|
25547
|
+
const req = await handlers.response.buildAndRunRequestPipeline(opts);
|
|
25548
|
+
await a.ctx.session.append({
|
|
25228
25549
|
type: "llm_request",
|
|
25229
25550
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25230
25551
|
model: req.model,
|
|
@@ -25235,39 +25556,39 @@ var Agent = class {
|
|
|
25235
25556
|
});
|
|
25236
25557
|
let res;
|
|
25237
25558
|
try {
|
|
25238
|
-
res = await customRunner(
|
|
25559
|
+
res = await customRunner(a.ctx, req);
|
|
25239
25560
|
const calibratedEstimate = estimateRequestTokensCalibrated(req.messages, req.system, req.tools ?? []).total;
|
|
25240
25561
|
recordActualUsage(res.usage.input, calibratedEstimate);
|
|
25241
25562
|
recoveryRetries = 0;
|
|
25242
25563
|
} catch (err) {
|
|
25243
25564
|
if (controller.signal.aborted) {
|
|
25244
|
-
|
|
25565
|
+
a.events.emit("error", { err: toError(err), phase: "provider" });
|
|
25245
25566
|
return { status: "aborted", iterations, error: toWrongStackError(err, "AGENT_ABORTED") };
|
|
25246
25567
|
}
|
|
25247
|
-
const extDecision = await
|
|
25568
|
+
const extDecision = await a.extensions.runOnError(a.ctx, err, "provider", i);
|
|
25248
25569
|
if (extDecision) {
|
|
25249
25570
|
if (extDecision.action === "fail") {
|
|
25250
|
-
|
|
25571
|
+
a.events.emit("error", { err: toError(err), phase: "provider" });
|
|
25251
25572
|
return { status: "failed", iterations, error: toWrongStackError(err), delegateSummaries };
|
|
25252
25573
|
}
|
|
25253
25574
|
if (extDecision.action === "continue") {
|
|
25254
|
-
await
|
|
25575
|
+
await a.extensions.runAfterIteration(a.ctx, i);
|
|
25255
25576
|
continue;
|
|
25256
25577
|
}
|
|
25257
25578
|
if (extDecision.action === "retry") {
|
|
25258
25579
|
recoveryRetries++;
|
|
25259
25580
|
if (recoveryRetries > 2) {
|
|
25260
|
-
|
|
25581
|
+
a.events.emit("error", { err: toError(err), phase: "provider" });
|
|
25261
25582
|
return { status: "failed", iterations, error: toWrongStackError(err), delegateSummaries };
|
|
25262
25583
|
}
|
|
25263
|
-
if (extDecision.model)
|
|
25264
|
-
|
|
25584
|
+
if (extDecision.model) a.ctx.model = extDecision.model;
|
|
25585
|
+
a.logger.info("Extension requested retry; retrying turn");
|
|
25265
25586
|
continue;
|
|
25266
25587
|
}
|
|
25267
25588
|
}
|
|
25268
|
-
const recovered = await
|
|
25589
|
+
const recovered = await a.errorHandler.recover(err, a.ctx);
|
|
25269
25590
|
if (!recovered || recovered.action === "fail") {
|
|
25270
|
-
|
|
25591
|
+
a.events.emit("error", { err: toError(err), phase: "provider" });
|
|
25271
25592
|
return {
|
|
25272
25593
|
status: "failed",
|
|
25273
25594
|
iterations,
|
|
@@ -25278,17 +25599,17 @@ var Agent = class {
|
|
|
25278
25599
|
if (recovered.action === "retry") {
|
|
25279
25600
|
recoveryRetries++;
|
|
25280
25601
|
if (recoveryRetries > 2) {
|
|
25281
|
-
|
|
25602
|
+
a.events.emit("error", { err: toError(err), phase: "provider" });
|
|
25282
25603
|
return { status: "failed", iterations, error: toWrongStackError(err) };
|
|
25283
25604
|
}
|
|
25284
|
-
if (recovered.model)
|
|
25285
|
-
|
|
25605
|
+
if (recovered.model) a.ctx.model = recovered.model;
|
|
25606
|
+
a.logger.info(`Recovered provider error via ${recovered.reason}; retrying turn`);
|
|
25286
25607
|
continue;
|
|
25287
25608
|
}
|
|
25288
25609
|
recoveryRetries = 0;
|
|
25289
25610
|
res = recovered.response;
|
|
25290
25611
|
}
|
|
25291
|
-
const responseResult = await
|
|
25612
|
+
const responseResult = await handlers.response.processResponse(res, req);
|
|
25292
25613
|
if (responseResult.aborted) {
|
|
25293
25614
|
return { status: "aborted", iterations, finalText: responseResult.finalText, delegateSummaries };
|
|
25294
25615
|
}
|
|
@@ -25298,11 +25619,11 @@ var Agent = class {
|
|
|
25298
25619
|
finalText = responseResult.finalText;
|
|
25299
25620
|
const toolUses = res.content.filter(isToolUseBlock);
|
|
25300
25621
|
if (toolUses.length === 0) {
|
|
25301
|
-
|
|
25302
|
-
|
|
25622
|
+
emitContextPct();
|
|
25623
|
+
a.events.emit("iteration.completed", { ctx: a.ctx, index: i });
|
|
25303
25624
|
if (autonomousContinue && responseResult.directive === "continue") {
|
|
25304
|
-
await
|
|
25305
|
-
await
|
|
25625
|
+
await compactContextIfNeeded();
|
|
25626
|
+
await a.extensions.runAfterIteration(a.ctx, i);
|
|
25306
25627
|
continue;
|
|
25307
25628
|
}
|
|
25308
25629
|
if (autonomousContinue && responseResult.directive === "stop") {
|
|
@@ -25310,18 +25631,18 @@ var Agent = class {
|
|
|
25310
25631
|
}
|
|
25311
25632
|
return { status: "done", iterations, finalText, delegateSummaries };
|
|
25312
25633
|
}
|
|
25313
|
-
await
|
|
25314
|
-
if (autonomousContinue && consumeAutonomousContinue(
|
|
25315
|
-
|
|
25316
|
-
|
|
25317
|
-
await
|
|
25318
|
-
await
|
|
25634
|
+
await handlers.tools.executeTools(toolUses);
|
|
25635
|
+
if (autonomousContinue && consumeAutonomousContinue(a.ctx)) {
|
|
25636
|
+
emitContextPct();
|
|
25637
|
+
a.events.emit("iteration.completed", { ctx: a.ctx, index: i });
|
|
25638
|
+
await compactContextIfNeeded();
|
|
25639
|
+
await a.extensions.runAfterIteration(a.ctx, i);
|
|
25319
25640
|
continue;
|
|
25320
25641
|
}
|
|
25321
|
-
|
|
25322
|
-
|
|
25323
|
-
await
|
|
25324
|
-
await
|
|
25642
|
+
emitContextPct();
|
|
25643
|
+
a.events.emit("iteration.completed", { ctx: a.ctx, index: i });
|
|
25644
|
+
await compactContextIfNeeded();
|
|
25645
|
+
await a.extensions.runAfterIteration(a.ctx, i);
|
|
25325
25646
|
if (autonomousContinue && responseResult.directive === "continue") {
|
|
25326
25647
|
continue;
|
|
25327
25648
|
}
|
|
@@ -25330,348 +25651,417 @@ var Agent = class {
|
|
|
25330
25651
|
}
|
|
25331
25652
|
}
|
|
25332
25653
|
} finally {
|
|
25333
|
-
offSubagentDone();
|
|
25334
|
-
const reason = controller.signal.aborted ? "aborted" : "clean";
|
|
25335
|
-
await
|
|
25336
|
-
|
|
25337
|
-
`in-flight marker clear failed: ${err instanceof Error ? err.message : String(err)}`
|
|
25338
|
-
);
|
|
25339
|
-
});
|
|
25654
|
+
offSubagentDone();
|
|
25655
|
+
const reason = controller.signal.aborted ? "aborted" : "clean";
|
|
25656
|
+
await a.ctx.session.clearInFlightMarker(reason).catch((err) => {
|
|
25657
|
+
a.logger.debug?.(
|
|
25658
|
+
`in-flight marker clear failed: ${err instanceof Error ? err.message : String(err)}`
|
|
25659
|
+
);
|
|
25660
|
+
});
|
|
25661
|
+
}
|
|
25662
|
+
}
|
|
25663
|
+
return { runInner };
|
|
25664
|
+
}
|
|
25665
|
+
|
|
25666
|
+
// src/core/agent-types.ts
|
|
25667
|
+
var DEFAULT_MAX_ITERATIONS = 100;
|
|
25668
|
+
function normalizeInput(input) {
|
|
25669
|
+
if (typeof input === "string") {
|
|
25670
|
+
return { blocks: [{ type: "text", text: input }], text: input };
|
|
25671
|
+
}
|
|
25672
|
+
const text = input.filter(isTextBlock).map((b) => b.text).join("");
|
|
25673
|
+
return { blocks: input, text };
|
|
25674
|
+
}
|
|
25675
|
+
function createDefaultPipelines() {
|
|
25676
|
+
return {
|
|
25677
|
+
request: new Pipeline(),
|
|
25678
|
+
response: new Pipeline(),
|
|
25679
|
+
toolCall: new Pipeline(),
|
|
25680
|
+
userInput: new Pipeline(),
|
|
25681
|
+
assistantOutput: new Pipeline(),
|
|
25682
|
+
contextWindow: new Pipeline()
|
|
25683
|
+
};
|
|
25684
|
+
}
|
|
25685
|
+
|
|
25686
|
+
// src/core/agent.ts
|
|
25687
|
+
var Agent = class {
|
|
25688
|
+
container;
|
|
25689
|
+
tools;
|
|
25690
|
+
providers;
|
|
25691
|
+
events;
|
|
25692
|
+
pipelines;
|
|
25693
|
+
ctx;
|
|
25694
|
+
maxIterations;
|
|
25695
|
+
executionStrategy;
|
|
25696
|
+
perIterationOutputCapBytes;
|
|
25697
|
+
plugins = [];
|
|
25698
|
+
toolExecutor;
|
|
25699
|
+
autoExtendLimit;
|
|
25700
|
+
autonomousContinue;
|
|
25701
|
+
tracer;
|
|
25702
|
+
extensions;
|
|
25703
|
+
_toolHandler;
|
|
25704
|
+
_responseHandler;
|
|
25705
|
+
_loopHandler;
|
|
25706
|
+
constructor(init) {
|
|
25707
|
+
this.container = init.container;
|
|
25708
|
+
this.tools = init.tools;
|
|
25709
|
+
this.providers = init.providers;
|
|
25710
|
+
this.events = init.events;
|
|
25711
|
+
this.pipelines = init.pipelines;
|
|
25712
|
+
this.ctx = init.context;
|
|
25713
|
+
this.maxIterations = init.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
25714
|
+
this.executionStrategy = init.executionStrategy ?? "smart";
|
|
25715
|
+
this.perIterationOutputCapBytes = init.perIterationOutputCapBytes ?? 1e5;
|
|
25716
|
+
this.autoExtendLimit = init.autoExtendLimit ?? true;
|
|
25717
|
+
this.autonomousContinue = init.autonomousContinue ?? false;
|
|
25718
|
+
this.tracer = init.tracer;
|
|
25719
|
+
this.extensions = init.extensions ?? new ExtensionRegistry();
|
|
25720
|
+
this.extensions.setLogger(this.container.resolve(TOKENS.Logger));
|
|
25721
|
+
this.toolExecutor = init.toolExecutor;
|
|
25722
|
+
this._toolHandler = createAgentToolHandler(this);
|
|
25723
|
+
this._responseHandler = createAgentResponseHandler(this);
|
|
25724
|
+
this._loopHandler = createAgentLoopHandler(this, {
|
|
25725
|
+
tools: this._toolHandler,
|
|
25726
|
+
response: this._responseHandler
|
|
25727
|
+
});
|
|
25728
|
+
}
|
|
25729
|
+
get logger() {
|
|
25730
|
+
return this.container.resolve(TOKENS.Logger);
|
|
25731
|
+
}
|
|
25732
|
+
get retry() {
|
|
25733
|
+
return this.container.resolve(TOKENS.RetryPolicy);
|
|
25734
|
+
}
|
|
25735
|
+
get errorHandler() {
|
|
25736
|
+
return this.container.resolve(TOKENS.ErrorHandler);
|
|
25737
|
+
}
|
|
25738
|
+
get permission() {
|
|
25739
|
+
return this.container.resolve(TOKENS.PermissionPolicy);
|
|
25740
|
+
}
|
|
25741
|
+
get renderer() {
|
|
25742
|
+
return this.container.has(TOKENS.Renderer) ? this.container.resolve(TOKENS.Renderer) : void 0;
|
|
25743
|
+
}
|
|
25744
|
+
disableInteractiveConfirmation() {
|
|
25745
|
+
this.toolExecutor.clearConfirmAwaiter();
|
|
25746
|
+
const policy = this.permission;
|
|
25747
|
+
if (typeof policy.setPromptDelegate === "function") {
|
|
25748
|
+
policy.setPromptDelegate(void 0);
|
|
25749
|
+
}
|
|
25750
|
+
}
|
|
25751
|
+
register(tool) {
|
|
25752
|
+
this.tools.register(tool);
|
|
25753
|
+
}
|
|
25754
|
+
async use(plugin, api) {
|
|
25755
|
+
await plugin.setup(api);
|
|
25756
|
+
this.plugins.push({ plugin, api });
|
|
25757
|
+
}
|
|
25758
|
+
async teardown() {
|
|
25759
|
+
const errors = [];
|
|
25760
|
+
for (const { plugin, api } of this.plugins.toReversed()) {
|
|
25761
|
+
if (typeof plugin.teardown !== "function") continue;
|
|
25762
|
+
try {
|
|
25763
|
+
await plugin.teardown(api);
|
|
25764
|
+
} catch (err) {
|
|
25765
|
+
errors.push(err);
|
|
25766
|
+
}
|
|
25767
|
+
}
|
|
25768
|
+
this.plugins.length = 0;
|
|
25769
|
+
if (errors.length > 0) {
|
|
25770
|
+
throw new Error(`Agent teardown failed: ${errors.map(String).join("; ")}`);
|
|
25771
|
+
}
|
|
25772
|
+
}
|
|
25773
|
+
async run(userInput, opts = {}) {
|
|
25774
|
+
const controller = new RunController({ parentSignal: opts.signal });
|
|
25775
|
+
const signal = controller.signal;
|
|
25776
|
+
this.ctx.signal = signal;
|
|
25777
|
+
controller.onAbort(() => this.ctx.drainAbortHooks());
|
|
25778
|
+
const span = this.tracer?.startSpan("agent.run", {
|
|
25779
|
+
"agent.model": opts.model ?? this.ctx.model,
|
|
25780
|
+
"agent.executionStrategy": opts.executionStrategy ?? this.executionStrategy
|
|
25781
|
+
});
|
|
25782
|
+
const { blocks, text } = normalizeInput(userInput);
|
|
25783
|
+
const inputPayload = { content: blocks, text, ctx: this.ctx };
|
|
25784
|
+
await this.extensions.runBeforeRun(this.ctx, inputPayload);
|
|
25785
|
+
try {
|
|
25786
|
+
const autonomousContinue = opts.autonomousContinue ?? this.autonomousContinue;
|
|
25787
|
+
const result = await this._loopHandler.runInner(inputPayload, opts, controller, autonomousContinue);
|
|
25788
|
+
span?.setAttribute("agent.status", result.status);
|
|
25789
|
+
span?.setAttribute("agent.iterations", result.iterations);
|
|
25790
|
+
await this.extensions.runAfterRun(this.ctx, result);
|
|
25791
|
+
return result;
|
|
25792
|
+
} catch (err) {
|
|
25793
|
+
const wse = err instanceof AgentError ? err : toWrongStackError(err);
|
|
25794
|
+
this.events.emit("error", { err: err instanceof Error ? err : new Error(String(err)), phase: "agent" });
|
|
25795
|
+
if (err instanceof Error) span?.recordError(err);
|
|
25796
|
+
span?.setAttribute("agent.status", "failed");
|
|
25797
|
+
const result = {
|
|
25798
|
+
status: signal.aborted ? "aborted" : "failed",
|
|
25799
|
+
iterations: 0,
|
|
25800
|
+
error: wse
|
|
25801
|
+
};
|
|
25802
|
+
await this.extensions.runAfterRun(this.ctx, result);
|
|
25803
|
+
return result;
|
|
25804
|
+
} finally {
|
|
25805
|
+
span?.end();
|
|
25806
|
+
await controller.dispose();
|
|
25340
25807
|
}
|
|
25341
25808
|
}
|
|
25342
|
-
|
|
25343
|
-
|
|
25344
|
-
|
|
25345
|
-
|
|
25346
|
-
|
|
25347
|
-
|
|
25348
|
-
|
|
25349
|
-
|
|
25350
|
-
|
|
25351
|
-
|
|
25352
|
-
|
|
25353
|
-
|
|
25354
|
-
|
|
25355
|
-
|
|
25356
|
-
|
|
25357
|
-
|
|
25358
|
-
|
|
25359
|
-
|
|
25809
|
+
// ── Tool + response execution handled by AgentToolHandler / AgentResponseHandler ──
|
|
25810
|
+
};
|
|
25811
|
+
|
|
25812
|
+
// src/hooks/registry.ts
|
|
25813
|
+
var HookRegistry = class {
|
|
25814
|
+
entries = [];
|
|
25815
|
+
/** Register an in-process hook. Returns an unsubscribe function. */
|
|
25816
|
+
registerInProcess(event, matcher, hook, owner) {
|
|
25817
|
+
const entry = {
|
|
25818
|
+
kind: "inprocess",
|
|
25819
|
+
event,
|
|
25820
|
+
matcher: matcher ?? "*",
|
|
25821
|
+
hook,
|
|
25822
|
+
owner
|
|
25823
|
+
};
|
|
25824
|
+
this.entries.push(entry);
|
|
25825
|
+
return () => this.remove(entry);
|
|
25826
|
+
}
|
|
25827
|
+
/** Register a single shell hook. Returns an unsubscribe function. */
|
|
25828
|
+
registerShell(event, hook) {
|
|
25829
|
+
const entry = {
|
|
25830
|
+
kind: "shell",
|
|
25831
|
+
event,
|
|
25832
|
+
matcher: hook.matcher ?? "*",
|
|
25833
|
+
command: hook.command,
|
|
25834
|
+
timeoutMs: hook.timeoutMs
|
|
25835
|
+
};
|
|
25836
|
+
this.entries.push(entry);
|
|
25837
|
+
return () => this.remove(entry);
|
|
25838
|
+
}
|
|
25839
|
+
/** Bulk-load shell hooks from a `config.hooks` map. */
|
|
25840
|
+
loadShellHooks(hooks) {
|
|
25841
|
+
if (!hooks) return;
|
|
25842
|
+
for (const [event, list] of Object.entries(hooks)) {
|
|
25843
|
+
for (const h of list ?? []) {
|
|
25844
|
+
if (h?.command) this.registerShell(event, h);
|
|
25360
25845
|
}
|
|
25361
|
-
return { limit, exit: { status: "max_iterations", iterations: currentIterations, delegateSummaries } };
|
|
25362
25846
|
}
|
|
25363
|
-
return { limit };
|
|
25364
25847
|
}
|
|
25365
|
-
/**
|
|
25366
|
-
|
|
25367
|
-
|
|
25368
|
-
|
|
25369
|
-
|
|
25370
|
-
|
|
25371
|
-
|
|
25372
|
-
|
|
25373
|
-
|
|
25374
|
-
|
|
25848
|
+
/** All entries registered for an event, in registration order. */
|
|
25849
|
+
list(event) {
|
|
25850
|
+
return this.entries.filter((e) => e.event === event);
|
|
25851
|
+
}
|
|
25852
|
+
/** True when any entry is registered for the event. */
|
|
25853
|
+
has(event) {
|
|
25854
|
+
return this.entries.some((e) => e.event === event);
|
|
25855
|
+
}
|
|
25856
|
+
/** Drop every registered hook (used in teardown / tests). */
|
|
25857
|
+
clear() {
|
|
25858
|
+
this.entries.length = 0;
|
|
25859
|
+
}
|
|
25860
|
+
remove(entry) {
|
|
25861
|
+
const i = this.entries.indexOf(entry);
|
|
25862
|
+
if (i >= 0) this.entries.splice(i, 1);
|
|
25863
|
+
}
|
|
25864
|
+
};
|
|
25865
|
+
function hookMatcherMatches(matcher, toolName) {
|
|
25866
|
+
if (!matcher || matcher === "*") return true;
|
|
25867
|
+
if (toolName === void 0) return true;
|
|
25868
|
+
const target = toolName.toLowerCase();
|
|
25869
|
+
return matcher.split("|").map((s) => s.trim().toLowerCase()).filter(Boolean).includes(target);
|
|
25870
|
+
}
|
|
25871
|
+
var DEFAULT_TIMEOUT_MS3 = 5e3;
|
|
25872
|
+
var MAX_OUTPUT_BYTES = 64 * 1024;
|
|
25873
|
+
async function runShellHook(spec, input, logger) {
|
|
25874
|
+
const timeoutMs = spec.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
|
|
25875
|
+
return await new Promise((resolve13) => {
|
|
25876
|
+
let settled = false;
|
|
25877
|
+
const done = (v) => {
|
|
25878
|
+
if (settled) return;
|
|
25879
|
+
settled = true;
|
|
25880
|
+
clearTimeout(timer);
|
|
25881
|
+
resolve13(v);
|
|
25882
|
+
};
|
|
25883
|
+
let child;
|
|
25884
|
+
try {
|
|
25885
|
+
child = spawn(spec.command, {
|
|
25886
|
+
cwd: input.cwd,
|
|
25887
|
+
env: process.env,
|
|
25888
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
25889
|
+
shell: true
|
|
25375
25890
|
});
|
|
25376
|
-
|
|
25377
|
-
|
|
25378
|
-
);
|
|
25891
|
+
} catch (err2) {
|
|
25892
|
+
logger?.warn?.(`hook spawn failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
25893
|
+
return resolve13(null);
|
|
25379
25894
|
}
|
|
25380
|
-
const
|
|
25381
|
-
|
|
25382
|
-
|
|
25383
|
-
|
|
25384
|
-
|
|
25385
|
-
|
|
25386
|
-
|
|
25387
|
-
|
|
25388
|
-
|
|
25389
|
-
|
|
25390
|
-
|
|
25391
|
-
|
|
25392
|
-
|
|
25393
|
-
|
|
25394
|
-
|
|
25395
|
-
|
|
25396
|
-
|
|
25397
|
-
|
|
25398
|
-
usage: res.usage,
|
|
25399
|
-
stopReason: res.stopReason
|
|
25895
|
+
const timer = setTimeout(() => {
|
|
25896
|
+
logger?.warn?.(`hook command timed out after ${timeoutMs}ms: ${spec.command}`);
|
|
25897
|
+
try {
|
|
25898
|
+
child.kill("SIGKILL");
|
|
25899
|
+
} catch {
|
|
25900
|
+
}
|
|
25901
|
+
done(null);
|
|
25902
|
+
}, timeoutMs);
|
|
25903
|
+
let out = "";
|
|
25904
|
+
let err = "";
|
|
25905
|
+
let outTrunc = false;
|
|
25906
|
+
child.stdout?.on("data", (d) => {
|
|
25907
|
+
if (outTrunc) return;
|
|
25908
|
+
out += d.toString("utf8");
|
|
25909
|
+
if (Buffer.byteLength(out, "utf8") > MAX_OUTPUT_BYTES) {
|
|
25910
|
+
out = out.slice(0, MAX_OUTPUT_BYTES);
|
|
25911
|
+
outTrunc = true;
|
|
25912
|
+
}
|
|
25400
25913
|
});
|
|
25401
|
-
|
|
25402
|
-
|
|
25403
|
-
await this.ctx.session.append({
|
|
25404
|
-
type: "llm_response",
|
|
25405
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25406
|
-
content: res.content,
|
|
25407
|
-
stopReason: res.stopReason,
|
|
25408
|
-
usage: res.usage
|
|
25914
|
+
child.stderr?.on("data", (d) => {
|
|
25915
|
+
if (err.length < MAX_OUTPUT_BYTES) err += d.toString("utf8");
|
|
25409
25916
|
});
|
|
25410
|
-
|
|
25411
|
-
|
|
25412
|
-
|
|
25413
|
-
|
|
25917
|
+
child.on("error", (e) => {
|
|
25918
|
+
logger?.warn?.(`hook command error: ${e instanceof Error ? e.message : String(e)}`);
|
|
25919
|
+
done(null);
|
|
25920
|
+
});
|
|
25921
|
+
child.on("close", (code) => {
|
|
25922
|
+
if (code === 2) {
|
|
25923
|
+
const reason = (err.trim() || out.trim() || "blocked by hook").slice(0, 2e3);
|
|
25924
|
+
return done({ decision: "block", reason });
|
|
25414
25925
|
}
|
|
25415
|
-
|
|
25926
|
+
const parsed = parseOutcome(out);
|
|
25927
|
+
done(parsed);
|
|
25928
|
+
});
|
|
25929
|
+
try {
|
|
25930
|
+
child.stdin?.end(`${JSON.stringify(input)}
|
|
25931
|
+
`);
|
|
25932
|
+
} catch {
|
|
25416
25933
|
}
|
|
25417
|
-
|
|
25418
|
-
|
|
25419
|
-
|
|
25420
|
-
|
|
25421
|
-
|
|
25422
|
-
|
|
25423
|
-
|
|
25424
|
-
|
|
25934
|
+
});
|
|
25935
|
+
}
|
|
25936
|
+
function parseOutcome(stdout) {
|
|
25937
|
+
const trimmed = stdout.trim();
|
|
25938
|
+
if (!trimmed || trimmed[0] !== "{") return null;
|
|
25939
|
+
try {
|
|
25940
|
+
const obj = JSON.parse(trimmed);
|
|
25941
|
+
const outcome = {};
|
|
25942
|
+
if (obj["decision"] === "block" || obj["decision"] === "allow") {
|
|
25943
|
+
outcome.decision = obj["decision"];
|
|
25425
25944
|
}
|
|
25426
|
-
|
|
25427
|
-
if (
|
|
25428
|
-
|
|
25945
|
+
if (typeof obj["reason"] === "string") outcome.reason = obj["reason"];
|
|
25946
|
+
if (typeof obj["additionalContext"] === "string") {
|
|
25947
|
+
outcome.additionalContext = obj["additionalContext"];
|
|
25429
25948
|
}
|
|
25430
|
-
|
|
25949
|
+
if (obj["modifiedInput"] && typeof obj["modifiedInput"] === "object") {
|
|
25950
|
+
outcome.modifiedInput = obj["modifiedInput"];
|
|
25951
|
+
}
|
|
25952
|
+
return outcome;
|
|
25953
|
+
} catch {
|
|
25954
|
+
return null;
|
|
25431
25955
|
}
|
|
25432
|
-
|
|
25433
|
-
|
|
25434
|
-
|
|
25435
|
-
|
|
25436
|
-
|
|
25437
|
-
|
|
25438
|
-
|
|
25439
|
-
|
|
25440
|
-
|
|
25441
|
-
|
|
25442
|
-
|
|
25443
|
-
|
|
25444
|
-
|
|
25445
|
-
|
|
25446
|
-
|
|
25447
|
-
const
|
|
25448
|
-
|
|
25449
|
-
|
|
25450
|
-
|
|
25451
|
-
|
|
25452
|
-
|
|
25453
|
-
|
|
25454
|
-
|
|
25455
|
-
|
|
25456
|
-
|
|
25457
|
-
|
|
25458
|
-
|
|
25459
|
-
|
|
25460
|
-
|
|
25461
|
-
|
|
25462
|
-
|
|
25463
|
-
tool: tool.name,
|
|
25464
|
-
pattern: result.suggestedPattern,
|
|
25465
|
-
decision
|
|
25466
|
-
});
|
|
25467
|
-
} catch {
|
|
25468
|
-
}
|
|
25469
|
-
} else if (decision === "deny") {
|
|
25470
|
-
try {
|
|
25471
|
-
await this.permission.deny({
|
|
25472
|
-
tool: tool.name,
|
|
25473
|
-
pattern: result.suggestedPattern
|
|
25474
|
-
});
|
|
25475
|
-
this.events.emit("trust.persisted", {
|
|
25476
|
-
tool: tool.name,
|
|
25477
|
-
pattern: result.suggestedPattern,
|
|
25478
|
-
decision
|
|
25479
|
-
});
|
|
25480
|
-
} catch {
|
|
25481
|
-
}
|
|
25482
|
-
}
|
|
25483
|
-
if (decision === "yes") {
|
|
25484
|
-
const p = this.permission;
|
|
25485
|
-
p.allowOnce?.({ tool: tool.name, pattern: result.suggestedPattern });
|
|
25486
|
-
} else if (decision === "no") {
|
|
25487
|
-
const p = this.permission;
|
|
25488
|
-
p.denyOnce?.({ tool: tool.name, pattern: result.suggestedPattern });
|
|
25489
|
-
}
|
|
25490
|
-
const reRunResult = decision === "yes" || decision === "always" ? await this.executeSingleWithDecision(
|
|
25491
|
-
tool,
|
|
25492
|
-
{ id: result.toolUseId, name: tool.name, input: result.input }
|
|
25493
|
-
) : {
|
|
25494
|
-
result: {
|
|
25495
|
-
type: "tool_result",
|
|
25496
|
-
tool_use_id: result.toolUseId,
|
|
25497
|
-
content: decision === "deny" ? `Tool "${tool.name}" denied and blocked for this pattern.` : `Tool "${tool.name}" denied by user.`,
|
|
25498
|
-
is_error: true
|
|
25499
|
-
},
|
|
25500
|
-
durationMs: 0
|
|
25501
|
-
};
|
|
25502
|
-
const use2 = useById.get(reRunResult.result.tool_use_id);
|
|
25503
|
-
if (use2) {
|
|
25504
|
-
await this.pipelines.toolCall.run({
|
|
25505
|
-
toolUse: use2,
|
|
25506
|
-
result: reRunResult.result,
|
|
25507
|
-
ctx: this.ctx,
|
|
25508
|
-
tool
|
|
25509
|
-
});
|
|
25510
|
-
await this.ctx.session.append({
|
|
25511
|
-
type: "tool_result",
|
|
25512
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25513
|
-
id: reRunResult.result.tool_use_id,
|
|
25514
|
-
content: reRunResult.result.content,
|
|
25515
|
-
isError: !!reRunResult.result.is_error
|
|
25516
|
-
});
|
|
25517
|
-
{
|
|
25518
|
-
const sig = sizeSignals(tool?.name, reRunResult.result.content);
|
|
25519
|
-
this.events.emit("tool.executed", {
|
|
25520
|
-
id: reRunResult.result.tool_use_id,
|
|
25521
|
-
name: tool.name,
|
|
25522
|
-
durationMs: reRunResult.durationMs,
|
|
25523
|
-
ok: !reRunResult.result.is_error,
|
|
25524
|
-
input: result.input,
|
|
25525
|
-
output: truncateForEvent(reRunResult.result.content),
|
|
25526
|
-
outputBytes: sig.outputBytes,
|
|
25527
|
-
outputTokens: sig.outputTokens,
|
|
25528
|
-
outputLines: sig.outputLines
|
|
25529
|
-
});
|
|
25530
|
-
}
|
|
25531
|
-
}
|
|
25532
|
-
resultsForMessage.push(reRunResult.result);
|
|
25533
|
-
continue;
|
|
25956
|
+
}
|
|
25957
|
+
|
|
25958
|
+
// src/hooks/runner.ts
|
|
25959
|
+
var HookRunner = class {
|
|
25960
|
+
constructor(opts) {
|
|
25961
|
+
this.opts = opts;
|
|
25962
|
+
this.registry = opts.registry;
|
|
25963
|
+
}
|
|
25964
|
+
opts;
|
|
25965
|
+
registry;
|
|
25966
|
+
/** Cheap guard so callers can skip building payloads when nothing listens. */
|
|
25967
|
+
has(event) {
|
|
25968
|
+
return this.registry.has(event);
|
|
25969
|
+
}
|
|
25970
|
+
async preToolUse(toolName, toolInput, env) {
|
|
25971
|
+
const entries = this.matching("PreToolUse", toolName);
|
|
25972
|
+
if (entries.length === 0) return {};
|
|
25973
|
+
let current = toolInput;
|
|
25974
|
+
let mutated = false;
|
|
25975
|
+
for (const entry of entries) {
|
|
25976
|
+
const payload = {
|
|
25977
|
+
event: "PreToolUse",
|
|
25978
|
+
toolName,
|
|
25979
|
+
toolInput: current,
|
|
25980
|
+
...this.base(env)
|
|
25981
|
+
};
|
|
25982
|
+
const outcome = await this.invoke(entry, payload);
|
|
25983
|
+
if (!outcome) continue;
|
|
25984
|
+
if (outcome.modifiedInput && typeof outcome.modifiedInput === "object") {
|
|
25985
|
+
current = outcome.modifiedInput;
|
|
25986
|
+
mutated = true;
|
|
25534
25987
|
}
|
|
25535
|
-
|
|
25536
|
-
|
|
25537
|
-
if (!use) continue;
|
|
25538
|
-
await this.pipelines.toolCall.run({
|
|
25539
|
-
toolUse: use,
|
|
25540
|
-
result,
|
|
25541
|
-
ctx: this.ctx,
|
|
25542
|
-
tool: tool ?? void 0
|
|
25543
|
-
});
|
|
25544
|
-
await this.ctx.session.append({
|
|
25545
|
-
type: "tool_result",
|
|
25546
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25547
|
-
id: result.tool_use_id,
|
|
25548
|
-
content: result.content,
|
|
25549
|
-
isError: !!result.is_error
|
|
25550
|
-
});
|
|
25551
|
-
{
|
|
25552
|
-
const sig = sizeSignals(use.name, result.content);
|
|
25553
|
-
this.events.emit("tool.executed", {
|
|
25554
|
-
id: result.tool_use_id,
|
|
25555
|
-
name: use.name,
|
|
25556
|
-
durationMs,
|
|
25557
|
-
ok: !result.is_error,
|
|
25558
|
-
input: use.input,
|
|
25559
|
-
output: truncateForEvent(result.content),
|
|
25560
|
-
outputBytes: sig.outputBytes,
|
|
25561
|
-
outputTokens: sig.outputTokens,
|
|
25562
|
-
outputLines: sig.outputLines
|
|
25563
|
-
});
|
|
25988
|
+
if (outcome.decision === "block") {
|
|
25989
|
+
return { block: true, reason: outcome.reason ?? `Blocked by ${entry.event} hook` };
|
|
25564
25990
|
}
|
|
25565
25991
|
}
|
|
25566
|
-
|
|
25567
|
-
role: "user",
|
|
25568
|
-
content: resultsForMessage
|
|
25569
|
-
});
|
|
25570
|
-
await this.extensions.runAfterToolExecution(this.ctx, outputs);
|
|
25992
|
+
return mutated ? { input: current } : {};
|
|
25571
25993
|
}
|
|
25572
|
-
|
|
25573
|
-
|
|
25574
|
-
|
|
25575
|
-
|
|
25576
|
-
|
|
25577
|
-
|
|
25578
|
-
|
|
25579
|
-
|
|
25580
|
-
|
|
25581
|
-
|
|
25582
|
-
|
|
25583
|
-
|
|
25584
|
-
|
|
25585
|
-
const
|
|
25586
|
-
const
|
|
25587
|
-
|
|
25588
|
-
const
|
|
25589
|
-
|
|
25590
|
-
|
|
25591
|
-
|
|
25994
|
+
async postToolUse(toolName, toolInput, result, env) {
|
|
25995
|
+
const payload = {
|
|
25996
|
+
event: "PostToolUse",
|
|
25997
|
+
toolName,
|
|
25998
|
+
toolInput,
|
|
25999
|
+
toolResult: result,
|
|
26000
|
+
...this.base(env)
|
|
26001
|
+
};
|
|
26002
|
+
return { additionalContext: await this.collectContext("PostToolUse", toolName, payload) };
|
|
26003
|
+
}
|
|
26004
|
+
async userPromptSubmit(prompt, env) {
|
|
26005
|
+
const entries = this.matching("UserPromptSubmit", void 0);
|
|
26006
|
+
if (entries.length === 0) return {};
|
|
26007
|
+
const payload = { event: "UserPromptSubmit", prompt, ...this.base(env) };
|
|
26008
|
+
const parts = [];
|
|
26009
|
+
for (const entry of entries) {
|
|
26010
|
+
const outcome = await this.invoke(entry, payload);
|
|
26011
|
+
if (!outcome) continue;
|
|
26012
|
+
if (outcome.decision === "block") {
|
|
26013
|
+
return { block: true, reason: outcome.reason ?? "Blocked by UserPromptSubmit hook" };
|
|
26014
|
+
}
|
|
26015
|
+
if (outcome.additionalContext) parts.push(outcome.additionalContext);
|
|
25592
26016
|
}
|
|
26017
|
+
return parts.length ? { additionalContext: parts.join("\n") } : {};
|
|
25593
26018
|
}
|
|
25594
|
-
|
|
25595
|
-
|
|
25596
|
-
|
|
25597
|
-
tool: info.tool,
|
|
25598
|
-
input: info.input,
|
|
25599
|
-
toolUseId: info.toolUseId,
|
|
25600
|
-
suggestedPattern: info.suggestedPattern,
|
|
25601
|
-
resolve: resolve12
|
|
25602
|
-
});
|
|
25603
|
-
});
|
|
26019
|
+
async sessionStart(env) {
|
|
26020
|
+
const payload = { event: "SessionStart", ...this.base(env) };
|
|
26021
|
+
return { additionalContext: await this.collectContext("SessionStart", void 0, payload) };
|
|
25604
26022
|
}
|
|
25605
|
-
async
|
|
25606
|
-
const
|
|
26023
|
+
async stop(env) {
|
|
26024
|
+
const payload = { event: "Stop", ...this.base(env) };
|
|
26025
|
+
await this.collectContext("Stop", void 0, payload);
|
|
26026
|
+
}
|
|
26027
|
+
// ── internals ──────────────────────────────────────────────────────
|
|
26028
|
+
base(env) {
|
|
26029
|
+
const sessionId = this.opts.sessionId?.();
|
|
26030
|
+
return sessionId ? { cwd: env.cwd, sessionId } : { cwd: env.cwd };
|
|
26031
|
+
}
|
|
26032
|
+
matching(event, toolName) {
|
|
26033
|
+
return this.registry.list(event).filter((e) => hookMatcherMatches(e.matcher, toolName));
|
|
26034
|
+
}
|
|
26035
|
+
async invoke(entry, payload) {
|
|
25607
26036
|
try {
|
|
25608
|
-
|
|
25609
|
-
|
|
25610
|
-
|
|
25611
|
-
|
|
25612
|
-
|
|
26037
|
+
if (entry.kind === "inprocess") {
|
|
26038
|
+
const r = await entry.hook(payload);
|
|
26039
|
+
return r ?? null;
|
|
26040
|
+
}
|
|
26041
|
+
if (this.opts.allowShell === false) return null;
|
|
26042
|
+
return await runShellHook(
|
|
26043
|
+
{ command: entry.command, timeoutMs: entry.timeoutMs },
|
|
26044
|
+
payload,
|
|
26045
|
+
this.opts.logger
|
|
25613
26046
|
);
|
|
25614
|
-
return { result, durationMs: Date.now() - start };
|
|
25615
26047
|
} catch (err) {
|
|
25616
|
-
|
|
25617
|
-
|
|
25618
|
-
|
|
25619
|
-
|
|
25620
|
-
tool_use_id: use.id,
|
|
25621
|
-
content: `Tool "${tool.name}" threw: ${msg}`,
|
|
25622
|
-
is_error: true
|
|
25623
|
-
},
|
|
25624
|
-
durationMs: Date.now() - start
|
|
25625
|
-
};
|
|
26048
|
+
this.opts.logger?.warn?.(
|
|
26049
|
+
`${payload.event} hook threw: ${err instanceof Error ? err.message : String(err)}`
|
|
26050
|
+
);
|
|
26051
|
+
return null;
|
|
25626
26052
|
}
|
|
25627
26053
|
}
|
|
25628
|
-
|
|
25629
|
-
|
|
25630
|
-
|
|
25631
|
-
|
|
25632
|
-
|
|
25633
|
-
|
|
25634
|
-
|
|
25635
|
-
|
|
25636
|
-
|
|
25637
|
-
* (FleetBus → TUI) can render a live fill bar per agent.
|
|
25638
|
-
*/
|
|
25639
|
-
emitContextPct() {
|
|
25640
|
-
const maxContext = this.ctx.provider.capabilities.maxContext ?? 2e5;
|
|
25641
|
-
const { total } = estimateRequestTokens(
|
|
25642
|
-
this.ctx.messages,
|
|
25643
|
-
this.ctx.systemPrompt,
|
|
25644
|
-
this.ctx.tools ?? []
|
|
25645
|
-
);
|
|
25646
|
-
this.events.emit("ctx.pct", { load: total / maxContext, tokens: total, maxContext });
|
|
26054
|
+
async collectContext(event, toolName, payload) {
|
|
26055
|
+
const entries = this.matching(event, toolName);
|
|
26056
|
+
if (entries.length === 0) return void 0;
|
|
26057
|
+
const parts = [];
|
|
26058
|
+
for (const entry of entries) {
|
|
26059
|
+
const outcome = await this.invoke(entry, payload);
|
|
26060
|
+
if (outcome?.additionalContext) parts.push(outcome.additionalContext);
|
|
26061
|
+
}
|
|
26062
|
+
return parts.length ? parts.join("\n") : void 0;
|
|
25647
26063
|
}
|
|
25648
26064
|
};
|
|
25649
|
-
function toError(err) {
|
|
25650
|
-
return err instanceof Error ? err : new Error(String(err));
|
|
25651
|
-
}
|
|
25652
|
-
function truncateForEvent(content, max = 400) {
|
|
25653
|
-
if (!content) return "";
|
|
25654
|
-
return content.length <= max ? content : `${content.slice(0, max - 1)}\u2026`;
|
|
25655
|
-
}
|
|
25656
|
-
function sizeSignals(toolName, content) {
|
|
25657
|
-
if (typeof content !== "string" || content.length === 0) {
|
|
25658
|
-
return { outputBytes: 0, outputTokens: 0, outputLines: void 0 };
|
|
25659
|
-
}
|
|
25660
|
-
const outputBytes = Buffer.byteLength(content, "utf8");
|
|
25661
|
-
const outputTokens = Math.max(1, Math.round(outputBytes / 3.5));
|
|
25662
|
-
let outputLines;
|
|
25663
|
-
if (toolName === "read") {
|
|
25664
|
-
const lineRe = /^\s*\d+→/gm;
|
|
25665
|
-
let count = 0;
|
|
25666
|
-
while (lineRe.exec(content) !== null) count++;
|
|
25667
|
-
if (count > 0) outputLines = count;
|
|
25668
|
-
} else if (toolName === "bash" || toolName === "shell" || toolName === "grep" || toolName === "logs") {
|
|
25669
|
-
let nl = 0;
|
|
25670
|
-
for (let i = 0; i < content.length; i++) if (content.charCodeAt(i) === 10) nl++;
|
|
25671
|
-
outputLines = nl + (content.endsWith("\n") ? 0 : 1);
|
|
25672
|
-
}
|
|
25673
|
-
return { outputBytes, outputTokens, outputLines };
|
|
25674
|
-
}
|
|
25675
26065
|
async function bootConfig(options = {}) {
|
|
25676
26066
|
const { flags = {}, appLabel = "wstack", loadSyncConfig = true } = options;
|
|
25677
26067
|
const cwd = typeof flags["cwd"] === "string" ? path6.resolve(flags["cwd"]) : process.cwd();
|
|
@@ -25719,6 +26109,10 @@ function flagsToConfigPatch(flags) {
|
|
|
25719
26109
|
const patch = {};
|
|
25720
26110
|
if (typeof flags["provider"] === "string") patch.provider = flags["provider"];
|
|
25721
26111
|
if (typeof flags["model"] === "string") patch.model = flags["model"];
|
|
26112
|
+
if (typeof flags["fallback-model"] === "string") {
|
|
26113
|
+
const list = flags["fallback-model"].split(",").map((s) => s.trim()).filter(Boolean);
|
|
26114
|
+
if (list.length > 0) patch.fallbackModels = list;
|
|
26115
|
+
}
|
|
25722
26116
|
if (typeof flags["cwd"] === "string") patch.cwd = flags["cwd"];
|
|
25723
26117
|
if (typeof flags["log-level"] === "string") {
|
|
25724
26118
|
patch.log = { level: flags["log-level"] };
|
|
@@ -26050,8 +26444,8 @@ var InputBuilder = class {
|
|
|
26050
26444
|
async registerFile(input) {
|
|
26051
26445
|
const ref = await this.store.add({ ...input, kind: "file" });
|
|
26052
26446
|
this.refs.push(ref);
|
|
26053
|
-
const
|
|
26054
|
-
return `[file:${
|
|
26447
|
+
const path37 = ref.meta.filename ?? ref.meta.label ?? String(ref.seq);
|
|
26448
|
+
return `[file:${path37}]`;
|
|
26055
26449
|
}
|
|
26056
26450
|
/**
|
|
26057
26451
|
* Whether `appendPaste(text)` would collapse the text to a placeholder
|
|
@@ -26451,12 +26845,12 @@ ${mem}`);
|
|
|
26451
26845
|
}
|
|
26452
26846
|
}
|
|
26453
26847
|
async gitStatus(root) {
|
|
26454
|
-
return new Promise((
|
|
26848
|
+
return new Promise((resolve13) => {
|
|
26455
26849
|
let settled = false;
|
|
26456
26850
|
const finish = (s) => {
|
|
26457
26851
|
if (settled) return;
|
|
26458
26852
|
settled = true;
|
|
26459
|
-
|
|
26853
|
+
resolve13(s);
|
|
26460
26854
|
};
|
|
26461
26855
|
let proc;
|
|
26462
26856
|
const timer = setTimeout(() => {
|
|
@@ -26851,9 +27245,13 @@ var DefaultPluginAPI = class {
|
|
|
26851
27245
|
config;
|
|
26852
27246
|
log;
|
|
26853
27247
|
configStore;
|
|
27248
|
+
hookRegistry;
|
|
27249
|
+
ownerName;
|
|
26854
27250
|
pluginCleanupFns = [];
|
|
26855
27251
|
constructor(init) {
|
|
26856
27252
|
const owner = init.ownerName;
|
|
27253
|
+
this.ownerName = owner;
|
|
27254
|
+
this.hookRegistry = init.hookRegistry;
|
|
26857
27255
|
this.container = init.container;
|
|
26858
27256
|
this.events = init.events;
|
|
26859
27257
|
this.config = init.config;
|
|
@@ -26940,6 +27338,13 @@ var DefaultPluginAPI = class {
|
|
|
26940
27338
|
registerSystemPromptContributor(c) {
|
|
26941
27339
|
return this.extensions.registerSystemPromptContributor(c);
|
|
26942
27340
|
}
|
|
27341
|
+
registerHook(event, matcher, hook) {
|
|
27342
|
+
if (!this.hookRegistry) return () => {
|
|
27343
|
+
};
|
|
27344
|
+
const off = this.hookRegistry.registerInProcess(event, matcher, hook, this.ownerName);
|
|
27345
|
+
this.pluginCleanupFns.push(off);
|
|
27346
|
+
return off;
|
|
27347
|
+
}
|
|
26943
27348
|
};
|
|
26944
27349
|
var noopMcp = {
|
|
26945
27350
|
start: async () => void 0,
|
|
@@ -27662,7 +28067,7 @@ var PhaseOrchestrator = class {
|
|
|
27662
28067
|
async mergeOne(phase, handle) {
|
|
27663
28068
|
if (!this.worktrees) return;
|
|
27664
28069
|
try {
|
|
27665
|
-
const
|
|
28070
|
+
const resolve13 = this.ctx.resolveConflict ? async (info) => {
|
|
27666
28071
|
const shouldResolve = await this.shouldAttemptConflictResolution(phase, info);
|
|
27667
28072
|
if (!shouldResolve) return false;
|
|
27668
28073
|
this.emit("phase.conflictResolving", {
|
|
@@ -27672,7 +28077,7 @@ var PhaseOrchestrator = class {
|
|
|
27672
28077
|
});
|
|
27673
28078
|
return this.ctx.resolveConflict(phase, info);
|
|
27674
28079
|
} : void 0;
|
|
27675
|
-
const result = await this.worktrees.merge(handle, { squash: true, resolve:
|
|
28080
|
+
const result = await this.worktrees.merge(handle, { squash: true, resolve: resolve13 });
|
|
27676
28081
|
if (result.resolved) {
|
|
27677
28082
|
this.emit("phase.conflictResolved", { phaseId: phase.id, name: phase.name });
|
|
27678
28083
|
}
|
|
@@ -28022,7 +28427,7 @@ var PhaseOrchestrator = class {
|
|
|
28022
28427
|
}
|
|
28023
28428
|
}
|
|
28024
28429
|
delay(ms) {
|
|
28025
|
-
return new Promise((
|
|
28430
|
+
return new Promise((resolve13) => setTimeout(resolve13, ms));
|
|
28026
28431
|
}
|
|
28027
28432
|
};
|
|
28028
28433
|
|
|
@@ -29059,12 +29464,12 @@ var BrainDecisionQueue = class {
|
|
|
29059
29464
|
options: request.options,
|
|
29060
29465
|
rationale: "Decision escalated to human authority."
|
|
29061
29466
|
};
|
|
29062
|
-
const pending = new Promise((
|
|
29063
|
-
const entry = { request, resolve:
|
|
29467
|
+
const pending = new Promise((resolve13) => {
|
|
29468
|
+
const entry = { request, resolve: resolve13 };
|
|
29064
29469
|
if (this.opts.timeoutMs && this.opts.timeoutMs > 0) {
|
|
29065
29470
|
entry.timer = setTimeout(() => {
|
|
29066
29471
|
this.pending.delete(request.id);
|
|
29067
|
-
|
|
29472
|
+
resolve13({ type: "deny", reason: "Brain human decision timed out." });
|
|
29068
29473
|
}, this.opts.timeoutMs);
|
|
29069
29474
|
}
|
|
29070
29475
|
this.pending.set(request.id, entry);
|
|
@@ -29179,8 +29584,8 @@ var CollaborationBus = class {
|
|
|
29179
29584
|
if (this.isPaused()) return false;
|
|
29180
29585
|
this.pausedAtMs = Date.now();
|
|
29181
29586
|
this.pausedBy = byParticipant;
|
|
29182
|
-
this.pausePromise = new Promise((
|
|
29183
|
-
this.pauseResolve =
|
|
29587
|
+
this.pausePromise = new Promise((resolve13) => {
|
|
29588
|
+
this.pauseResolve = resolve13;
|
|
29184
29589
|
});
|
|
29185
29590
|
return true;
|
|
29186
29591
|
}
|
|
@@ -29216,8 +29621,8 @@ var CollaborationBus = class {
|
|
|
29216
29621
|
return true;
|
|
29217
29622
|
}
|
|
29218
29623
|
let timer;
|
|
29219
|
-
const timeoutPromise = new Promise((
|
|
29220
|
-
timer = setTimeout(() =>
|
|
29624
|
+
const timeoutPromise = new Promise((resolve13) => {
|
|
29625
|
+
timer = setTimeout(() => resolve13("timeout"), timeoutMs);
|
|
29221
29626
|
});
|
|
29222
29627
|
const resumedPromise = this.pausePromise.then(() => "resumed");
|
|
29223
29628
|
const winner = await Promise.race([resumedPromise, timeoutPromise]);
|
|
@@ -29708,7 +30113,7 @@ function createGitPlugin() {
|
|
|
29708
30113
|
}
|
|
29709
30114
|
async function runGit(args, cwd) {
|
|
29710
30115
|
try {
|
|
29711
|
-
return await new Promise((
|
|
30116
|
+
return await new Promise((resolve13, reject) => {
|
|
29712
30117
|
const child = spawn("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
29713
30118
|
let stdout = "";
|
|
29714
30119
|
let stderr = "";
|
|
@@ -29729,7 +30134,7 @@ async function runGit(args, cwd) {
|
|
|
29729
30134
|
})
|
|
29730
30135
|
);
|
|
29731
30136
|
});
|
|
29732
|
-
child.on("close", (code) =>
|
|
30137
|
+
child.on("close", (code) => resolve13({ stdout, stderr, code: code ?? 0 }));
|
|
29733
30138
|
});
|
|
29734
30139
|
} catch (err) {
|
|
29735
30140
|
if (err instanceof WrongStackError) throw err;
|
|
@@ -30405,6 +30810,6 @@ ${formatPlan(updated)}`
|
|
|
30405
30810
|
};
|
|
30406
30811
|
}
|
|
30407
30812
|
|
|
30408
|
-
export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BrainDecisionQueue, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HumanEscalatingBrainArbiter, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, bootConfig, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, extractRunEnv, filesystemServer, findCriticalPath, flagsToConfigPatch, formatContextWindowModeList, formatGoal, formatHumanPrompt, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getCalibrationState, getContextWindowMode, getPlanTemplate, getTemplate, getTermSize, githubServer, goalFilePath, googleMapsServer, hashRequest, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isInteractive, isPluginError, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isValidMatrixKey, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, matrixKeyKind, mergeCustomModelDefs, mergeModelsPayload, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, onResize, parseContinueDirective, parseSkillRef, pendingBtwCount, phaseForRole, projectHash, recordActualUsage, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resetCalibration, resolveAuditLevel, resolveContextWindowPolicy, resolveModelMatrix, resolveSessionLoggingConfig, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, setRawMode, slackServer, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, writeErr, writeOut, zaiVisionServer };
|
|
30813
|
+
export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BrainDecisionQueue, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HookRegistry, HookRunner, HumanEscalatingBrainArbiter, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, bootConfig, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, extractRunEnv, filesystemServer, findCriticalPath, flagsToConfigPatch, formatContextWindowModeList, formatGoal, formatHumanPrompt, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getCalibrationState, getContextWindowMode, getPlanTemplate, getTemplate, getTermSize, githubServer, goalFilePath, googleMapsServer, hashRequest, hookMatcherMatches, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isInteractive, isPluginError, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isValidMatrixKey, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, matrixKeyKind, mergeCustomModelDefs, mergeModelsPayload, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, onResize, parseContinueDirective, parseSkillRef, pendingBtwCount, phaseForRole, projectHash, recordActualUsage, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resetCalibration, resolveAuditLevel, resolveContextWindowPolicy, resolveModelMatrix, resolveSessionLoggingConfig, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, runShellHook, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, setRawMode, slackServer, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, writeErr, writeOut, zaiVisionServer };
|
|
30409
30814
|
//# sourceMappingURL=index.js.map
|
|
30410
30815
|
//# sourceMappingURL=index.js.map
|