@sema-agent/core 1.284.0 → 1.286.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 (49) hide show
  1. package/dist/agents/subagent.d.ts +1 -0
  2. package/dist/agents/subagent.d.ts.map +1 -1
  3. package/dist/agents/subagent.js +6 -3
  4. package/dist/agents/subagent.js.map +1 -1
  5. package/dist/core/auto-compaction.d.ts +29 -0
  6. package/dist/core/auto-compaction.d.ts.map +1 -1
  7. package/dist/core/auto-compaction.js +149 -8
  8. package/dist/core/auto-compaction.js.map +1 -1
  9. package/dist/core/runner/call-cap.d.ts +6 -0
  10. package/dist/core/runner/call-cap.d.ts.map +1 -1
  11. package/dist/core/runner/call-cap.js +19 -7
  12. package/dist/core/runner/call-cap.js.map +1 -1
  13. package/dist/core/runner/prepare-task.d.ts.map +1 -1
  14. package/dist/core/runner/prepare-task.js +21 -1
  15. package/dist/core/runner/prepare-task.js.map +1 -1
  16. package/dist/core/runner/runtask.d.ts.map +1 -1
  17. package/dist/core/runner/runtask.js +119 -11
  18. package/dist/core/runner/runtask.js.map +1 -1
  19. package/dist/core/trace.d.ts +46 -0
  20. package/dist/core/trace.d.ts.map +1 -1
  21. package/dist/core/trace.js.map +1 -1
  22. package/dist/core/types.d.ts +8 -1
  23. package/dist/core/types.d.ts.map +1 -1
  24. package/dist/core/version.d.ts +2 -0
  25. package/dist/core/version.d.ts.map +1 -0
  26. package/dist/core/version.js +15 -0
  27. package/dist/core/version.js.map +1 -0
  28. package/dist/engine/compaction/compaction.d.ts +9 -0
  29. package/dist/engine/compaction/compaction.d.ts.map +1 -1
  30. package/dist/engine/compaction/compaction.js +33 -0
  31. package/dist/engine/compaction/compaction.js.map +1 -1
  32. package/dist/engine/harness/agent-harness.d.ts +1 -0
  33. package/dist/engine/harness/agent-harness.d.ts.map +1 -1
  34. package/dist/engine/harness/agent-harness.js.map +1 -1
  35. package/dist/engine/harness/types.d.ts +1 -0
  36. package/dist/engine/harness/types.d.ts.map +1 -1
  37. package/dist/engine/harness/types.js.map +1 -1
  38. package/dist/engine/loop/agent-loop.js +1 -0
  39. package/dist/engine/loop/agent-loop.js.map +1 -1
  40. package/dist/engine/loop/types.d.ts +1 -0
  41. package/dist/engine/loop/types.d.ts.map +1 -1
  42. package/dist/index.d.ts +1 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/internal/harness.d.ts +2 -2
  46. package/dist/internal/harness.d.ts.map +1 -1
  47. package/dist/internal/harness.js +1 -1
  48. package/dist/internal/harness.js.map +1 -1
  49. package/package.json +1 -1
@@ -1,7 +1,8 @@
1
1
  import { AgentHarness, DEFAULT_COMPACTION_SETTINGS, uuidv7 } from "../../internal/harness.js";
2
2
  import { CheckpointError, BINDING_CHECKPOINT_VERSION, checkpointVersionOf, MAX_SUPPORTED_CHECKPOINT_VERSION, remainingBudgetMicroUsd, validatePendingSteer, winnerFromOutcome, } from "../checkpoint-store.js";
3
- import { effectiveCushionMs, estimateCycleMs, recordCallSample, recordToolSample, writeoutCushionMs } from "./call-cap.js";
4
- import { DEFAULT_COMPACTION_INSTRUCTIONS, createRapidRefillState, maybeCompact, nextTrimForceBackoff, recordCompactionAndCheckRapidRefill } from "../auto-compaction.js";
3
+ import { effectiveCushionMs, estimateCycleMs, minLiveWriteoutWindowMs, recordCallSample, recordToolSample, recordTtftSample, softExecDeadlineMs, writeoutCushionMs } from "./call-cap.js";
4
+ import { engineVersion } from "../version.js";
5
+ import { DEFAULT_COMPACTION_INSTRUCTIONS, createRapidRefillState, isCompactionWalltimeAbort, maybeCompact, nextTrimForceBackoff, recordCompactionAndCheckRapidRefill } from "../auto-compaction.js";
5
6
  import { ASK_USER_QUESTION_TOOL_NAME } from "../ask-question.js";
