@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.
Files changed (79) hide show
  1. package/dist/{compactor-BxddyCFu.d.ts → compactor-DQLL4HTo.d.ts} +1 -1
  2. package/dist/{config-DkCbA3Bw.d.ts → config-MRqn1V-u.d.ts} +130 -22
  3. package/dist/coordination/index.d.ts +43 -20
  4. package/dist/coordination/index.js +1744 -912
  5. package/dist/coordination/index.js.map +1 -1
  6. package/dist/{default-config-Buho8yge.d.ts → default-config-B79_gJYv.d.ts} +7 -0
  7. package/dist/defaults/index.d.ts +25 -29
  8. package/dist/defaults/index.js +2546 -7396
  9. package/dist/defaults/index.js.map +1 -1
  10. package/dist/{director-state-B_GPa78Q.d.ts → director-state-CMS_bMs4.d.ts} +2 -0
  11. package/dist/{events-KmxSmvho.d.ts → events-Bgnh43r9.d.ts} +27 -10
  12. package/dist/execution/index.d.ts +15 -16
  13. package/dist/execution/index.js +534 -140
  14. package/dist/execution/index.js.map +1 -1
  15. package/dist/execution/prompt-enhancer.d.ts +1 -1
  16. package/dist/extension/index.d.ts +6 -6
  17. package/dist/{global-mailbox-rWVt8YlO.d.ts → global-mailbox-sZwyI6CS.d.ts} +13 -2
  18. package/dist/{goal-store-8owBXJT2.d.ts → goal-store-Datpp-ar.d.ts} +1 -1
  19. package/dist/hq/index.d.ts +35 -9
  20. package/dist/hq/index.js +80 -7
  21. package/dist/hq/index.js.map +1 -1
  22. package/dist/{index-BhCteHAF.d.ts → index--Gm41aBJ.d.ts} +26 -11
  23. package/dist/{index-BEFWNZYs.d.ts → index-CbyuOE5y.d.ts} +5 -1
  24. package/dist/index.d.ts +52 -1017
  25. package/dist/index.js +21053 -27778
  26. package/dist/index.js.map +1 -1
  27. package/dist/infrastructure/index.d.ts +9 -7
  28. package/dist/infrastructure/index.js +7 -2
  29. package/dist/infrastructure/index.js.map +1 -1
  30. package/dist/kernel/index.d.ts +11 -11
  31. package/dist/kernel/index.js.map +1 -1
  32. package/dist/{mcp-servers-BUx9A_AQ.d.ts → mcp-servers-DEV4s6Ks.d.ts} +3 -3
  33. package/dist/models/index.d.ts +4 -4
  34. package/dist/models/index.js +18 -3
  35. package/dist/models/index.js.map +1 -1
  36. package/dist/{agent-subagent-runner-BsuWhB28.d.ts → multi-agent-coordinator-4RCRZKjN.d.ts} +417 -9
  37. package/dist/{null-fleet-bus-D4e9R7Qc.d.ts → null-fleet-bus-CFoNVQEK.d.ts} +53 -12
  38. package/dist/observability/index.d.ts +3 -3
  39. package/dist/{parallel-eternal-engine-iY2uxocj.d.ts → parallel-eternal-engine-HUrtePLd.d.ts} +4 -5
  40. package/dist/{permission-B6YAtNFz.d.ts → permission-ByDKXEcG.d.ts} +1 -1
  41. package/dist/{pipeline-ixSFe5jg.d.ts → pipeline-DGDyIohT.d.ts} +28 -7
  42. package/dist/{provider-model-resolve-DIxKL_T-.d.ts → provider-model-resolve-o2hHLs79.d.ts} +3 -3
  43. package/dist/{provider-runner-oQhDaZmH.d.ts → provider-runner-ChL-kVg6.d.ts} +3 -3
  44. package/dist/{retry-policy-V67lBOJz.d.ts → retry-policy-CQ7KwXJa.d.ts} +2 -2
  45. package/dist/{secret-vault-D7jeyXUQ.d.ts → secret-vault-DxohkUBc.d.ts} +3 -2
  46. package/dist/security/index.d.ts +4 -4
  47. package/dist/security/index.js +232 -2
  48. package/dist/security/index.js.map +1 -1
  49. package/dist/{selector-Bx2HgUkU.d.ts → selector-D8O6B_Rm.d.ts} +1 -1
  50. package/dist/{session-event-bridge-Bkp7ORfc.d.ts → session-event-bridge-D_z_mBwk.d.ts} +3 -3
  51. package/dist/{session-reader-B-Fi9L6I.d.ts → session-reader-7Esxrkpw.d.ts} +1 -1
  52. package/dist/storage/index.d.ts +77 -39
  53. package/dist/storage/index.js +1223 -288
  54. package/dist/storage/index.js.map +1 -1
  55. package/dist/tasking/index.d.ts +124 -0
  56. package/dist/tasking/index.js +492 -0
  57. package/dist/tasking/index.js.map +1 -0
  58. package/dist/{todos-checkpoint-BwCrj4Cb.d.ts → todos-checkpoint-FY7PjmMx.d.ts} +13 -4
  59. package/dist/{tool-LVSLiE1s.d.ts → tool-BNlnIJvo.d.ts} +216 -17
  60. package/dist/{tool-executor-kElSEgO0.d.ts → tool-executor-CckSCM5E.d.ts} +12 -15
  61. package/dist/tools/index.d.ts +2 -2
  62. package/dist/tools/index.js.map +1 -1
  63. package/dist/types/index.d.ts +94 -19
  64. package/dist/types/index.js +76 -12
  65. package/dist/types/index.js.map +1 -1
  66. package/dist/utils/index.d.ts +44 -10
  67. package/dist/utils/index.js +106 -17
  68. package/dist/utils/index.js.map +1 -1
  69. package/dist/{worktree-manager-BjyAW30D.d.ts → worktree-manager-DzwxKE35.d.ts} +1 -1
  70. package/instructions/coordination/subagent-baseline.md +5 -0
  71. package/instructions/llm/autonomy-brain.md +3 -2
  72. package/instructions/system.md +4 -0
  73. package/package.json +10 -3
  74. package/skills/mailbox-bridge/SKILL.md +33 -0
  75. package/dist/multi-agent-coordinator-CrjeTB9i.d.ts +0 -357
  76. package/dist/sdd/index.d.ts +0 -1993
  77. package/dist/sdd/index.js +0 -9500
  78. package/dist/sdd/index.js.map +0 -1
  79. package/dist/spec-TBi3Jr6T.d.ts +0 -78
