@sema-agent/core 7.6.2 → 7.6.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 7.6.3 — 2026-09-08
4
+
5
+ Maintenance patch on the 7.6.x line: one correction to 7.6.2's forwarding drain.
6
+
7
+ ### Fixed
8
+ - **forwardSubagentEvents drain gate** — 7.6.2 gated the drain inside an `async` helper and awaited it unconditionally, so a run that did NOT opt in still yielded one extra microtask before its terminal push (the black-box round measured parent `done` at hop 356 vs 355 on 7.6.1). The gate is now a synchronous predicate at both terminal pushes and the helper is a plain Promise factory; the non-forwarding terminal depth is pinned (ratchet 58, the unconditional-await form reds it at 59). No change for opted-in runs.
9
+
3
10
  ## 7.6.2 — 2026-09-08
4
11
 
5
12
  Backport patch on the 7.6.x line (two field bugs the server 7.64.0 chain found; no store-contract change — that is 7.7.0).
@@ -97,5 +97,9 @@ export interface PrepareRunRefsResult {
97
97
  * the smallest boundary that strictly orders after all pending microtasks; it is taken only on the opted-in run,
98
98
  * only once, right before `done`.
99
99
  */
100
- export declare function drainForwardedFramesBeforeDone(spec: Pick<TaskSpec, "forwardSubagentEvents">): Promise<void>;
100
+ export declare function forwardsSubagentEvents(spec: Pick<TaskSpec, "forwardSubagentEvents">): boolean;
101
+ /** The drain itself — one macrotask turn. Callers gate it with {@link forwardsSubagentEvents} SYNCHRONOUSLY so a
102
+ * non-forwarding run's terminal push is not one microtask later than it was (an `await` of an early-returning
103
+ * async function still yields once; the black-box round measured that tick). */
104
+ export declare function drainForwardedFramesBeforeDone(): Promise<void>;
101
105
  export declare function prepareRunRefs(input: PrepareRunRefsInput): PrepareRunRefsResult;
@@ -2,10 +2,11 @@ import { createSubagentWorktreeHelper } from "../../agents/subagent.js";
2
2
  import { SubagentRetainLedger } from "../../agents/retain-ledger.js";
3
3
  import { ActiveSkillScope } from "./active-skill-scope.js";
4
4
  import { createEditedFilesLedger } from "./edited-files-ledger.js";
5
- export async function drainForwardedFramesBeforeDone(spec) {
6
- if (spec.forwardSubagentEvents !== true)
7
- return;
8
- await new Promise((resolve) => setImmediate(resolve));
5
+ export function forwardsSubagentEvents(spec) {
6
+ return spec.forwardSubagentEvents === true;
7
+ }
8
+ export function drainForwardedFramesBeforeDone() {
9
+ return new Promise((resolve) => setImmediate(resolve));
9
10
  }
10
11
  export function prepareRunRefs(input) {
11
12
  const { spec, internals, executionEnv, taskRootFinal } = input;
@@ -39,7 +39,7 @@ import { amendTerminal, terminalProjection } from "./terminal-projection.js";
39
39
  import { ATTACHMENT_BYTE_CAP, CHANGED_FILES_MAX, TOTAL_TOKENS_REMINDER_DEFAULT_MODE, AGENT_LISTING_REMOVED_HEADER, SKILLS_LISTING_DELTA_HEADER, SKILLS_LISTING_REMOVED_HEADER, advanceCadenceClock, agentListingDeltaHeader, attachmentEnvelopeTags, agentListingInitialHeader, replayAnnouncedListing, replayAnnouncedModels, clipToBytes, collectDateChange, collectDueAttachments, collectInstructionsChange, commitAgentListing, commitInstructionsChange, commitSkillsListing, createAttachmentState, rebaseCadenceWindows, reduceToolEnd, renderAgentListingDelta, renderMcpDroppedTools, renderMcpInstructionsDelta, renderOrphanedBackgroundTasks, selectMcpDroppedBatch, renderSkillsListingDelta, renderToolsDelta, stampWriteAnchor } from "./turn-attachments.js";
40
40
  import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } from "./compaction-call-options.js";
41
41
  import { effectiveDelegationFacts, prepareTask } from "./prepare-task.js";
42
- import { drainForwardedFramesBeforeDone } from "./prepare-run-refs.js";
42
+ import { drainForwardedFramesBeforeDone, forwardsSubagentEvents } from "./prepare-run-refs.js";
43
43
  import { gatedCallIdOf } from "./park-commit.js";
44
44
  import { placementValueOrAbsent } from "./checkpoint-scope.js";
45
45
  import { SessionReadFileStates } from "./prepare-hands-readface.js";
@@ -1838,7 +1838,8 @@ export class Runner {
1838
1838
  onError: (f) => console.warn(`[sema-core] ${f.site}: delegation-lifecycle observer threw (contained; further failures counted, not re-disclosed): ${f.error.message}`),
1839
1839
  }), "runtask.onDelegationLifecycle");
1840
1840
  }
1841
- await drainForwardedFramesBeforeDone(spec);
1841
+ if (forwardsSubagentEvents(spec))
1842
+ await drainForwardedFramesBeforeDone();
1842
1843
  queue.push({ type: "done", result: resultValue });
1843
1844
  queue.close();
1844
1845
  });
@@ -4278,7 +4279,8 @@ export class Runner {
4278
4279
  drainManualCompact("mooted");
4279
4280
  }
4280
4281
  manualCompactRef.emitMooted = undefined;
4281
- await drainForwardedFramesBeforeDone(spec);
4282
+ if (forwardsSubagentEvents(spec))
4283
+ await drainForwardedFramesBeforeDone();
4282
4284
  queue.push({ type: "done", result });
4283
4285
  queue.close();
4284
4286
  await prepared.fileHistoryBoundary?.settle();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/core",
3
- "version": "7.6.2",
3
+ "version": "7.6.3",
4
4
  "description": "Stateless, task-oriented AI agent core",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",