6
7
  import { computeCostMicroUsd, modelCostToPricing } from "../pricing.js";
7
8
  import { emitTrace } from "../trace.js";
@@ -303,6 +304,7 @@ export class Runner {
303
304
  const manualCompactRef = { requested: false, waiters: [] };
304
305
  const drainManualCompactWaiters = (outcome) => {
305
306
  manualCompactRef.requested = false;
307
+ manualCompactRef.instructions = undefined;
306
308
  for (const w of manualCompactRef.waiters.splice(0))
307
309
  w(outcome);
308
310
  };
@@ -496,7 +498,7 @@ export class Runner {
496
498
  }
497
499
  notifyRef.inject(payload, opts);
498
500
  },
499
- compact: async () => {
501
+ compact: async (opts) => {
500
502
  if (resultValue)
501
503
  throw steeringError("the task has already finished");
502
504
  const h = handle ?? (await orTimeout(ready));
@@ -504,6 +506,9 @@ export class Runner {
504
506
  throw steeringError("the task is not running");
505
507
  return new Promise((resolve) => {
506
508
  manualCompactRef.requested = true;
509
+ if (opts?.instructions !== undefined) {
510
+ manualCompactRef.instructions = opts.instructions;
511
+ }
507
512
  manualCompactRef.waiters.push(resolve);
508
513
  });
509
514
  },
@@ -796,7 +801,7 @@ export class Runner {
796
801
  const writeFamilyOf = (name) => writeFamilyByName.get(name) ?? writeFamilyOfCanonical(canonicalToolName(name));
797
802
  const toolStartAt = new Map();
798
803
  const startedToolCallIds = new Set();
799
- emitTrace(tracer, () => ({ kind: "task.start", version: 1, taskId, model: prepared.model.id, ts: taskStart }));
804
+ emitTrace(tracer, () => ({ kind: "task.start", version: 1, taskId, model: prepared.model.id, engineVersion: engineVersion(), ts: taskStart }));
800
805
  emitTrace(tracer, () => ({
801
806
  kind: "prompt.assembled",
802
807
  version: 1,
@@ -1007,6 +1012,9 @@ export class Runner {
1007
1012
  const capLast = prepared.callCapRef?.state.last;
1008
1013
  if (prepared.callCapRef) {
1009
1014
  recordCallSample(prepared.callCapRef.state, u.output || 0, callStartAt !== undefined ? callEndAt - callStartAt : 0);
1015
+ if (callStartAt !== undefined && firstTokenAt !== undefined) {
1016
+ recordTtftSample(prepared.callCapRef.state, firstTokenAt - callStartAt);
1017
+ }
1010
1018
  prepared.callCapRef.state.last = undefined;
1011
1019
  }
1012
1020
  emitTrace(tracer, () => ({
@@ -1330,6 +1338,52 @@ export class Runner {
1330
1338
  };
1331
1339
  const withinTaskCompaction = (spec.compaction?.enabled ?? true) && (spec.compaction?.withinTask ?? true);
1332
1340
  const compactionBreaker = { failures: 0 };
1341
+ const compactionThroughputRef = {};
1342
+ const windowSafetyOptions = (mainModel) => ({
1343
+ ...(maxCostMicroUsd !== undefined
1344
+ ? {
1345
+ fallbackBudget: {
1346
+ spentMicroUsd: () => stats.costMicroUsd,
1347
+ capMicroUsd: maxCostMicroUsd,
1348
+ mainInputPer1M: (this.deps.pricing?.[mainModel.id] ?? modelCostToPricing(mainModel.cost)).inputPer1M,
1349
+ },
1350
+ }
1351
+ : {}),
1352
+ ...(walltimeDeadlineMs !== undefined && prepared.callCapRef !== undefined
1353
+ ? {
1354
+ walltime: {
1355
+ deadlineMs: walltimeDeadlineMs,
1356
+ cushionMs: () => effectiveCushionMs(prepared.callCapRef) ?? 0,
1357
+ throughputRef: compactionThroughputRef,
1358
+ },
1359
+ }
1360
+ : {}),
1361
+ onWindowSafety: (info) => {
1362
+ if (info.kind === "fallback") {
1363
+ emitTrace(tracer, () => ({
1364
+ kind: "compaction.model_fallback",
1365
+ version: 1,
1366
+ taskId,
1367
+ contentTokens: info.contentTokens,
1368
+ headroomTokens: info.headroomTokens ?? 0,
1369
+ truncationRatio: info.truncationRatio,
1370
+ ...(info.estCostMicroUsd !== undefined ? { estCostMicroUsd: info.estCostMicroUsd } : {}),
1371
+ ts: Date.now(),
1372
+ }));
1373
+ }
1374
+ else {
1375
+ emitTrace(tracer, () => ({
1376
+ kind: "compaction.clamp_disclosure",
1377
+ version: 1,
1378
+ taskId,
1379
+ truncationRatio: info.truncationRatio,
1380
+ reason: info.reason ?? "tolerance",
1381
+ ...(info.estCostMicroUsd !== undefined ? { estCostMicroUsd: info.estCostMicroUsd } : {}),
1382
+ ts: Date.now(),
1383
+ }));
1384
+ }
1385
+ },
1386
+ });
1333
1387
  const stopHook = (spec.hooks ?? this.deps.hooks)?.stop;
1334
1388
  const finalVerificationOn = spec.finalVerification === true;
1335
1389
  if (stopHook || finalVerificationOn) {
@@ -1434,7 +1488,18 @@ export class Runner {
1434
1488
  malformedToolUse: {},
1435
1489
  thinkingOnly: {},
1436
1490
  degenerateOutput: { detect: (m) => m.errorMessage === DEGENERATE_MESSAGE },
1437
- walltimeCutoff: { detect: (m) => m.errorMessage === WALLTIME_CUTOFF_MESSAGE },
1491
+ walltimeCutoff: {
1492
+ detect: (m) => m.errorMessage === WALLTIME_CUTOFF_MESSAGE,
1493
+ hasLiveWriteoutWindow: () => {
1494
+ const ref = prepared.callCapRef;
1495
+ if (ref === undefined)
1496
+ return true;
1497
+ const soft = softExecDeadlineMs(ref);
1498
+ if (soft === undefined)
1499
+ return true;
1500
+ return soft - Date.now() >= minLiveWriteoutWindowMs(ref.state);
1501
+ },
1502
+ },
1438
1503
  promptTooLong: {
1439
1504
  recover: async () => {
1440
1505
  if (!(spec.compaction?.enabled ?? true))
@@ -1466,6 +1531,7 @@ export class Runner {
1466
1531
  }
1467
1532
  : undefined,
1468
1533
  ...this.seamCCompactionOptions(prepared),
1534
+ ...windowSafetyOptions(prepared.harness.getModel()),
1469
1535
  ...this.compactionHookOptions(spec, prepared.sessionId, "forced"),
1470
1536
  });
1471
1537
  if (comp.compacted) {
@@ -1484,6 +1550,10 @@ export class Runner {
1484
1550
  ...(comp.durationMs !== undefined ? { durationMs: comp.durationMs } : {}),
1485
1551
  ...(comp.firstKeptEntryId !== undefined ? { preserved_segment: { firstKeptEntryId: comp.firstKeptEntryId } } : {}),
1486
1552
  ...(comp.attachedFiles !== undefined ? { attachedFiles: comp.attachedFiles } : {}),
1553
+ ...(comp.modelFallback ? { modelFallback: true } : {}),
1554
+ ...(comp.fallbackReason !== undefined ? { fallbackReason: comp.fallbackReason } : {}),
1555
+ ...(comp.clampedRatio !== undefined ? { clampedRatio: comp.clampedRatio } : {}),
1556
+ ...(comp.clampReason !== undefined ? { clampReason: comp.clampReason } : {}),
1487
1557
  });
1488
1558
  prepared.cacheBreakDetector?.notifyCompaction();
1489
1559
  if (attachState !== undefined) {
@@ -1496,8 +1566,9 @@ export class Runner {
1496
1566
  }
1497
1567
  return comp.compacted === true;
1498
1568
  }
1499
- catch {
1500
- compactionBreaker.failures += 1;
1569
+ catch (err) {
1570
+ if (!isCompactionWalltimeAbort(err))
1571
+ compactionBreaker.failures += 1;
1501
1572
  return false;
1502
1573
  }
1503
1574
  },
@@ -1508,6 +1579,7 @@ export class Runner {
1508
1579
  let trimForceBackoff = false;
1509
1580
  const drainManualCompact = (outcome) => {
1510
1581
  manualCompactRef.requested = false;
1582
+ manualCompactRef.instructions = undefined;
1511
1583
  for (const w of manualCompactRef.waiters.splice(0))
1512
1584
  w(outcome);
1513
1585
  };
@@ -1743,11 +1815,27 @@ export class Runner {
1743
1815
  }
1744
1816
  return undefined;
1745
1817
  }
1818
+ const claimedManual = forceManual
1819
+ ? { instructions: manualCompactRef.instructions, waiters: manualCompactRef.waiters.splice(0) }
1820
+ : undefined;
1821
+ if (forceManual) {
1822
+ manualCompactRef.requested = false;
1823
+ manualCompactRef.instructions = undefined;
1824
+ }
1825
+ const resolveClaimedWaiters = (outcome) => {
1826
+ if (claimedManual !== undefined)
1827
+ for (const w of claimedManual.waiters.splice(0))
1828
+ w(outcome);
1829
+ };
1746
1830
  const trimPressureArmed = prepared.trimPressureRef.droppedMessages;
1747
1831
  if (trimPressureArmed)
1748
1832
  prepared.trimPressureRef.droppedMessages = false;
1749
1833
  const trimPressure = trimPressureArmed && !trimForceBackoff;
1750
1834
  let manualOutcome = "failed";
1835
+ if (finalizeInjected && forceManual) {
1836
+ emitTrace(tracer, () => ({ kind: "compaction.manual_in_finalize", version: 1, taskId, ts: Date.now() }));
1837
+ }
1838
+ const manualInstructions = claimedManual?.instructions;
1751
1839
  try {
1752
1840
  const comp = await maybeCompact({
1753
1841
  session: prepared.session,
@@ -1757,7 +1845,7 @@ export class Runner {
1757
1845
  getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
1758
1846
  thinking: prepared.thinking,
1759
1847
  settings: { ...DEFAULT_COMPACTION_SETTINGS, ...spec.compaction },
1760
- customInstructions: spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
1848
+ customInstructions: manualInstructions ?? spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
1761
1849
  signal: prepared.abortController.signal,
1762
1850
  minTokens: forceManual ? 0 : compactionFloor,
1763
1851
  force: forceManual,
@@ -1772,6 +1860,7 @@ export class Runner {
1772
1860
  }
1773
1861
  : undefined,
1774
1862
  ...this.seamCCompactionOptions(prepared),
1863
+ ...windowSafetyOptions(event.model),
1775
1864
  ...this.compactionHookOptions(spec, prepared.sessionId, trimPressure ? "forced" : forceManual ? "manual" : "auto"),
1776
1865
  });
1777
1866
  if (comp.blocked) {
@@ -1824,6 +1913,10 @@ export class Runner {
1824
1913
  ...(comp.durationMs !== undefined ? { durationMs: comp.durationMs } : {}),
1825
1914
  ...(comp.firstKeptEntryId !== undefined ? { preserved_segment: { firstKeptEntryId: comp.firstKeptEntryId } } : {}),
1826
1915
  ...(comp.attachedFiles !== undefined ? { attachedFiles: comp.attachedFiles } : {}),
1916
+ ...(comp.modelFallback ? { modelFallback: true } : {}),
1917
+ ...(comp.fallbackReason !== undefined ? { fallbackReason: comp.fallbackReason } : {}),
1918
+ ...(comp.clampedRatio !== undefined ? { clampedRatio: comp.clampedRatio } : {}),
1919
+ ...(comp.clampReason !== undefined ? { clampReason: comp.clampReason } : {}),
1827
1920
  });
1828
1921
  prepared.cacheBreakDetector?.notifyCompaction();
1829
1922
  if (attachState !== undefined) {
@@ -1839,7 +1932,9 @@ export class Runner {
1839
1932
  }
1840
1933
  catch (err) {
1841
1934
  if (!prepared.abortController.signal.aborted) {
1842
- compactionBreaker.failures += 1;
1935
+ const walltimeAbort = isCompactionWalltimeAbort(err);
1936
+ if (!walltimeAbort)
1937
+ compactionBreaker.failures += 1;
1843
1938
  this.deps.onError?.(err, { phase: "compaction", sessionId: prepared.sessionId });
1844
1939
  const msg = String(err instanceof Error ? err.message : err);
1845
1940
  emitTrace(tracer, () => ({
@@ -1847,7 +1942,11 @@ export class Runner {
1847
1942
  version: 1,
1848
1943
  taskId,
1849
1944
  trigger: trimPressure ? "forced" : forceManual ? "manual" : "auto",
1850
- reason: msg.length > 512 ? `${msg.slice(0, 512)}…` : msg,
1945
+ reason: walltimeAbort
1946
+ ? "walltime soft-deadline abort (engine-initiated write-out protection; not counted toward the breaker)"
1947
+ : msg.length > 512
1948
+ ? `${msg.slice(0, 512)}…`
1949
+ : msg,
1851
1950
  ts: Date.now(),
1852
1951
  }));
1853
1952
  manualOutcome = "failed";
@@ -1857,7 +1956,7 @@ export class Runner {
1857
1956
  }
1858
1957
  }
1859
1958
  if (forceManual)
1860
- drainManualCompact(manualOutcome);
1959
+ resolveClaimedWaiters(manualOutcome);
1861
1960
  return undefined;
1862
1961
  };
1863
1962
  const unsubBoundary = prepared.harness.on("turn_boundary", onTurnBoundary);
@@ -2027,6 +2126,7 @@ export class Runner {
2027
2126
  skipCompaction: durablyPaused || compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES,
2028
2127
  minTokens: compactionFloor,
2029
2128
  brain: compactionBrain,
2129
+ windowSafety: windowSafetyOptions(prepared.model),
2030
2130
  });
2031
2131
  try {
2032
2132
  if (comp?.compacted) {
@@ -2039,6 +2139,10 @@ export class Runner {
2039
2139
  ...(comp.durationMs !== undefined ? { durationMs: comp.durationMs } : {}),
2040
2140
  ...(comp.firstKeptEntryId !== undefined ? { preserved_segment: { firstKeptEntryId: comp.firstKeptEntryId } } : {}),
2041
2141
  ...(comp.attachedFiles !== undefined ? { attachedFiles: comp.attachedFiles } : {}),
2142
+ ...(comp.modelFallback ? { modelFallback: true } : {}),
2143
+ ...(comp.fallbackReason !== undefined ? { fallbackReason: comp.fallbackReason } : {}),
2144
+ ...(comp.clampedRatio !== undefined ? { clampedRatio: comp.clampedRatio } : {}),
2145
+ ...(comp.clampReason !== undefined ? { clampReason: comp.clampReason } : {}),
2042
2146
  });
2043
2147
  prepared.cacheBreakDetector?.notifyCompaction();
2044
2148
  }
@@ -2187,6 +2291,9 @@ export class Runner {
2187
2291
  costMicroUsd: stats.costMicroUsd,
2188
2292
  durationMs: Date.now() - taskStart,
2189
2293
  ...(prepared.outputRef.set ? { hasStructuredOutput: true } : {}),
2294
+ ...(stats.mechanisms !== undefined
2295
+ ? { mechanisms: (({ repetitionEvents: _events, ...scalars }) => scalars)(stats.mechanisms) }
2296
+ : {}),
2190
2297
  ts: Date.now(),
2191
2298
  }));
2192
2299
  setResult(result);
@@ -2782,6 +2889,7 @@ export class Runner {
2782
2889
  keptChars: info.keptChars,
2783
2890
  ts: Date.now(),
2784
2891
  })),
2892
+ ...(opts?.windowSafety ?? {}),
2785
2893
  workingFileAttachments: spec.compaction?.attachWorkingFiles !== false && prepared.readTaskFile
2786
2894
  ? {
2787
2895
  readFile: prepared.readTaskFile,