@@ -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
- errors.push({ path: joinPath(path12, req), message: "required property missing" });
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
- for (const opt of request.options) {
2306
- if (text.toLowerCase().includes(opt.id.toLowerCase())) {
2307
- return {
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: providerStatusToCode(status, opts.body?.type),
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
- function providerStatusToCode(status, type) {
3882
- if (status === 0) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
3883
- if (type === "rate_limit_error" || status === 429) return ERROR_CODES.PROVIDER_RATE_LIMITED;
3884
- if (type === "authentication_error" || status === 401) return ERROR_CODES.PROVIDER_AUTH_FAILED;
3885
- if (type === "overloaded_error" || status === 529) return ERROR_CODES.PROVIDER_OVERLOADED;
3886
- if (type === "invalid_request_error" || status === 400) return ERROR_CODES.PROVIDER_INVALID_REQUEST;
3887
- if (status === 408) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
3888
- if (status >= 500) return ERROR_CODES.PROVIDER_SERVER_ERROR;
3889
- return ERROR_CODES.PROVIDER_INVALID_REQUEST;
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.status !== 413 && !isContextOverflowError(err)) return null;
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.status !== 429) return null;
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.status !== 529 && err.status < 500) return null;
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
- function isContextOverflowError(err) {
3970
- return CONTEXT_OVERFLOW_RE.test([
3971
- err.message,
3972
- err.body?.message,
3973
- err.body?.type,
3974
- err.body?.raw
3975
- ].filter(Boolean).join("\n"));
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.status === 429) return { kind: "rate_limit", retryable: true };
3991
- if (err.status === 529) return { kind: "overloaded", retryable: true };
3992
- if (err.status >= 500) return { kind: "server", retryable: true };
3993
- if (err.status === 413 || isContextOverflowError(err)) {
3994
- return { kind: "context_overflow", retryable: false };
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
- const status = err.status;
7345
- if (status === 429 || err.body?.type === "rate_limit_error") {
7346
- return { kind: "provider_rate_limit", message, retryable: true, backoffMs: 5e3, cause };
7347
- }
7348
- if (status === 401 || status === 403 || err.body?.type === "authentication_error") {
7349
- return { kind: "provider_auth", message, retryable: false, cause };
7350
- }
7351
- if (status === 408 || status === 0) {
7352
- return { kind: "provider_timeout", message, retryable: true, cause };
7353
- }
7354
- if (status >= 500 && status < 600) {
7355
- return { kind: "provider_5xx", message, retryable: true, backoffMs: 3e3, cause };
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
- if (err.status === 429) return 5;
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
- return new ProviderBackedCompactor(strategy, opts);
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 HybridCompactor({
10019
- preserveK: opts.preserveK,
10020
- eliseThreshold: opts.eliseThreshold,
10021
- smart: opts.smart
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 errorDetails = validation.errors.map((e) => ` - ${e.path || "input"}: ${e.message}`).join("\n");
10265
- const result = {
10266
- type: "tool_result",
10267
- tool_use_id: use.id,
10268
- content: `Invalid arguments for tool "${tool.name}".
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
- Please call the tool again with arguments that match its inputSchema. You can use the "tool-help" tool with name="${tool.name}" to see the exact expected schema.`,
10274
- is_error: true
10275
- };
10276
- budget = this.budgetForString(result.content, budget);
10277
- return { result, tool, durationMs: Date.now() - start };
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
- return content + `
10834
- [full tool output: ${bytes} bytes at ${filePath}; read/grep that file selectively instead of re-running or requesting more output]`;
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