@wrongstack/core 0.283.0 → 0.284.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{compactor-BxddyCFu.d.ts → compactor-DQLL4HTo.d.ts} +1 -1
- package/dist/{config-DkCbA3Bw.d.ts → config-MRqn1V-u.d.ts} +130 -22
- package/dist/coordination/index.d.ts +43 -20
- package/dist/coordination/index.js +1744 -912
- package/dist/coordination/index.js.map +1 -1
- package/dist/{default-config-Buho8yge.d.ts → default-config-B79_gJYv.d.ts} +7 -0
- package/dist/defaults/index.d.ts +25 -29
- package/dist/defaults/index.js +2546 -7396
- package/dist/defaults/index.js.map +1 -1
- package/dist/{director-state-B_GPa78Q.d.ts → director-state-CMS_bMs4.d.ts} +2 -0
- package/dist/{events-KmxSmvho.d.ts → events-Bgnh43r9.d.ts} +27 -10
- package/dist/execution/index.d.ts +15 -16
- package/dist/execution/index.js +534 -140
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{global-mailbox-rWVt8YlO.d.ts → global-mailbox-sZwyI6CS.d.ts} +13 -2
- package/dist/{goal-store-8owBXJT2.d.ts → goal-store-Datpp-ar.d.ts} +1 -1
- package/dist/hq/index.d.ts +35 -9
- package/dist/hq/index.js +80 -7
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-BhCteHAF.d.ts → index--Gm41aBJ.d.ts} +26 -11
- package/dist/{index-BEFWNZYs.d.ts → index-CbyuOE5y.d.ts} +5 -1
- package/dist/index.d.ts +52 -1017
- package/dist/index.js +21053 -27778
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +9 -7
- package/dist/infrastructure/index.js +7 -2
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +11 -11
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-BUx9A_AQ.d.ts → mcp-servers-DEV4s6Ks.d.ts} +3 -3
- package/dist/models/index.d.ts +4 -4
- package/dist/models/index.js +18 -3
- package/dist/models/index.js.map +1 -1
- package/dist/{agent-subagent-runner-BsuWhB28.d.ts → multi-agent-coordinator-4RCRZKjN.d.ts} +417 -9
- package/dist/{null-fleet-bus-D4e9R7Qc.d.ts → null-fleet-bus-CFoNVQEK.d.ts} +53 -12
- package/dist/observability/index.d.ts +3 -3
- package/dist/{parallel-eternal-engine-iY2uxocj.d.ts → parallel-eternal-engine-HUrtePLd.d.ts} +4 -5
- package/dist/{permission-B6YAtNFz.d.ts → permission-ByDKXEcG.d.ts} +1 -1
- package/dist/{pipeline-ixSFe5jg.d.ts → pipeline-DGDyIohT.d.ts} +28 -7
- package/dist/{provider-model-resolve-DIxKL_T-.d.ts → provider-model-resolve-o2hHLs79.d.ts} +3 -3
- package/dist/{provider-runner-oQhDaZmH.d.ts → provider-runner-ChL-kVg6.d.ts} +3 -3
- package/dist/{retry-policy-V67lBOJz.d.ts → retry-policy-CQ7KwXJa.d.ts} +2 -2
- package/dist/{secret-vault-D7jeyXUQ.d.ts → secret-vault-DxohkUBc.d.ts} +3 -2
- package/dist/security/index.d.ts +4 -4
- package/dist/security/index.js +232 -2
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-Bx2HgUkU.d.ts → selector-D8O6B_Rm.d.ts} +1 -1
- package/dist/{session-event-bridge-Bkp7ORfc.d.ts → session-event-bridge-D_z_mBwk.d.ts} +3 -3
- package/dist/{session-reader-B-Fi9L6I.d.ts → session-reader-7Esxrkpw.d.ts} +1 -1
- package/dist/storage/index.d.ts +77 -39
- package/dist/storage/index.js +1223 -288
- package/dist/storage/index.js.map +1 -1
- package/dist/tasking/index.d.ts +124 -0
- package/dist/tasking/index.js +492 -0
- package/dist/tasking/index.js.map +1 -0
- package/dist/{todos-checkpoint-BwCrj4Cb.d.ts → todos-checkpoint-FY7PjmMx.d.ts} +13 -4
- package/dist/{tool-LVSLiE1s.d.ts → tool-BNlnIJvo.d.ts} +216 -17
- package/dist/{tool-executor-kElSEgO0.d.ts → tool-executor-CckSCM5E.d.ts} +12 -15
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +94 -19
- package/dist/types/index.js +76 -12
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +44 -10
- package/dist/utils/index.js +106 -17
- package/dist/utils/index.js.map +1 -1
- package/dist/{worktree-manager-BjyAW30D.d.ts → worktree-manager-DzwxKE35.d.ts} +1 -1
- package/instructions/coordination/subagent-baseline.md +5 -0
- package/instructions/llm/autonomy-brain.md +3 -2
- package/instructions/system.md +4 -0
- package/package.json +10 -3
- package/skills/mailbox-bridge/SKILL.md +33 -0
- package/dist/multi-agent-coordinator-CrjeTB9i.d.ts +0 -357
- package/dist/sdd/index.d.ts +0 -1993
- package/dist/sdd/index.js +0 -9500
- package/dist/sdd/index.js.map +0 -1
- package/dist/spec-TBi3Jr6T.d.ts +0 -78
package/dist/execution/index.js
CHANGED
|
@@ -205,7 +205,7 @@ function walk(value, schema, path12, errors, depth) {
|
|
|
205
205
|
if (!checkType(value, schema.type)) {
|
|
206
206
|
errors.push({
|
|
207
207
|
path: path12 || "<root>",
|
|
208
|
-
message: `expected ${schema.type}, got ${describeType(value)}`
|
|
208
|
+
message: `expected ${schema.type}, got ${describeType(value)} (${previewValue(value)})`
|
|
209
209
|
});
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
@@ -214,7 +214,11 @@ function walk(value, schema, path12, errors, depth) {
|
|
|
214
214
|
const obj = value;
|
|
215
215
|
for (const req of schema.required ?? []) {
|
|
216
216
|
if (!(req in obj)) {
|
|
217
|
-
|
|
217
|
+
const expected = schema.properties?.[req]?.type;
|
|
218
|
+
errors.push({
|
|
219
|
+
path: joinPath(path12, req),
|
|
220
|
+
message: `required property missing${typeof expected === "string" ? ` (expected ${expected})` : ""}`
|
|
221
|
+
});
|
|
218
222
|
}
|
|
219
223
|
}
|
|
220
224
|
if (schema.properties) {
|
|
@@ -231,6 +235,69 @@ function walk(value, schema, path12, errors, depth) {
|
|
|
231
235
|
}
|
|
232
236
|
}
|
|
233
237
|
}
|
|
238
|
+
function coerceAgainstSchema(value, schema) {
|
|
239
|
+
return coerceWalk(value, schema, 0);
|
|
240
|
+
}
|
|
241
|
+
function coerceWalk(value, schema, depth) {
|
|
242
|
+
if (depth > MAX_SCHEMA_DEPTH) return { value, changed: false };
|
|
243
|
+
const type = typeof schema.type === "string" ? schema.type : void 0;
|
|
244
|
+
if (type && !checkType(value, type)) {
|
|
245
|
+
if (type === "string" && (typeof value === "number" || typeof value === "boolean")) {
|
|
246
|
+
return { value: String(value), changed: true };
|
|
247
|
+
}
|
|
248
|
+
if ((type === "number" || type === "integer") && typeof value === "string") {
|
|
249
|
+
const trimmed = value.trim();
|
|
250
|
+
if (trimmed !== "" && /^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(trimmed)) {
|
|
251
|
+
const num = Number(trimmed);
|
|
252
|
+
if (!Number.isNaN(num) && (type === "number" || Number.isInteger(num))) {
|
|
253
|
+
return { value: num, changed: true };
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return { value, changed: false };
|
|
257
|
+
}
|
|
258
|
+
if (type === "boolean" && typeof value === "string") {
|
|
259
|
+
const lowered = value.trim().toLowerCase();
|
|
260
|
+
if (lowered === "true") return { value: true, changed: true };
|
|
261
|
+
if (lowered === "false") return { value: false, changed: true };
|
|
262
|
+
return { value, changed: false };
|
|
263
|
+
}
|
|
264
|
+
if ((type === "object" || type === "array") && typeof value === "string") {
|
|
265
|
+
try {
|
|
266
|
+
const parsed = JSON.parse(value);
|
|
267
|
+
if (checkType(parsed, type)) {
|
|
268
|
+
return { value: coerceWalk(parsed, schema, depth + 1).value, changed: true };
|
|
269
|
+
}
|
|
270
|
+
} catch {
|
|
271
|
+
}
|
|
272
|
+
return { value, changed: false };
|
|
273
|
+
}
|
|
274
|
+
return { value, changed: false };
|
|
275
|
+
}
|
|
276
|
+
if (type === "object" && isPlainObject(value) && schema.properties) {
|
|
277
|
+
const obj = value;
|
|
278
|
+
let changed = false;
|
|
279
|
+
const out = { ...obj };
|
|
280
|
+
for (const [key, subSchema] of Object.entries(schema.properties)) {
|
|
281
|
+
if (!(key in obj)) continue;
|
|
282
|
+
const r = coerceWalk(obj[key], subSchema, depth + 1);
|
|
283
|
+
if (r.changed) {
|
|
284
|
+
out[key] = r.value;
|
|
285
|
+
changed = true;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return changed ? { value: out, changed } : { value, changed: false };
|
|
289
|
+
}
|
|
290
|
+
if (type === "array" && Array.isArray(value) && schema.items) {
|
|
291
|
+
let changed = false;
|
|
292
|
+
const out = value.map((item) => {
|
|
293
|
+
const r = coerceWalk(item, schema.items, depth + 1);
|
|
294
|
+
if (r.changed) changed = true;
|
|
295
|
+
return r.value;
|
|
296
|
+
});
|
|
297
|
+
return changed ? { value: out, changed } : { value, changed: false };
|
|
298
|
+
}
|
|
299
|
+
return { value, changed: false };
|
|
300
|
+
}
|
|
234
301
|
function checkType(value, type) {
|
|
235
302
|
switch (type) {
|
|
236
303
|
case "string":
|
|
@@ -259,6 +326,15 @@ function describeType(v) {
|
|
|
259
326
|
if (Array.isArray(v)) return "array";
|
|
260
327
|
return typeof v;
|
|
261
328
|
}
|
|
329
|
+
function previewValue(v) {
|
|
330
|
+
try {
|
|
331
|
+
const s = JSON.stringify(v);
|
|
332
|
+
if (s === void 0) return String(v);
|
|
333
|
+
return s.length > 80 ? `${s.slice(0, 80)}\u2026` : s;
|
|
334
|
+
} catch {
|
|
335
|
+
return String(v);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
262
338
|
function joinPath(parent, key) {
|
|
263
339
|
if (!parent) return key;
|
|
264
340
|
return `${parent}.${key}`;
|
|
@@ -413,6 +489,21 @@ function compileUserRegex(pattern, flags) {
|
|
|
413
489
|
}
|
|
414
490
|
}
|
|
415
491
|
|
|
492
|
+
// src/utils/safe-json.ts
|
|
493
|
+
function safeParse(input, maxBytes = 5e6) {
|
|
494
|
+
if (input.length > maxBytes) {
|
|
495
|
+
return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };
|
|
496
|
+
}
|
|
497
|
+
try {
|
|
498
|
+
return { ok: true, value: JSON.parse(input) };
|
|
499
|
+
} catch (err) {
|
|
500
|
+
return {
|
|
501
|
+
ok: false,
|
|
502
|
+
error: toErrorMessage(err)
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
416
507
|
// src/utils/slug.ts
|
|
417
508
|
function slugify(name, fallback = "prompt", maxLen = 64) {
|
|
418
509
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLen).replace(/-+$/g, "") || fallback;
|
|
@@ -908,18 +999,23 @@ ${renderStringList(files)}` : void 0
|
|
|
908
999
|
}
|
|
909
1000
|
if (typeof obj["diff"] === "string") {
|
|
910
1001
|
const diff = obj["diff"];
|
|
1002
|
+
const matchedBy = typeof obj["matched_by"] === "string" && obj["matched_by"] !== "exact" ? obj["matched_by"] : void 0;
|
|
1003
|
+
const syntaxErrors = Array.isArray(obj["syntax_errors"]) ? obj["syntax_errors"].filter((e) => typeof e === "string") : [];
|
|
911
1004
|
return joinSections([
|
|
912
1005
|
renderHeader(toolName, {
|
|
913
1006
|
path: obj["path"],
|
|
914
1007
|
replacements: obj["replacements"],
|
|
915
1008
|
bytes_written: obj["bytes_written"],
|
|
916
1009
|
created: obj["created"],
|
|
1010
|
+
matched_by: matchedBy,
|
|
917
1011
|
note: obj["note"],
|
|
918
1012
|
files: Array.isArray(obj["files"]) ? obj["files"].length : void 0,
|
|
919
1013
|
truncated: obj["truncated"],
|
|
920
1014
|
mode: obj["mode"]
|
|
921
1015
|
}),
|
|
922
|
-
compactDiff(diff)
|
|
1016
|
+
compactDiff(diff),
|
|
1017
|
+
syntaxErrors.length > 0 ? `syntax_errors:
|
|
1018
|
+
${renderStringList(syntaxErrors)}` : void 0
|
|
923
1019
|
]);
|
|
924
1020
|
}
|
|
925
1021
|
if (toolName === "test" && typeof obj["output"] === "string") {
|
|
@@ -2302,16 +2398,14 @@ ${request.context}` : "",
|
|
|
2302
2398
|
);
|
|
2303
2399
|
const text = extractText(response).trim();
|
|
2304
2400
|
if (request.options?.length) {
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
type: "answer",
|
|
2309
|
-
optionId: opt.id,
|
|
2310
|
-
text: opt.label,
|
|
2311
|
-
rationale: text
|
|
2312
|
-
};
|
|
2313
|
-
}
|
|
2401
|
+
const parsed = parseOptionDecision(text, request.options);
|
|
2402
|
+
if (parsed) {
|
|
2403
|
+
return parsed;
|
|
2314
2404
|
}
|
|
2405
|
+
return {
|
|
2406
|
+
type: "deny",
|
|
2407
|
+
reason: "Autonomy Brain returned no exact valid option id."
|
|
2408
|
+
};
|
|
2315
2409
|
}
|
|
2316
2410
|
return {
|
|
2317
2411
|
type: "answer",
|
|
@@ -2328,6 +2422,34 @@ ${request.context}` : "",
|
|
|
2328
2422
|
return { type: "deny", reason: "Autonomy Brain LLM unavailable for decision." };
|
|
2329
2423
|
}
|
|
2330
2424
|
}
|
|
2425
|
+
function parseOptionDecision(rawText, options) {
|
|
2426
|
+
const text = rawText.trim();
|
|
2427
|
+
const byId = new Map(options.map((option2) => [option2.id, option2]));
|
|
2428
|
+
const wholeFence = /^```(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n?```$/i.exec(text);
|
|
2429
|
+
const jsonCandidate = wholeFence ? (wholeFence[1] ?? "").trim() : text;
|
|
2430
|
+
const parsed = safeParse(jsonCandidate, 16384);
|
|
2431
|
+
if (parsed.ok && parsed.value && typeof parsed.value.optionId === "string") {
|
|
2432
|
+
const option2 = byId.get(parsed.value.optionId);
|
|
2433
|
+
if (!option2) return null;
|
|
2434
|
+
return {
|
|
2435
|
+
type: "answer",
|
|
2436
|
+
optionId: option2.id,
|
|
2437
|
+
text: option2.label,
|
|
2438
|
+
rationale: typeof parsed.value.rationale === "string" && parsed.value.rationale.trim() ? parsed.value.rationale.trim() : void 0
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
const legacy = /^\s*\[([^\]\r\n]+)\](?:\s*(?:—|-|:)\s*)?([\s\S]*)$/.exec(text);
|
|
2442
|
+
if (!legacy) return null;
|
|
2443
|
+
const option = byId.get((legacy[1] ?? "").trim());
|
|
2444
|
+
if (!option) return null;
|
|
2445
|
+
const rationale = (legacy[2] ?? "").trim();
|
|
2446
|
+
return {
|
|
2447
|
+
type: "answer",
|
|
2448
|
+
optionId: option.id,
|
|
2449
|
+
text: option.label,
|
|
2450
|
+
rationale: rationale || void 0
|
|
2451
|
+
};
|
|
2452
|
+
}
|
|
2331
2453
|
function extractText(result) {
|
|
2332
2454
|
if (!result || typeof result !== "object") return "";
|
|
2333
2455
|
const r = result;
|
|
@@ -3821,15 +3943,55 @@ function installDesignStudioMiddleware(deps) {
|
|
|
3821
3943
|
}
|
|
3822
3944
|
|
|
3823
3945
|
// src/types/provider.ts
|
|
3946
|
+
var CONTEXT_OVERFLOW_RE = /context.length|context.window|max.*tokens?.*exceeded|prompt is too long|too long|exceeds the context|\btokens\b.*exceed|context_length_exceeded/i;
|
|
3947
|
+
var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
|
|
3948
|
+
function classifyProviderError(status, body, message) {
|
|
3949
|
+
const type = body?.type;
|
|
3950
|
+
if (status === 0) return "network";
|
|
3951
|
+
if (status === 408) return "timeout";
|
|
3952
|
+
if (status === 599) return "stream_hang";
|
|
3953
|
+
if (type === "rate_limit_error" || status === 429) return "rate_limit";
|
|
3954
|
+
if (type === "overloaded_error" || status === 529) return "overloaded";
|
|
3955
|
+
if (status >= 500) return "server";
|
|
3956
|
+
if (type === "authentication_error" || type === "permission_error" || status === 401 || status === 403) {
|
|
3957
|
+
return "auth";
|
|
3958
|
+
}
|
|
3959
|
+
const text = [message, body?.message, type, body?.raw].filter(Boolean).join("\n");
|
|
3960
|
+
if (type === "content_filter" || CONTENT_FILTER_RE.test(text)) return "content_filter";
|
|
3961
|
+
if (status === 413 || status >= 400 && CONTEXT_OVERFLOW_RE.test(text)) {
|
|
3962
|
+
return "context_overflow";
|
|
3963
|
+
}
|
|
3964
|
+
if (status >= 400) return "invalid_request";
|
|
3965
|
+
return "unknown";
|
|
3966
|
+
}
|
|
3967
|
+
function isRetryableKind(kind) {
|
|
3968
|
+
return RETRYABLE_BY_KIND[kind];
|
|
3969
|
+
}
|
|
3970
|
+
var RETRYABLE_BY_KIND = {
|
|
3971
|
+
rate_limit: true,
|
|
3972
|
+
overloaded: true,
|
|
3973
|
+
server: true,
|
|
3974
|
+
timeout: true,
|
|
3975
|
+
network: true,
|
|
3976
|
+
stream_hang: true,
|
|
3977
|
+
auth: false,
|
|
3978
|
+
context_overflow: false,
|
|
3979
|
+
content_filter: false,
|
|
3980
|
+
invalid_request: false,
|
|
3981
|
+
unknown: false
|
|
3982
|
+
};
|
|
3824
3983
|
var ProviderError = class extends WrongStackError {
|
|
3825
3984
|
status;
|
|
3826
3985
|
retryable;
|
|
3827
3986
|
providerId;
|
|
3987
|
+
/** Canonical failure classification — see {@link ProviderErrorKind}. */
|
|
3988
|
+
kind;
|
|
3828
3989
|
body;
|
|
3829
3990
|
constructor(message, status, retryable, providerId, opts = {}) {
|
|
3991
|
+
const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
|
|
3830
3992
|
super({
|
|
3831
3993
|
message,
|
|
3832
|
-
code:
|
|
3994
|
+
code: kindToCode(kind),
|
|
3833
3995
|
subsystem: "provider",
|
|
3834
3996
|
severity: status >= 500 ? "error" : "warning",
|
|
3835
3997
|
recoverable: retryable,
|
|
@@ -3840,6 +4002,7 @@ var ProviderError = class extends WrongStackError {
|
|
|
3840
4002
|
this.status = status;
|
|
3841
4003
|
this.retryable = retryable;
|
|
3842
4004
|
this.providerId = providerId;
|
|
4005
|
+
this.kind = kind;
|
|
3843
4006
|
this.body = opts.body;
|
|
3844
4007
|
}
|
|
3845
4008
|
/**
|
|
@@ -3867,33 +4030,40 @@ var ProviderError = class extends WrongStackError {
|
|
|
3867
4030
|
};
|
|
3868
4031
|
function describeStatus(status, type) {
|
|
3869
4032
|
if (status === 0) return "network error";
|
|
4033
|
+
if (status === 599) return `stream hang (${status})`;
|
|
3870
4034
|
if (type === "overloaded_error" || status === 529) return `overloaded (${status})`;
|
|
3871
4035
|
if (type === "rate_limit_error" || status === 429) return `rate limited (${status})`;
|
|
3872
4036
|
if (type === "authentication_error" || status === 401) return `auth failed (${status})`;
|
|
3873
4037
|
if (type === "permission_error" || status === 403) return `forbidden (${status})`;
|
|
3874
4038
|
if (type === "not_found_error" || status === 404) return `not found (${status})`;
|
|
4039
|
+
if (type === "content_filter") return `content filtered (${status})`;
|
|
3875
4040
|
if (type === "invalid_request_error" || status === 400) return `invalid request (${status})`;
|
|
3876
4041
|
if (status === 408) return `timeout (${status})`;
|
|
3877
4042
|
if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;
|
|
3878
4043
|
if (type) return `${type} (${status})`;
|
|
3879
4044
|
return `HTTP ${status}`;
|
|
3880
4045
|
}
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
4046
|
+
var KIND_TO_CODE = {
|
|
4047
|
+
network: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
4048
|
+
timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
4049
|
+
rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
4050
|
+
auth: ERROR_CODES.PROVIDER_AUTH_FAILED,
|
|
4051
|
+
overloaded: ERROR_CODES.PROVIDER_OVERLOADED,
|
|
4052
|
+
context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,
|
|
4053
|
+
server: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
4054
|
+
stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
4055
|
+
content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
4056
|
+
invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
4057
|
+
unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST
|
|
4058
|
+
};
|
|
4059
|
+
function kindToCode(kind) {
|
|
4060
|
+
return KIND_TO_CODE[kind];
|
|
3890
4061
|
}
|
|
3891
4062
|
|
|
3892
4063
|
// src/execution/regex-patterns.ts
|
|
3893
4064
|
var NETWORK_ERR_RE = /ECONN|ETIMEDOUT|ETIME|ENOTFOUND|EAI_AGAIN|fetch failed/i;
|
|
3894
4065
|
|
|
3895
4066
|
// src/execution/error-handler.ts
|
|
3896
|
-
var CONTEXT_OVERFLOW_RE = /context|too long|tokens|exceeds the context window|context window/i;
|
|
3897
4067
|
function buildRecoveryStrategies(opts) {
|
|
3898
4068
|
return [
|
|
3899
4069
|
{
|
|
@@ -3901,7 +4071,7 @@ function buildRecoveryStrategies(opts) {
|
|
|
3901
4071
|
compactor: opts?.compactor,
|
|
3902
4072
|
async attempt(err, ctx) {
|
|
3903
4073
|
if (!(err instanceof ProviderError)) return null;
|
|
3904
|
-
if (err.
|
|
4074
|
+
if (err.kind !== "context_overflow") return null;
|
|
3905
4075
|
if (this.compactor) {
|
|
3906
4076
|
try {
|
|
3907
4077
|
const report = await this.compactor.compact(ctx, { aggressive: true });
|
|
@@ -3917,7 +4087,7 @@ function buildRecoveryStrategies(opts) {
|
|
|
3917
4087
|
{
|
|
3918
4088
|
label: "rate_limit_backoff",
|
|
3919
4089
|
async attempt(err) {
|
|
3920
|
-
if (!(err instanceof ProviderError) || err.
|
|
4090
|
+
if (!(err instanceof ProviderError) || err.kind !== "rate_limit") return null;
|
|
3921
4091
|
const delayMs = err.body?.retryAfterMs ?? 5e3;
|
|
3922
4092
|
const delay = Math.min(6e4, Math.max(1e3, delayMs));
|
|
3923
4093
|
await new Promise((r) => setTimeout(r, delay));
|
|
@@ -3928,7 +4098,9 @@ function buildRecoveryStrategies(opts) {
|
|
|
3928
4098
|
label: "downgrade_model",
|
|
3929
4099
|
async attempt(err, ctx) {
|
|
3930
4100
|
if (!(err instanceof ProviderError)) return null;
|
|
3931
|
-
if (err.
|
|
4101
|
+
if (err.kind !== "overloaded" && err.kind !== "server" && err.kind !== "stream_hang") {
|
|
4102
|
+
return null;
|
|
4103
|
+
}
|
|
3932
4104
|
const registry = opts?.modelsRegistry;
|
|
3933
4105
|
if (!registry) return null;
|
|
3934
4106
|
try {
|
|
@@ -3962,18 +4134,59 @@ function buildRecoveryStrategies(opts) {
|
|
|
3962
4134
|
return null;
|
|
3963
4135
|
}
|
|
3964
4136
|
}
|
|
4137
|
+
},
|
|
4138
|
+
{
|
|
4139
|
+
label: "content_filter_reroute",
|
|
4140
|
+
async attempt(err, ctx) {
|
|
4141
|
+
if (!(err instanceof ProviderError) || err.kind !== "content_filter") return null;
|
|
4142
|
+
const registry = opts?.modelsRegistry;
|
|
4143
|
+
if (!registry) return null;
|
|
4144
|
+
try {
|
|
4145
|
+
const providerId = ctx.provider?.id;
|
|
4146
|
+
if (!providerId) return null;
|
|
4147
|
+
const provider = await registry.getProvider(providerId);
|
|
4148
|
+
if (!provider) return null;
|
|
4149
|
+
const currentModel = await registry.getModel(providerId, ctx.model);
|
|
4150
|
+
if (!currentModel) return null;
|
|
4151
|
+
const visibleModels = opts?.getConfig?.().providers?.[providerId]?.models;
|
|
4152
|
+
const candidates = provider.models.filter((m) => {
|
|
4153
|
+
if (m.id === ctx.model) return false;
|
|
4154
|
+
if (visibleModels !== void 0 && !visibleModels.includes(m.id)) return false;
|
|
4155
|
+
if (currentModel.capabilities.tools && !m.tool_call) return false;
|
|
4156
|
+
if (currentModel.capabilities.vision && !m.modalities?.input?.includes("image"))
|
|
4157
|
+
return false;
|
|
4158
|
+
return true;
|
|
4159
|
+
});
|
|
4160
|
+
if (candidates.length === 0) return null;
|
|
4161
|
+
const currentCost = currentModel.cost?.input;
|
|
4162
|
+
const distance = (m) => currentCost === void 0 || m.cost?.input === void 0 ? Number.POSITIVE_INFINITY : Math.abs(m.cost.input - currentCost);
|
|
4163
|
+
const reroute = candidates.reduce((prev, curr) => {
|
|
4164
|
+
const delta = distance(curr) - distance(prev);
|
|
4165
|
+
if (delta < 0) return curr;
|
|
4166
|
+
if (delta === 0 && curr.id < prev.id) return curr;
|
|
4167
|
+
return prev;
|
|
4168
|
+
});
|
|
4169
|
+
return { action: "retry", reason: "content_filter_reroute", model: reroute.id };
|
|
4170
|
+
} catch {
|
|
4171
|
+
return null;
|
|
4172
|
+
}
|
|
4173
|
+
}
|
|
3965
4174
|
}
|
|
3966
4175
|
];
|
|
3967
4176
|
}
|
|
3968
4177
|
var DEFAULT_RECOVERY_STRATEGIES = buildRecoveryStrategies();
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
4178
|
+
var HANDLER_KIND_BY_PROVIDER_KIND = {
|
|
4179
|
+
rate_limit: "rate_limit",
|
|
4180
|
+
overloaded: "overloaded",
|
|
4181
|
+
server: "server",
|
|
4182
|
+
stream_hang: "server",
|
|
4183
|
+
timeout: "network",
|
|
4184
|
+
network: "network",
|
|
4185
|
+
context_overflow: "context_overflow",
|
|
4186
|
+
content_filter: "content_filter",
|
|
4187
|
+
auth: "client",
|
|
4188
|
+
invalid_request: "client"
|
|
4189
|
+
};
|
|
3977
4190
|
var DefaultErrorHandler = class {
|
|
3978
4191
|
strategies;
|
|
3979
4192
|
constructor(strategies = DEFAULT_RECOVERY_STRATEGIES) {
|
|
@@ -3987,13 +4200,11 @@ var DefaultErrorHandler = class {
|
|
|
3987
4200
|
return { kind: "abort", retryable: false };
|
|
3988
4201
|
}
|
|
3989
4202
|
if (err instanceof ProviderError) {
|
|
3990
|
-
if (err.
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
}
|
|
3996
|
-
if (err.status >= 400) return { kind: "client", retryable: false };
|
|
4203
|
+
if (err.kind === "unknown") return { kind: "unknown", retryable: err.retryable };
|
|
4204
|
+
return {
|
|
4205
|
+
kind: HANDLER_KIND_BY_PROVIDER_KIND[err.kind],
|
|
4206
|
+
retryable: isRetryableKind(err.kind)
|
|
4207
|
+
};
|
|
3997
4208
|
}
|
|
3998
4209
|
if (err instanceof Error && NETWORK_ERR_RE.test(err.message)) {
|
|
3999
4210
|
return { kind: "network", retryable: true };
|
|
@@ -4305,7 +4516,7 @@ var EternalAutonomyEngine = class {
|
|
|
4305
4516
|
if (maxCtx && maxCtx > 0) {
|
|
4306
4517
|
const used = ctx.tokenCounter?.currentRequestTokens?.();
|
|
4307
4518
|
if (used) {
|
|
4308
|
-
const total = used.input + used.cacheRead;
|
|
4519
|
+
const total = used.input + used.cacheRead + used.cacheWrite;
|
|
4309
4520
|
if (total / maxCtx >= threshold) {
|
|
4310
4521
|
shouldRun = true;
|
|
4311
4522
|
aggressive = true;
|
|
@@ -5405,6 +5616,104 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
5405
5616
|
}
|
|
5406
5617
|
};
|
|
5407
5618
|
|
|
5619
|
+
// src/security/capabilities.ts
|
|
5620
|
+
var ToolCapabilities = {
|
|
5621
|
+
/** Can execute arbitrary commands in the user's shell (the `bash` tool). */
|
|
5622
|
+
SHELL_ARBITRARY: "shell.arbitrary",
|
|
5623
|
+
/** Can execute a restricted set of commands (the `exec` tool). */
|
|
5624
|
+
SHELL_RESTRICTED: "shell.restricted",
|
|
5625
|
+
/** Can run a restricted project formatter/linter-style command. */
|
|
5626
|
+
SHELL_EXEC: "shell.exec",
|
|
5627
|
+
/** Can write / modify / delete files inside the project. */
|
|
5628
|
+
FS_WRITE: "fs.write",
|
|
5629
|
+
/** Can write files outside the current project root (very high risk). */
|
|
5630
|
+
FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project",
|
|
5631
|
+
/** Can invoke arbitrary registered tools through a meta-tool. */
|
|
5632
|
+
TOOL_MUTATE_ANY: "tool.mutate.any",
|
|
5633
|
+
/** Can write persistent memory. */
|
|
5634
|
+
MEMORY_WRITE: "memory.write",
|
|
5635
|
+
/** Can delete persistent memory. */
|
|
5636
|
+
MEMORY_DELETE: "memory.delete",
|
|
5637
|
+
/** Proxies tools from external MCP servers (unknown capability). */
|
|
5638
|
+
MCP_PROXY: "mcp.proxy",
|
|
5639
|
+
/** Can spawn or manage subagents / multi-agent tasks. */
|
|
5640
|
+
SUBAGENT_SPAWN: "subagent.spawn",
|
|
5641
|
+
/** Can mutate global or session configuration / trust state. */
|
|
5642
|
+
CONFIG_MUTATE: "config.mutate",
|
|
5643
|
+
/** Can install packages or run package managers with side effects. */
|
|
5644
|
+
PACKAGE_INSTALL: "package.install"
|
|
5645
|
+
};
|
|
5646
|
+
var DANGEROUS_FOR_SUBAGENTS = [
|
|
5647
|
+
ToolCapabilities.SHELL_ARBITRARY,
|
|
5648
|
+
ToolCapabilities.SHELL_RESTRICTED,
|
|
5649
|
+
ToolCapabilities.SHELL_EXEC,
|
|
5650
|
+
ToolCapabilities.FS_WRITE,
|
|
5651
|
+
ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,
|
|
5652
|
+
ToolCapabilities.TOOL_MUTATE_ANY,
|
|
5653
|
+
ToolCapabilities.MEMORY_WRITE,
|
|
5654
|
+
ToolCapabilities.MEMORY_DELETE,
|
|
5655
|
+
ToolCapabilities.MCP_PROXY,
|
|
5656
|
+
ToolCapabilities.SUBAGENT_SPAWN,
|
|
5657
|
+
ToolCapabilities.CONFIG_MUTATE,
|
|
5658
|
+
ToolCapabilities.PACKAGE_INSTALL
|
|
5659
|
+
];
|
|
5660
|
+
function hasDangerousCapabilityForSubagents(toolOrCaps) {
|
|
5661
|
+
if (!toolOrCaps) return false;
|
|
5662
|
+
const input = toolOrCaps;
|
|
5663
|
+
const caps = Array.isArray(toolOrCaps) ? toolOrCaps : input.capabilities ?? [];
|
|
5664
|
+
return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c));
|
|
5665
|
+
}
|
|
5666
|
+
function getDangerousCapabilities(toolOrCaps) {
|
|
5667
|
+
if (!toolOrCaps) return [];
|
|
5668
|
+
const input = toolOrCaps;
|
|
5669
|
+
const caps = Array.isArray(toolOrCaps) ? toolOrCaps : input.capabilities ?? [];
|
|
5670
|
+
return caps.filter(
|
|
5671
|
+
(c) => DANGEROUS_FOR_SUBAGENTS.includes(c)
|
|
5672
|
+
);
|
|
5673
|
+
}
|
|
5674
|
+
|
|
5675
|
+
// src/coordination/subagent-result-tool.ts
|
|
5676
|
+
var SUBAGENT_STRUCTURED_REPORT_META_KEY = "subagentStructuredReport";
|
|
5677
|
+
var MAX_SUBAGENT_STRUCTURED_REPORT_CHARS = 8e3;
|
|
5678
|
+
var MAX_SUMMARY_CHARS = 1500;
|
|
5679
|
+
var MAX_FINDINGS = 16;
|
|
5680
|
+
var MAX_FILES = 64;
|
|
5681
|
+
var MAX_NEXT_STEPS = 12;
|
|
5682
|
+
var MAX_ITEM_CHARS = 500;
|
|
5683
|
+
function normalizeSubagentStructuredReport(value) {
|
|
5684
|
+
if (!isRecord3(value)) return void 0;
|
|
5685
|
+
const summary = nonEmptyString(value["summary"]);
|
|
5686
|
+
const findings = stringArray(value["findings"]);
|
|
5687
|
+
const filesExamined = stringArray(value["files_examined"]);
|
|
5688
|
+
const nextSteps = stringArray(value["suggested_next_steps"]);
|
|
5689
|
+
const confidence = value["confidence"];
|
|
5690
|
+
if (!summary || summary.length > MAX_SUMMARY_CHARS || !findings || findings.length > MAX_FINDINGS || !filesExamined || filesExamined.length > MAX_FILES || !nextSteps || nextSteps.length > MAX_NEXT_STEPS || [...findings, ...filesExamined, ...nextSteps].some(
|
|
5691
|
+
(item) => item.trim().length > MAX_ITEM_CHARS
|
|
5692
|
+
) || typeof confidence !== "number" || !Number.isFinite(confidence) || confidence < 0 || confidence > 1) {
|
|
5693
|
+
return void 0;
|
|
5694
|
+
}
|
|
5695
|
+
const report = {
|
|
5696
|
+
summary,
|
|
5697
|
+
findings: findings.map((item) => item.trim()).filter(Boolean),
|
|
5698
|
+
files_examined: filesExamined.map((item) => item.trim()).filter(Boolean),
|
|
5699
|
+
confidence,
|
|
5700
|
+
suggested_next_steps: nextSteps.map((item) => item.trim()).filter(Boolean)
|
|
5701
|
+
};
|
|
5702
|
+
return JSON.stringify(report).length <= MAX_SUBAGENT_STRUCTURED_REPORT_CHARS ? report : void 0;
|
|
5703
|
+
}
|
|
5704
|
+
function readSubagentStructuredReport(ctx) {
|
|
5705
|
+
return normalizeSubagentStructuredReport(ctx?.meta?.[SUBAGENT_STRUCTURED_REPORT_META_KEY]);
|
|
5706
|
+
}
|
|
5707
|
+
function isRecord3(value) {
|
|
5708
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5709
|
+
}
|
|
5710
|
+
function nonEmptyString(value) {
|
|
5711
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
5712
|
+
}
|
|
5713
|
+
function stringArray(value) {
|
|
5714
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
|
|
5715
|
+
}
|
|
5716
|
+
|
|
5408
5717
|
// src/coordination/agent-subagent-runner.ts
|
|
5409
5718
|
function withDisabledToolFiltering(factory) {
|
|
5410
5719
|
return async (config) => {
|
|
@@ -5426,6 +5735,8 @@ function makeAgentSubagentRunner(opts) {
|
|
|
5426
5735
|
const taskStartedAt = Date.now();
|
|
5427
5736
|
const factoryResult = await opts.factory(ctx.config);
|
|
5428
5737
|
const { agent, events } = factoryResult;
|
|
5738
|
+
const agentContext = agent.ctx;
|
|
5739
|
+
if (agentContext?.meta) agentContext.meta["subagentTaskId"] = task.id;
|
|
5429
5740
|
const detachFleet = opts.fleetBus?.attach(ctx.subagentId, events, task.id);
|
|
5430
5741
|
const aborter = new AbortController();
|
|
5431
5742
|
ctx.budget._events = events;
|
|
@@ -5521,6 +5832,10 @@ function makeAgentSubagentRunner(opts) {
|
|
|
5521
5832
|
events.on("provider.text_delta", (e) => {
|
|
5522
5833
|
ctx.budget.markActivity();
|
|
5523
5834
|
streamingTextAcc = (streamingTextAcc + e.text).slice(-2e3);
|
|
5835
|
+
const text = streamingTextAcc.trim();
|
|
5836
|
+
if (text) {
|
|
5837
|
+
ctx.reportProgress?.({ text, source: "stream", capturedAt: Date.now() });
|
|
5838
|
+
}
|
|
5524
5839
|
})
|
|
5525
5840
|
);
|
|
5526
5841
|
const onParentAbort = () => aborter.abort();
|
|
@@ -5528,6 +5843,10 @@ function makeAgentSubagentRunner(opts) {
|
|
|
5528
5843
|
let result;
|
|
5529
5844
|
try {
|
|
5530
5845
|
result = await agent.run(format(task, ctx.config), { signal: aborter.signal });
|
|
5846
|
+
const finalText2 = result.finalText?.trim();
|
|
5847
|
+
if (finalText2) {
|
|
5848
|
+
ctx.reportProgress?.({ text: finalText2, source: "run_result", capturedAt: Date.now() });
|
|
5849
|
+
}
|
|
5531
5850
|
events.emit("subagent.task_completed", {
|
|
5532
5851
|
subagentId: ctx.subagentId,
|
|
5533
5852
|
taskId: task.id,
|
|
@@ -5609,6 +5928,7 @@ function makeAgentSubagentRunner(opts) {
|
|
|
5609
5928
|
}
|
|
5610
5929
|
return {
|
|
5611
5930
|
result: result.finalText,
|
|
5931
|
+
report: readSubagentStructuredReport(agentContext),
|
|
5612
5932
|
iterations: result.iterations,
|
|
5613
5933
|
toolCalls: usage.toolCalls
|
|
5614
5934
|
};
|
|
@@ -7341,20 +7661,31 @@ function classifySubagentError(err, hints = {}) {
|
|
|
7341
7661
|
return { kind: "unknown", message: baseMessage, retryable: false, cause };
|
|
7342
7662
|
}
|
|
7343
7663
|
function providerErrorToSubagentError(err, message, cause) {
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7664
|
+
switch (err.kind) {
|
|
7665
|
+
case "rate_limit":
|
|
7666
|
+
return {
|
|
7667
|
+
kind: "provider_rate_limit",
|
|
7668
|
+
message,
|
|
7669
|
+
retryable: true,
|
|
7670
|
+
backoffMs: err.body?.retryAfterMs ?? 5e3,
|
|
7671
|
+
cause
|
|
7672
|
+
};
|
|
7673
|
+
case "auth":
|
|
7674
|
+
return { kind: "provider_auth", message, retryable: false, cause };
|
|
7675
|
+
case "timeout":
|
|
7676
|
+
case "network":
|
|
7677
|
+
return { kind: "provider_timeout", message, retryable: true, cause };
|
|
7678
|
+
case "overloaded":
|
|
7679
|
+
case "server":
|
|
7680
|
+
case "stream_hang":
|
|
7681
|
+
return { kind: "provider_5xx", message, retryable: true, backoffMs: 3e3, cause };
|
|
7682
|
+
case "context_overflow":
|
|
7683
|
+
return { kind: "context_overflow", message, retryable: false, cause };
|
|
7684
|
+
case "invalid_request":
|
|
7685
|
+
case "content_filter":
|
|
7686
|
+
case "unknown":
|
|
7687
|
+
return { kind: "unknown", message, retryable: err.retryable, cause };
|
|
7356
7688
|
}
|
|
7357
|
-
return { kind: "unknown", message, retryable: err.retryable, cause };
|
|
7358
7689
|
}
|
|
7359
7690
|
|
|
7360
7691
|
// src/coordination/fleet.ts
|
|
@@ -8087,12 +8418,22 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8087
8418
|
}
|
|
8088
8419
|
this.inFlight++;
|
|
8089
8420
|
const startTime = Date.now();
|
|
8421
|
+
let latestPartial;
|
|
8090
8422
|
const runCtx = {
|
|
8091
8423
|
subagentId,
|
|
8092
8424
|
config: subagent.config,
|
|
8093
8425
|
budget,
|
|
8094
8426
|
signal: subagent.abortController.signal,
|
|
8095
|
-
bridge: subagent.context.parentBridge || null
|
|
8427
|
+
bridge: subagent.context.parentBridge || null,
|
|
8428
|
+
reportProgress: (partial) => {
|
|
8429
|
+
const text = partial.text.trim();
|
|
8430
|
+
if (!text) return;
|
|
8431
|
+
latestPartial = {
|
|
8432
|
+
...partial,
|
|
8433
|
+
// A partial is context recovery, not a transcript replacement.
|
|
8434
|
+
text: text.slice(-4e3)
|
|
8435
|
+
};
|
|
8436
|
+
}
|
|
8096
8437
|
};
|
|
8097
8438
|
let result;
|
|
8098
8439
|
budget.start();
|
|
@@ -8109,6 +8450,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8109
8450
|
taskId: task.id,
|
|
8110
8451
|
status: "success",
|
|
8111
8452
|
result: outcome.result,
|
|
8453
|
+
...outcome.report ? { report: outcome.report } : {},
|
|
8112
8454
|
iterations: outcome.iterations,
|
|
8113
8455
|
toolCalls: outcome.toolCalls,
|
|
8114
8456
|
durationMs: Date.now() - startTime
|
|
@@ -8123,6 +8465,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8123
8465
|
error: classifySubagentError(err, {
|
|
8124
8466
|
parentAborted: subagent.abortController.signal.aborted
|
|
8125
8467
|
}),
|
|
8468
|
+
...latestPartial ? { partial: latestPartial } : {},
|
|
8126
8469
|
iterations: usage.iterations,
|
|
8127
8470
|
toolCalls: usage.toolCalls,
|
|
8128
8471
|
durationMs: Date.now() - startTime
|
|
@@ -8368,6 +8711,8 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8368
8711
|
taskId: result.taskId,
|
|
8369
8712
|
status: result.status,
|
|
8370
8713
|
result: result.result,
|
|
8714
|
+
report: result.report,
|
|
8715
|
+
partial: result.partial,
|
|
8371
8716
|
iterations: result.iterations,
|
|
8372
8717
|
toolCalls: result.toolCalls,
|
|
8373
8718
|
durationMs: result.durationMs
|
|
@@ -8856,6 +9201,20 @@ ${lastFew}` : "No prior iterations.",
|
|
|
8856
9201
|
}
|
|
8857
9202
|
};
|
|
8858
9203
|
var MAX_RETRY_AFTER_MS = 6e4;
|
|
9204
|
+
var MAX_ATTEMPTS_BY_KIND = {
|
|
9205
|
+
rate_limit: 5,
|
|
9206
|
+
stream_hang: 5,
|
|
9207
|
+
// transient, worth retrying aggressively
|
|
9208
|
+
overloaded: 3,
|
|
9209
|
+
server: 3,
|
|
9210
|
+
timeout: 2,
|
|
9211
|
+
network: 2,
|
|
9212
|
+
auth: 0,
|
|
9213
|
+
invalid_request: 0,
|
|
9214
|
+
context_overflow: 0,
|
|
9215
|
+
content_filter: 0,
|
|
9216
|
+
unknown: 0
|
|
9217
|
+
};
|
|
8859
9218
|
var DefaultRetryPolicy = class {
|
|
8860
9219
|
shouldRetry(err, attempt) {
|
|
8861
9220
|
if (err instanceof ProviderError) {
|
|
@@ -8869,11 +9228,7 @@ var DefaultRetryPolicy = class {
|
|
|
8869
9228
|
}
|
|
8870
9229
|
maxAttempts(err) {
|
|
8871
9230
|
if (err instanceof ProviderError) {
|
|
8872
|
-
|
|
8873
|
-
if (err.status === 529) return 3;
|
|
8874
|
-
if (err.status === 599) return 5;
|
|
8875
|
-
if (err.status >= 500) return 3;
|
|
8876
|
-
return 0;
|
|
9231
|
+
return MAX_ATTEMPTS_BY_KIND[err.kind];
|
|
8877
9232
|
}
|
|
8878
9233
|
return 2;
|
|
8879
9234
|
}
|
|
@@ -10012,14 +10367,56 @@ function escapeRegExp(s) {
|
|
|
10012
10367
|
function createStrategyCompactor(opts = {}) {
|
|
10013
10368
|
const requested = opts.strategy ?? (opts.llmSelector ? "selective" : "hybrid");
|
|
10014
10369
|
const strategy = requested;
|
|
10370
|
+
let inner;
|
|
10015
10371
|
if (strategy === "intelligent" || strategy === "selective") {
|
|
10016
|
-
|
|
10372
|
+
inner = new ProviderBackedCompactor(strategy, opts);
|
|
10373
|
+
} else {
|
|
10374
|
+
inner = new HybridCompactor({
|
|
10375
|
+
preserveK: opts.preserveK,
|
|
10376
|
+
eliseThreshold: opts.eliseThreshold,
|
|
10377
|
+
smart: opts.smart
|
|
10378
|
+
});
|
|
10017
10379
|
}
|
|
10018
|
-
return new
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10380
|
+
return new JournaledCompactor(inner);
|
|
10381
|
+
}
|
|
10382
|
+
var JournaledCompactor = class {
|
|
10383
|
+
constructor(inner) {
|
|
10384
|
+
this.inner = inner;
|
|
10385
|
+
}
|
|
10386
|
+
inner;
|
|
10387
|
+
async compact(ctx, compactOpts = {}) {
|
|
10388
|
+
const state = ctx.state;
|
|
10389
|
+
const revisionBefore = state.revision;
|
|
10390
|
+
const report = await this.inner.compact(ctx, compactOpts);
|
|
10391
|
+
const changed = state.revision !== revisionBefore || report.reductions.some((reduction) => reduction.saved > 0) || report.repaired !== void 0;
|
|
10392
|
+
const writer = ctx.session;
|
|
10393
|
+
if (!changed || !writer) return report;
|
|
10394
|
+
const messages = ctx.messages.map(stripTransientMessageFields);
|
|
10395
|
+
try {
|
|
10396
|
+
await writer.append({
|
|
10397
|
+
type: "context_snapshot",
|
|
10398
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10399
|
+
reason: "compaction",
|
|
10400
|
+
messages
|
|
10401
|
+
});
|
|
10402
|
+
await writer.flush();
|
|
10403
|
+
} catch (err) {
|
|
10404
|
+
console.error(
|
|
10405
|
+
JSON.stringify({
|
|
10406
|
+
level: "error",
|
|
10407
|
+
event: "session.context_snapshot_write_failed",
|
|
10408
|
+
sessionId: writer.id,
|
|
10409
|
+
message: toErrorMessage(err),
|
|
10410
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
10411
|
+
})
|
|
10412
|
+
);
|
|
10413
|
+
}
|
|
10414
|
+
return report;
|
|
10415
|
+
}
|
|
10416
|
+
};
|
|
10417
|
+
function stripTransientMessageFields(message) {
|
|
10418
|
+
const { _estTokens: _ignored, ...persisted } = message;
|
|
10419
|
+
return persisted;
|
|
10023
10420
|
}
|
|
10024
10421
|
var ProviderBackedCompactor = class {
|
|
10025
10422
|
constructor(strategy, opts) {
|
|
@@ -10077,62 +10474,6 @@ function readPolicy(ctx) {
|
|
|
10077
10474
|
return candidate;
|
|
10078
10475
|
}
|
|
10079
10476
|
|
|
10080
|
-
// src/security/capabilities.ts
|
|
10081
|
-
var ToolCapabilities = {
|
|
10082
|
-
/** Can execute arbitrary commands in the user's shell (the `bash` tool). */
|
|
10083
|
-
SHELL_ARBITRARY: "shell.arbitrary",
|
|
10084
|
-
/** Can execute a restricted set of commands (the `exec` tool). */
|
|
10085
|
-
SHELL_RESTRICTED: "shell.restricted",
|
|
10086
|
-
/** Can run a restricted project formatter/linter-style command. */
|
|
10087
|
-
SHELL_EXEC: "shell.exec",
|
|
10088
|
-
/** Can write / modify / delete files inside the project. */
|
|
10089
|
-
FS_WRITE: "fs.write",
|
|
10090
|
-
/** Can write files outside the current project root (very high risk). */
|
|
10091
|
-
FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project",
|
|
10092
|
-
/** Can invoke arbitrary registered tools through a meta-tool. */
|
|
10093
|
-
TOOL_MUTATE_ANY: "tool.mutate.any",
|
|
10094
|
-
/** Can write persistent memory. */
|
|
10095
|
-
MEMORY_WRITE: "memory.write",
|
|
10096
|
-
/** Can delete persistent memory. */
|
|
10097
|
-
MEMORY_DELETE: "memory.delete",
|
|
10098
|
-
/** Proxies tools from external MCP servers (unknown capability). */
|
|
10099
|
-
MCP_PROXY: "mcp.proxy",
|
|
10100
|
-
/** Can spawn or manage subagents / multi-agent tasks. */
|
|
10101
|
-
SUBAGENT_SPAWN: "subagent.spawn",
|
|
10102
|
-
/** Can mutate global or session configuration / trust state. */
|
|
10103
|
-
CONFIG_MUTATE: "config.mutate",
|
|
10104
|
-
/** Can install packages or run package managers with side effects. */
|
|
10105
|
-
PACKAGE_INSTALL: "package.install"
|
|
10106
|
-
};
|
|
10107
|
-
var DANGEROUS_FOR_SUBAGENTS = [
|
|
10108
|
-
ToolCapabilities.SHELL_ARBITRARY,
|
|
10109
|
-
ToolCapabilities.SHELL_RESTRICTED,
|
|
10110
|
-
ToolCapabilities.SHELL_EXEC,
|
|
10111
|
-
ToolCapabilities.FS_WRITE,
|
|
10112
|
-
ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,
|
|
10113
|
-
ToolCapabilities.TOOL_MUTATE_ANY,
|
|
10114
|
-
ToolCapabilities.MEMORY_WRITE,
|
|
10115
|
-
ToolCapabilities.MEMORY_DELETE,
|
|
10116
|
-
ToolCapabilities.MCP_PROXY,
|
|
10117
|
-
ToolCapabilities.SUBAGENT_SPAWN,
|
|
10118
|
-
ToolCapabilities.CONFIG_MUTATE,
|
|
10119
|
-
ToolCapabilities.PACKAGE_INSTALL
|
|
10120
|
-
];
|
|
10121
|
-
function hasDangerousCapabilityForSubagents(toolOrCaps) {
|
|
10122
|
-
if (!toolOrCaps) return false;
|
|
10123
|
-
const input = toolOrCaps;
|
|
10124
|
-
const caps = Array.isArray(toolOrCaps) ? toolOrCaps : input.capabilities ?? [];
|
|
10125
|
-
return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c));
|
|
10126
|
-
}
|
|
10127
|
-
function getDangerousCapabilities(toolOrCaps) {
|
|
10128
|
-
if (!toolOrCaps) return [];
|
|
10129
|
-
const input = toolOrCaps;
|
|
10130
|
-
const caps = Array.isArray(toolOrCaps) ? toolOrCaps : input.capabilities ?? [];
|
|
10131
|
-
return caps.filter(
|
|
10132
|
-
(c) => DANGEROUS_FOR_SUBAGENTS.includes(c)
|
|
10133
|
-
);
|
|
10134
|
-
}
|
|
10135
|
-
|
|
10136
10477
|
// src/types/tool-markers.ts
|
|
10137
10478
|
var MALFORMED_ARG_MARKERS = ["__raw", "__raw_arguments", "_raw"];
|
|
10138
10479
|
|
|
@@ -10259,29 +10600,39 @@ var ToolExecutor = class _ToolExecutor {
|
|
|
10259
10600
|
budget = this.budgetForString(result.content, budget);
|
|
10260
10601
|
return { result, tool, durationMs: Date.now() - start };
|
|
10261
10602
|
}
|
|
10603
|
+
if (hasMalformedArguments(use.input)) {
|
|
10604
|
+
const result = this.malformedInputResult(use, extractMalformedRaw(use.input));
|
|
10605
|
+
budget = this.budgetForString(result.content, budget);
|
|
10606
|
+
return { result, tool, durationMs: Date.now() - start };
|
|
10607
|
+
}
|
|
10262
10608
|
const validation = validateAgainstSchema(use.input, tool.inputSchema);
|
|
10263
10609
|
if (!validation.ok) {
|
|
10264
|
-
const
|
|
10265
|
-
const
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10610
|
+
const coercion = coerceAgainstSchema(use.input, tool.inputSchema);
|
|
10611
|
+
const revalidation = coercion.changed ? validateAgainstSchema(coercion.value, tool.inputSchema) : validation;
|
|
10612
|
+
if (coercion.changed && revalidation.ok) {
|
|
10613
|
+
this.opts.logger?.info("tool arguments coerced to match inputSchema", {
|
|
10614
|
+
tool: tool.name,
|
|
10615
|
+
id: use.id
|
|
10616
|
+
});
|
|
10617
|
+
use = { ...use, input: coercion.value };
|
|
10618
|
+
} else {
|
|
10619
|
+
const errorDetails = revalidation.errors.map((e) => ` - ${e.path || "input"}: ${e.message}`).join("\n");
|
|
10620
|
+
const result = {
|
|
10621
|
+
type: "tool_result",
|
|
10622
|
+
tool_use_id: use.id,
|
|
10623
|
+
content: `Invalid arguments for tool "${tool.name}".
|
|
10269
10624
|
|
|
10270
10625
|
Validation errors:
|
|
10271
10626
|
${errorDetails}
|
|
10272
10627
|
|
|
10273
|
-
|
|
10274
|
-
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10628
|
+
Fix exactly the fields listed above and call the tool again. You can use the "tool-help" tool with name="${tool.name}" to see the exact expected schema.`,
|
|
10629
|
+
is_error: true
|
|
10630
|
+
};
|
|
10631
|
+
budget = this.budgetForString(result.content, budget);
|
|
10632
|
+
return { result, tool, durationMs: Date.now() - start };
|
|
10633
|
+
}
|
|
10278
10634
|
}
|
|
10279
10635
|
const toolDangerousCaps = getDangerousCapabilities(tool);
|
|
10280
|
-
if (hasMalformedArguments(use.input)) {
|
|
10281
|
-
const result = this.malformedInputResult(use, extractMalformedRaw(use.input));
|
|
10282
|
-
budget = this.budgetForString(result.content, budget);
|
|
10283
|
-
return { result, tool, durationMs: Date.now() - start };
|
|
10284
|
-
}
|
|
10285
10636
|
if (this.opts.hookRunner?.has("PreToolUse")) {
|
|
10286
10637
|
const pre = await this.opts.hookRunner.preToolUse(tool.name, use.input, ctx);
|
|
10287
10638
|
if (pre.block) {
|
|
@@ -10747,6 +11098,8 @@ function extractMalformedRaw(input) {
|
|
|
10747
11098
|
}
|
|
10748
11099
|
}
|
|
10749
11100
|
var TOOL_OUTPUT_ARTIFACT_THRESHOLD_BYTES = 64 * 1024;
|
|
11101
|
+
var TOOL_OUTPUT_ARTIFACT_PREVIEW_BYTES = 12 * 1024;
|
|
11102
|
+
var TOOL_OUTPUT_ARTIFACT_OMISSION = "\n\u2026[artifact middle omitted]\u2026\n";
|
|
10750
11103
|
function classifyToolError(err) {
|
|
10751
11104
|
if (err instanceof Error && err.name === "AbortError") {
|
|
10752
11105
|
return { category: "fatal" /* FATAL */, retryable: false, detail: "aborted" };
|
|
@@ -10830,12 +11183,53 @@ async function maybePersistLargeToolOutput(toolName, content, budget) {
|
|
|
10830
11183
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10831
11184
|
const filePath = path3.join(dir, `${stamp}-${safeTool}-${randomUUID()}.log`);
|
|
10832
11185
|
await fs.writeFile(filePath, content, "utf8");
|
|
10833
|
-
|
|
10834
|
-
|
|
11186
|
+
const marker = `[full tool output: ${bytes} bytes at ${filePath}; read/grep that file selectively instead of re-running or requesting more output]`;
|
|
11187
|
+
const fixedBytes = Buffer.byteLength(marker + TOOL_OUTPUT_ARTIFACT_OMISSION, "utf8");
|
|
11188
|
+
const previewBytes = Math.min(
|
|
11189
|
+
TOOL_OUTPUT_ARTIFACT_PREVIEW_BYTES,
|
|
11190
|
+
Math.max(0, budget - fixedBytes)
|
|
11191
|
+
);
|
|
11192
|
+
if (previewBytes < 256) return marker;
|
|
11193
|
+
const headBudget = Math.ceil(previewBytes / 2);
|
|
11194
|
+
const tailBudget = previewBytes - headBudget;
|
|
11195
|
+
const head = sliceUtf8Prefix(content, headBudget);
|
|
11196
|
+
const tail = sliceUtf8Suffix(content, tailBudget);
|
|
11197
|
+
return `${marker}
|
|
11198
|
+
${head}${TOOL_OUTPUT_ARTIFACT_OMISSION}${tail}`;
|
|
10835
11199
|
} catch {
|
|
10836
11200
|
return content;
|
|
10837
11201
|
}
|
|
10838
11202
|
}
|
|
11203
|
+
function sliceUtf8Prefix(text, maxBytes) {
|
|
11204
|
+
if (maxBytes <= 0) return "";
|
|
11205
|
+
if (Buffer.byteLength(text, "utf8") <= maxBytes) return text;
|
|
11206
|
+
let low = 0;
|
|
11207
|
+
let high = text.length;
|
|
11208
|
+
while (low < high) {
|
|
11209
|
+
const mid = Math.ceil((low + high) / 2);
|
|
11210
|
+
if (Buffer.byteLength(text.slice(0, mid), "utf8") <= maxBytes) low = mid;
|
|
11211
|
+
else high = mid - 1;
|
|
11212
|
+
}
|
|
11213
|
+
let end = low;
|
|
11214
|
+
const last = text.charCodeAt(end - 1);
|
|
11215
|
+
if (last >= 55296 && last <= 56319) end--;
|
|
11216
|
+
return text.slice(0, end);
|
|
11217
|
+
}
|
|
11218
|
+
function sliceUtf8Suffix(text, maxBytes) {
|
|
11219
|
+
if (maxBytes <= 0) return "";
|
|
11220
|
+
if (Buffer.byteLength(text, "utf8") <= maxBytes) return text;
|
|
11221
|
+
let low = 0;
|
|
11222
|
+
let high = text.length;
|
|
11223
|
+
while (low < high) {
|
|
11224
|
+
const chars = Math.ceil((low + high) / 2);
|
|
11225
|
+
if (Buffer.byteLength(text.slice(text.length - chars), "utf8") <= maxBytes) low = chars;
|
|
11226
|
+
else high = chars - 1;
|
|
11227
|
+
}
|
|
11228
|
+
let start = text.length - low;
|
|
11229
|
+
const first = text.charCodeAt(start);
|
|
11230
|
+
if (first >= 56320 && first <= 57343) start++;
|
|
11231
|
+
return text.slice(start);
|
|
11232
|
+
}
|
|
10839
11233
|
|
|
10840
11234
|
export { AutoCompactionMiddleware, AutonomousRunner, DEFAULT_RECOVERY_STRATEGIES, DefaultDesignKitLoader, DefaultErrorHandler, DefaultPromptLoader, DefaultRetryPolicy, DefaultSkillLoader, DoneConditionChecker, EternalAutonomyEngine, HybridCompactor, IntelligentCompactor, ParallelEternalEngine, SelectiveCompactor, ToolExecutor, _resetDesignKitLoaderMemo, _resetDesignRulesCache, activateDesign, applyModelRuntime, buildGoalPreamble, buildRecoveryStrategies, clearActiveKit, clearPersistedActiveKit, createAutonomyBrain, createStrategyCompactor, createTieredBrainArbiter, designProjectDir, detectFrontendFile, detectFrontendIntent, formatDecisionSummary, getDesignKitLoader, getDesignState, installDesignStudioMiddleware, loadActiveKit, loadProjectDesignRules, makeAutonomyPromptContributor, makeDesignDetectToolCallMiddleware, makeDesignDetectUserInputMiddleware, makeDesignStudioRequestMiddleware, mergeModelRuntime, recordKitChoice, renderPrompt, resolveBundledDesignKitsDir, resolveCacheForRequest, resolveModelRuntime, resolveReasoningForRequest, setActiveKit };
|
|
10841
11235
|
//# sourceMappingURL=index.js.map
|