@sema-agent/core 5.62.0 → 5.63.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.
@@ -345,6 +345,7 @@ function buildMicroCompactState(deps, model, sessionId, offloadStore, knob) {
345
345
  clearOnRejection: knob.clearOnRejection,
346
346
  ledger: createClearedProjectionLedger(),
347
347
  projectionRef: {},
348
+ inTurnCompactionRef: {},
348
349
  ...(offloadStore ? { offloadPersist: createOffloadPersist(offloadStore, sessionId, deps.onNotice) } : {}),
349
350
  };
350
351
  }
@@ -363,10 +364,75 @@ function recordFrontierClears(args) {
363
364
  taskId: args.taskId,
364
365
  clearedCount: args.pass.clears.length,
365
366
  tokensSavedEstimate: args.pass.tokensSavedEstimate,
366
- trigger: "frontier",
367
+ trigger: args.trigger,
367
368
  ts: Date.now(),
368
369
  }));
369
370
  }
371
+ function flushProjectionObservations(pending) {
372
+ for (const fire of pending.splice(0)) {
373
+ try {
374
+ fire();
375
+ }
376
+ catch {
377
+ }
378
+ }
379
+ }
380
+ export async function runGuardChain(args) {
381
+ const { edited, microCompact, guardAt, charsPerToken, deps, taskId } = args;
382
+ const applyGuardTrim = (view, anchoredTotal) => {
383
+ let trimmed = trimToBudget(view, guardAt, anchoredTotal, charsPerToken);
384
+ const dropped = trimmed.length < view.length;
385
+ if (dropped) {
386
+ args.trimPressureRef.droppedMessages = true;
387
+ const droppedCount = view.length - trimmed.length;
388
+ trimmed = insertTrimNotice(trimmed);
389
+ emitTrace(deps.tracer, () => ({
390
+ kind: "context.trim",
391
+ version: 1,
392
+ taskId,
393
+ dropped: droppedCount,
394
+ ts: Date.now(),
395
+ }));
396
+ }
397
+ return { trimmed, dropped };
398
+ };
399
+ let working = edited;
400
+ let anchoredWorking = estimateContextTokens(working, charsPerToken).tokens;
401
+ if (microCompact.machine === "legacy") {
402
+ const t = applyGuardTrim(working, anchoredWorking);
403
+ return { working, trimmed: t.trimmed, trimDroppedMessages: t.dropped };
404
+ }
405
+ if (microCompact.machine === "off" && anchoredWorking > guardAt) {
406
+ let blockingPass;
407
+ const blockingEdited = clearStaleToolResults(working, {
408
+ budgetTokens: guardAt,
409
+ machine: "cc",
410
+ clearSource: args.replayed,
411
+ onCleared: (pass) => { blockingPass = pass; },
412
+ anchoredTotalTokens: anchoredWorking,
413
+ charsPerToken,
414
+ ...(args.offloadStore ? { offload: { persist: createOffloadPersist(args.offloadStore, args.sessionId, deps.onNotice) } } : {}),
415
+ });
416
+ if (blockingPass !== undefined) {
417
+ recordFrontierClears({ pass: blockingPass, index: args.index, edited: blockingEdited, ledger: microCompact.ledger, tracer: deps.tracer, taskId, trigger: "blocking" });
418
+ working = blockingEdited;
419
+ anchoredWorking = estimateContextTokens(working, charsPerToken).tokens;
420
+ }
421
+ }
422
+ if (anchoredWorking > guardAt && args.recheck !== true) {
423
+ const compacted = (await microCompact.inTurnCompactionRef.current?.(args.signal, anchoredWorking)) === true;
424
+ if (compacted) {
425
+ args.pendingProjectionObservations.length = 0;
426
+ return { earlyReturn: { messages: working, adoptSessionRebuild: true } };
427
+ }
428
+ if (args.signal?.aborted === true) {
429
+ args.pendingProjectionObservations.length = 0;
430
+ return { working, trimmed: working, trimDroppedMessages: false };
431
+ }
432
+ }
433
+ const t = applyGuardTrim(working, anchoredWorking);
434
+ return { working, trimmed: t.trimmed, trimDroppedMessages: t.dropped };
435
+ }
370
436
  export function gatedCallIdOf(p) {
371
437
  if (p.suspendRef.token !== undefined)
372
438
  return p.suspendRef.gatedCallId;
@@ -4621,101 +4687,108 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
4621
4687
  const guardAt = guardBudget(model);
4622
4688
  const microCompact = buildMicroCompactState(deps, model, sessionId, offloadStore, microCompactKnob);
4623
4689
  const charsPerToken = model.charsPerToken ?? DEFAULT_CHARS_PER_TOKEN;
4624
- harness.on("context", async ({ messages }) => {
4690
+ harness.on("context", async ({ messages, recheck, signal }) => {
4625
4691
  batchHaltRef.current = undefined;
4626
- const healed = dropEmptyFailureAssistants(messages);
4627
- const replay = replayClearedProjection(healed, microCompact.ledger);
4628
- const replayed = replay.messages;
4629
- const capped = await capAggregateToolResults(replayed, {
4630
- store: offloadStore,
4631
- sessionId,
4632
- onCapped: (info) => emitTrace(deps.tracer, () => ({
4633
- kind: "tool_result.capped",
4634
- version: 1,
4635
- taskId: spec.taskId ?? sessionId,
4636
- ...(info.tool !== undefined ? { tool: info.tool } : {}),
4637
- sizeChars: info.sizeChars,
4638
- storeFallback: info.storeFallback,
4639
- ts: Date.now(),
4640
- })),
4641
- });
4642
- const mediaCapped = capAggregateMediaBytes(capped, {
4643
- limitBytes: deps.mediaByteCapBytes ?? AGGREGATE_MEDIA_BUDGET_BYTES,
4644
- onStripped: deps.onMediaStripped,
4645
- });
4646
- let ccPass;
4647
- const edited = clearStaleToolResults(mediaCapped, {
4648
- budgetTokens: editAt,
4649
- ...(microCompact.machine === "cc" || microCompact.clearOnRejection ? { recognizeCcMarkers: true } : {}),
4650
- ...(microCompact.machine === "cc"
4651
- ? {
4652
- machine: "cc",
4653
- clearSource: replayed,
4654
- onCleared: (pass) => { ccPass = pass; },
4655
- }
4656
- : {}),
4657
- anchoredTotalTokens: estimateContextTokens(mediaCapped, charsPerToken).tokens,
4658
- charsPerToken,
4659
- ...(offloadStore
4660
- ? {
4661
- offload: {
4662
- persist: createOffloadPersist(offloadStore, sessionId, deps.onNotice),
4663
- },
4664
- }
4665
- : {}),
4666
- });
4667
- if (ccPass !== undefined) {
4668
- recordFrontierClears({ pass: ccPass, index: replay.index, edited, ledger: microCompact.ledger, tracer: deps.tracer, taskId: spec.taskId ?? sessionId });
4669
- }
4670
- let trimmed = trimToBudget(edited, guardAt, estimateContextTokens(edited, charsPerToken).tokens, charsPerToken);
4671
- const trimDroppedMessages = trimmed.length < edited.length;
4672
- if (trimDroppedMessages) {
4673
- trimPressureRef.droppedMessages = true;
4674
- const droppedCount = edited.length - trimmed.length;
4675
- trimmed = insertTrimNotice(trimmed);
4676
- emitTrace(deps.tracer, () => ({
4677
- kind: "context.trim",
4678
- version: 1,
4679
- taskId: spec.taskId ?? sessionId,
4680
- dropped: droppedCount,
4681
- ts: Date.now(),
4682
- }));
4683
- }
4684
- trimmed = applyGitFrameGuard({
4685
- before: edited,
4686
- trimmed,
4687
- budgetTokens: guardAt,
4688
- ref: gitStatusRef,
4689
- charsPerToken,
4690
- onDegrade: (message) => {
4692
+ const pendingProjectionObservations = [];
4693
+ try {
4694
+ const healed = dropEmptyFailureAssistants(messages);
4695
+ const replay = replayClearedProjection(healed, microCompact.ledger);
4696
+ const replayed = replay.messages;
4697
+ const capped = await capAggregateToolResults(replayed, {
4698
+ store: offloadStore,
4699
+ sessionId,
4700
+ onCapped: (info) => pendingProjectionObservations.push(() => emitTrace(deps.tracer, () => ({
4701
+ kind: "tool_result.capped",
4702
+ version: 1,
4703
+ taskId: spec.taskId ?? sessionId,
4704
+ ...(info.tool !== undefined ? { tool: info.tool } : {}),
4705
+ sizeChars: info.sizeChars,
4706
+ storeFallback: info.storeFallback,
4707
+ ts: Date.now(),
4708
+ }))),
4709
+ });
4710
+ const mediaCapped = capAggregateMediaBytes(capped, {
4711
+ limitBytes: deps.mediaByteCapBytes ?? AGGREGATE_MEDIA_BUDGET_BYTES,
4712
+ onStripped: (info) => {
4713
+ const onMediaStripped = deps.onMediaStripped;
4714
+ if (onMediaStripped !== undefined)
4715
+ pendingProjectionObservations.push(() => onMediaStripped(info));
4716
+ },
4717
+ });
4718
+ let ccPass;
4719
+ const edited = microCompact.machine === "off" ? mediaCapped : clearStaleToolResults(mediaCapped, {
4720
+ budgetTokens: editAt,
4721
+ machine: microCompact.machine,
4722
+ ...(microCompact.machine === "cc" || microCompact.clearOnRejection ? { recognizeCcMarkers: true } : {}),
4723
+ ...(microCompact.machine === "cc"
4724
+ ? {
4725
+ clearSource: replayed,
4726
+ onCleared: (pass) => { ccPass = pass; },
4727
+ }
4728
+ : {}),
4729
+ anchoredTotalTokens: estimateContextTokens(mediaCapped, charsPerToken).tokens,
4730
+ charsPerToken,
4731
+ ...(offloadStore
4732
+ ? {
4733
+ offload: {
4734
+ persist: createOffloadPersist(offloadStore, sessionId, deps.onNotice),
4735
+ },
4736
+ }
4737
+ : {}),
4738
+ });
4739
+ if (ccPass !== undefined) {
4740
+ recordFrontierClears({ pass: ccPass, index: replay.index, edited, ledger: microCompact.ledger, tracer: deps.tracer, taskId: spec.taskId ?? sessionId, trigger: "frontier" });
4741
+ }
4742
+ const chain = await runGuardChain({
4743
+ edited, replayed, index: replay.index, microCompact, guardAt, charsPerToken, offloadStore,
4744
+ sessionId, taskId: spec.taskId ?? sessionId, deps, trimPressureRef, recheck, signal,
4745
+ pendingProjectionObservations,
4746
+ });
4747
+ if ("earlyReturn" in chain) {
4748
+ return chain.earlyReturn;
4749
+ }
4750
+ const { working, trimDroppedMessages } = chain;
4751
+ let trimmed = chain.trimmed;
4752
+ trimmed = applyGitFrameGuard({
4753
+ before: working,
4754
+ trimmed,
4755
+ budgetTokens: guardAt,
4756
+ ref: gitStatusRef,
4757
+ charsPerToken,
4758
+ onDegrade: (message) => {
4759
+ try {
4760
+ deps.onError?.(new Error(message), { phase: "degraded", sessionId, classification: "env-git-snapshot" });
4761
+ }
4762
+ catch {
4763
+ }
4764
+ },
4765
+ });
4766
+ const swept = dropOrphanToolResults(trimmed);
4767
+ if (swept.dropped.length > 0) {
4691
4768
  try {
4692
- deps.onError?.(new Error(message), { phase: "degraded", sessionId, classification: "env-git-snapshot" });
4769
+ deps.onError?.(new Error(`context belt: dropped ${swept.dropped.length} orphan toolResult(s) whose tool-call assistant was not in the request view — ` +
4770
+ swept.dropped
4771
+ .map((d) => `toolCallId=${d.toolCallId} at index ${d.index} (prev=${d.prevRole}, next=${d.nextRole})`)
4772
+ .join("; ")), { phase: "hook", sessionId });
4693
4773
  }
4694
4774
  catch {
4695
4775
  }
4696
- },
4697
- });
4698
- const swept = dropOrphanToolResults(trimmed);
4699
- if (swept.dropped.length > 0) {
4700
- try {
4701
- deps.onError?.(new Error(`context belt: dropped ${swept.dropped.length} orphan toolResult(s) whose tool-call assistant was not in the request view — ` +
4702
- swept.dropped
4703
- .map((d) => `toolCallId=${d.toolCallId} at index ${d.index} (prev=${d.prevRole}, next=${d.nextRole})`)
4704
- .join("; ")), { phase: "hook", sessionId });
4705
- }
4706
- catch {
4707
4776
  }
4777
+ requestLossyRef.current =
4778
+ replayed !== healed ||
4779
+ capped !== replayed ||
4780
+ mediaCapped !== capped ||
4781
+ edited !== mediaCapped ||
4782
+ working !== edited ||
4783
+ trimDroppedMessages ||
4784
+ swept.dropped.length > 0 ||
4785
+ gitStatusRef.overBudgetShrunk === true;
4786
+ microCompact.projectionRef.current = { messages: swept.messages, keyOf: replay.index.keyOf };
4787
+ return { messages: swept.messages };
4788
+ }
4789
+ finally {
4790
+ flushProjectionObservations(pendingProjectionObservations);
4708
4791
  }
4709
- requestLossyRef.current =
4710
- replayed !== healed ||
4711
- capped !== replayed ||
4712
- mediaCapped !== capped ||
4713
- edited !== mediaCapped ||
4714
- trimDroppedMessages ||
4715
- swept.dropped.length > 0 ||
4716
- gitStatusRef.overBudgetShrunk === true;
4717
- microCompact.projectionRef.current = { messages: swept.messages, keyOf: replay.index.keyOf };
4718
- return { messages: swept.messages };
4719
4792
  });
4720
4793
  const cacheBreakDetector = deps.cacheBreakDetection === false ? undefined : new CacheBreakDetector();
4721
4794
  const cacheFingerprint = cacheBreakDetector