@deepstrike/sdk 0.2.50 → 0.2.52

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 (39) hide show
  1. package/README.md +83 -60
  2. package/dist/index.d.ts +5 -7
  3. package/dist/index.js +3 -3
  4. package/dist/kernel.d.ts +61 -31
  5. package/dist/runtime/canonical-kernel-step.d.ts +152 -0
  6. package/dist/runtime/canonical-kernel-step.js +1483 -0
  7. package/dist/runtime/execution-plane.d.ts +0 -3
  8. package/dist/runtime/execution-plane.js +0 -24
  9. package/dist/runtime/facade.js +3 -0
  10. package/dist/runtime/kernel-event-log.js +7 -13
  11. package/dist/runtime/kernel-journal.d.ts +264 -0
  12. package/dist/runtime/kernel-journal.js +741 -0
  13. package/dist/runtime/kernel-primitives-dashboard.d.ts +0 -2
  14. package/dist/runtime/kernel-primitives-dashboard.js +1 -8
  15. package/dist/runtime/kernel-step.d.ts +29 -109
  16. package/dist/runtime/kernel-step.js +47 -317
  17. package/dist/runtime/os-snapshot.d.ts +2 -2
  18. package/dist/runtime/os-snapshot.js +2 -6
  19. package/dist/runtime/payload-store.d.ts +16 -0
  20. package/dist/runtime/payload-store.js +80 -0
  21. package/dist/runtime/runner.d.ts +31 -114
  22. package/dist/runtime/runner.js +689 -774
  23. package/dist/runtime/session-log.d.ts +34 -32
  24. package/dist/runtime/session-log.js +21 -131
  25. package/dist/runtime/session-repair.d.ts +2 -36
  26. package/dist/runtime/session-repair.js +2 -47
  27. package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
  28. package/dist/runtime/sub-agent-orchestrator.js +42 -40
  29. package/dist/types/agent.d.ts +22 -19
  30. package/dist/types/agent.js +26 -42
  31. package/dist/workflow/public.d.ts +1 -1
  32. package/dist/workflow/public.js +1 -1
  33. package/package.json +2 -2
  34. package/dist/runtime/kernel-rebuild.d.ts +0 -13
  35. package/dist/runtime/kernel-rebuild.js +0 -75
  36. package/dist/runtime/kernel-transaction-log.d.ts +0 -61
  37. package/dist/runtime/kernel-transaction-log.js +0 -149
  38. package/dist/runtime/large-result-spool.d.ts +0 -93
  39. package/dist/runtime/large-result-spool.js +0 -214
@@ -20,8 +20,6 @@ export interface PrimitivesStats {
20
20
  compressedCount: number;
21
21
  pageOutCount: number;
22
22
  pageInCount: number;
23
- largeResultSpooledCount: number;
24
- totalSpooledBytes: number;
25
23
  contextRenewedCount: number;
26
24
  };
27
25
  }
@@ -22,8 +22,6 @@ export class KernelPrimitivesDashboard {
22
22
  compressedCount: 0,
23
23
  pageOutCount: 0,
24
24
  pageInCount: 0,
25
- largeResultSpooledCount: 0,
26
- totalSpooledBytes: 0,
27
25
  contextRenewedCount: 0,
28
26
  },
29
27
  };
@@ -80,10 +78,6 @@ export class KernelPrimitivesDashboard {
80
78
  this.stats.mm.pageInCount++;
81
79
  else if (event.kind === "context_renewed")
82
80
  this.stats.mm.contextRenewedCount++;
83
- else if (event.kind === "large_result_spooled") {
84
- this.stats.mm.largeResultSpooledCount++;
85
- this.stats.mm.totalSpooledBytes += event.original_size;
86
- }
87
81
  }
88
82
  // Special handling for tool completion which logs at outer runner
89
83
  if (event.kind === "tool_completed") {
@@ -120,8 +114,7 @@ export class KernelPrimitivesDashboard {
120
114
  `║ ║`,
121
115
  `║ ${bold}${magenta}💾 MM (Memory Management & Context Paging)${reset} ║`,
122
116
  `║ - Compressions: ${s.mm.compressedCount.toString().padEnd(9)} - Page-Outs (Semantic): ${s.mm.pageOutCount.toString().padEnd(10)} ║`,
123
- `║ - Page-Ins (Cache): ${s.mm.pageInCount.toString().padEnd(7)} - Large Spooled: ${s.mm.largeResultSpooledCount.toString().padEnd(14)} ║`,
124
- `║ - Total Spooled Bytes: ${(s.mm.totalSpooledBytes / 1024).toFixed(1).toString() + " KB"}`.padEnd(70) + "║",
117
+ `║ - Page-Ins (Cache): ${s.mm.pageInCount.toString().padEnd(43)} ║`,
125
118
  footer
126
119
  ];
127
120
  return lines.join("\n");
@@ -1,69 +1,7 @@
1
1
  import type { EntropySample, Message, RenderedContext, TaskUpdate, ToolCall, ToolResult, ToolSchema } from "../types.js";
2
2
  import type { SkillMetadata } from "../skills/loader.js";
3
3
  import type { RollbackReason } from "./session-log.js";
4
- import type { SessionLog } from "./session-log.js";
5
- export declare const KERNEL_ABI_VERSION = 2;
6
- export interface KernelRuntimeHandle {
7
- step(inputJson: string): string;
8
- prepareStep(inputJson: string): string;
9
- commitPrepared(prepareToken: string): string;
10
- abortPrepared(prepareToken: string): void;
11
- snapshot(): string;
12
- restore(snapshotJson: string): void;
13
- diagnostics(): string;
14
- isTerminal(): boolean;
15
- turn(): number;
16
- recoveryContentBytes(): number;
17
- render(): RenderedContext;
18
- drainNewMessages(): Message[];
19
- preservedRefs(): string[];
20
- }
21
- export type KernelPreparationStatus = "prepared" | "replayed" | "rejected";
22
- export interface KernelPreparedStep {
23
- status: KernelPreparationStatus;
24
- base_generation: number;
25
- prepare_token?: string;
26
- input: Record<string, unknown>;
27
- step: KernelStepJson;
28
- }
29
- export interface KernelDiagnostics {
30
- lifecycle: string;
31
- next_step_seq: number;
32
- accepted_input_count: number;
33
- accepted_input_bytes: number;
34
- snapshot_input_limit: number;
35
- snapshot_journal_bytes_limit: number;
36
- max_input_bytes: number;
37
- snapshot_overflowed: boolean;
38
- recorded_event_count: number;
39
- completed_effect_count: number;
40
- pending_effect_count: number;
41
- }
42
- export declare function readKernelDiagnostics(runtime: KernelRuntimeHandle): KernelDiagnostics;
43
- export interface KernelSnapshot {
44
- snapshot_version: 2;
45
- abi_version: 2;
46
- initial_policy: {
47
- max_tokens: number;
48
- max_turns: number;
49
- max_total_tokens: string;
50
- max_wall_ms?: string;
51
- };
52
- lifecycle: string;
53
- operation_id?: string;
54
- next_step_seq: number;
55
- snapshot_input_limit: number;
56
- max_input_bytes: number;
57
- snapshot_journal_bytes_limit: number;
58
- accepted_input_bytes: number;
59
- accepted_inputs: Array<{
60
- event_id: string;
61
- [key: string]: unknown;
62
- }>;
63
- last_step?: Record<string, unknown>;
64
- }
65
- export declare function snapshotKernelRuntime(runtime: KernelRuntimeHandle): KernelSnapshot;
66
- export declare function restoreKernelRuntime(runtime: KernelRuntimeHandle, snapshot: KernelSnapshot): void;
4
+ export declare function encodeCanonicalContentParts(parts: unknown[]): string;
67
5
  export interface PaceDecision {
68
6
  action: "continue" | "sleep" | "stop";
69
7
  delayMs?: number;
@@ -75,6 +13,7 @@ export interface KernelLoopResult {
75
13
  termination: string;
76
14
  turnsUsed: number;
77
15
  totalTokensUsed: number;
16
+ finalMessage?: Message;
78
17
  /** ③ loop-agent: the kernel-adjudicated after-round decision (absent on non-loop runs). */
79
18
  paceDecision?: PaceDecision;
80
19
  }
@@ -117,6 +56,10 @@ export type KernelRunnerAction = {
117
56
  kind: "preempt_sub_agents";
118
57
  effectId: string;
119
58
  agentIds: string[];
59
+ attempts?: Array<{
60
+ task_id: string;
61
+ attempt_id: string;
62
+ }>;
120
63
  reason: string;
121
64
  } | {
122
65
  kind: "persist_memory";
@@ -127,22 +70,26 @@ export type KernelRunnerAction = {
127
70
  effectId: string;
128
71
  query: Record<string, unknown>;
129
72
  requestedK: number;
130
- } | {
131
- kind: "spool_large_result";
132
- effectId: string;
133
- callId: string;
134
- tool: string;
135
- output: string;
136
- originalSize: number;
137
- previewSize: number;
138
73
  } | {
139
74
  kind: "archive_page_out";
140
75
  effectId: string;
141
- turn: number;
142
- action: string;
76
+ turn?: number;
77
+ action?: string;
143
78
  summary?: string;
144
- archived: Message[];
145
- tier: string;
79
+ archived?: Message[];
80
+ tier?: string;
81
+ handleId?: string;
82
+ payload?: {
83
+ content: string;
84
+ digest: string;
85
+ original_size: string;
86
+ preview?: string;
87
+ };
88
+ } | {
89
+ kind: "load_payload";
90
+ effectId: string;
91
+ handleId: string;
92
+ payloadRef: string;
146
93
  } | {
147
94
  kind: "evaluate_milestone";
148
95
  effectId: string;
@@ -150,6 +97,10 @@ export type KernelRunnerAction = {
150
97
  criteria: string[];
151
98
  verifier?: MilestoneVerifierKind;
152
99
  requiredEvidence: string[];
100
+ } | {
101
+ kind: "unsupported_effect";
102
+ effectId: string;
103
+ effectKind: string;
153
104
  } | {
154
105
  kind: "done";
155
106
  effectId: string;
@@ -182,7 +133,7 @@ export interface KernelObservation {
182
133
  tokens_freed?: number;
183
134
  reason?: RollbackReason | string;
184
135
  agent_id?: string;
185
- parent_session_id?: string;
136
+ parent_task_id?: string;
186
137
  role?: string;
187
138
  isolation?: string;
188
139
  context_inheritance?: string;
@@ -207,7 +158,6 @@ export interface KernelObservation {
207
158
  tier?: string;
208
159
  message_count?: number;
209
160
  archive_ref?: string;
210
- spool_ref?: string;
211
161
  original_size?: number;
212
162
  preview_size?: number;
213
163
  record_id?: string;
@@ -252,19 +202,6 @@ export interface KernelObservation {
252
202
  window_turns?: number;
253
203
  threshold?: number;
254
204
  }
255
- export interface KernelStepJson {
256
- version: number;
257
- operation_id: string;
258
- input_event_id: string;
259
- step_seq: number;
260
- actions: Array<Record<string, unknown>>;
261
- observations: KernelObservation[];
262
- faults?: Array<{
263
- code?: string;
264
- message?: string;
265
- effect_id?: string;
266
- }>;
267
- }
268
205
  export declare function toolSchemaToKernel(schema: ToolSchema): Record<string, unknown>;
269
206
  export declare function skillMetadataToKernel(skill: SkillMetadata): Record<string, unknown>;
270
207
  export declare function messageToKernelMessage(message: Message): Record<string, unknown>;
@@ -277,22 +214,5 @@ export declare function capabilityCommandMount(capability: Record<string, unknow
277
214
  export declare function capabilityCommandUnmount(capabilityKind: string, id: string): Record<string, unknown>;
278
215
  /** Camel-case an `entropy_sample` kernel observation into the SDK's `EntropySample`. */
279
216
  export declare function entropySampleFromObservation(obs: KernelObservation): EntropySample;
280
- /**
281
- * Execute one production transition behind the durable action-publish gate. Genesis is persisted
282
- * before prepare; a newly prepared transaction is CAS-appended before commit; only the committed
283
- * step is returned to callers, so actions and observations cannot escape early.
284
- */
285
- export declare function durableKernelStep(runtime: KernelRuntimeHandle, sessionLog: SessionLog, sessionId: string, event: Record<string, unknown>): Promise<KernelStepJson>;
286
- export declare function durableKernelApply(runtime: KernelRuntimeHandle, sessionLog: SessionLog, sessionId: string, pending: KernelObservation[], event: Record<string, unknown>): Promise<KernelObservation[]>;
287
- export declare function durableKernelMaybeAction(runtime: KernelRuntimeHandle, sessionLog: SessionLog, sessionId: string, pending: KernelObservation[], event: Record<string, unknown>): Promise<KernelRunnerAction | null>;
288
- export declare function durableKernelAction(runtime: KernelRuntimeHandle, sessionLog: SessionLog, sessionId: string, pending: KernelObservation[], event: Record<string, unknown>): Promise<KernelRunnerAction>;
289
- export declare function kernelApply(runtime: KernelRuntimeHandle, pending: KernelObservation[], event: Record<string, unknown>): KernelObservation[];
290
- export declare function kernelAction(runtime: KernelRuntimeHandle, pending: KernelObservation[], event: Record<string, unknown>): KernelRunnerAction;
291
- /**
292
- * Like {@link kernelAction} but tolerates a zero-action step. Used for events
293
- * whose outcome may not drive a provider call — e.g. a signal the kernel queues
294
- * or ignores returns no action. Returns `null` in that case.
295
- */
296
- export declare function kernelMaybeAction(runtime: KernelRuntimeHandle, pending: KernelObservation[], event: Record<string, unknown>): KernelRunnerAction | null;
297
- /** Internal ABI-v2 step primitive shared by SDK adapters and conformance tests. */
298
- export declare function kernelStep(runtime: KernelRuntimeHandle, event: Record<string, unknown>): KernelStepJson;
217
+ export declare function kernelMessageToSdk(raw: Record<string, unknown>): Message;
218
+ export declare function renderedContextToSdk(raw: Record<string, unknown>): RenderedContext;
@@ -1,25 +1,20 @@
1
- import { createKernelOperationGenesis, createKernelTransaction, kernelRecordDigest, } from "./kernel-transaction-log.js";
2
- export const KERNEL_ABI_VERSION = 2;
3
- export function readKernelDiagnostics(runtime) {
4
- return JSON.parse(runtime.diagnostics());
1
+ const CANONICAL_CONTENT_PARTS_PREFIX = "[[deepstrike-content-parts:v1]]";
2
+ export function encodeCanonicalContentParts(parts) {
3
+ return `${CANONICAL_CONTENT_PARTS_PREFIX}${Buffer.from(JSON.stringify(parts)).toString("base64url")}`;
5
4
  }
6
- export function snapshotKernelRuntime(runtime) {
7
- return JSON.parse(runtime.snapshot());
8
- }
9
- export function restoreKernelRuntime(runtime, snapshot) {
10
- runtime.restore(JSON.stringify(snapshot));
11
- const operationId = snapshot.operation_id;
12
- if (!operationId) {
13
- kernelWireStates.delete(runtime);
14
- return;
5
+ function decodeCanonicalContentParts(content) {
6
+ if (!content.startsWith(CANONICAL_CONTENT_PARTS_PREFIX))
7
+ return undefined;
8
+ try {
9
+ const decoded = JSON.parse(Buffer.from(content.slice(CANONICAL_CONTENT_PARTS_PREFIX.length), "base64url").toString("utf8"));
10
+ return Array.isArray(decoded)
11
+ ? decoded.filter((part) => Boolean(part) && typeof part === "object")
12
+ : undefined;
13
+ }
14
+ catch {
15
+ return undefined;
15
16
  }
16
- const nextEventSequence = snapshot.accepted_inputs.reduce((next, input) => {
17
- const match = input.event_id.match(/-event-(\d+)$/);
18
- return match ? Math.max(next, Number(match[1]) + 1) : next;
19
- }, 1);
20
- kernelWireStates.set(runtime, { operationId, nextEventSequence });
21
17
  }
22
- const kernelWireStates = new WeakMap();
23
18
  function tryParseJson(s) {
24
19
  try {
25
20
  return JSON.parse(s);
@@ -153,9 +148,6 @@ export function capabilityCommandUnmount(capabilityKind, id) {
153
148
  command: { action: "unmount", kind: capabilityKind, id },
154
149
  };
155
150
  }
156
- function parseStep(raw) {
157
- return JSON.parse(raw);
158
- }
159
151
  /** Camel-case an `entropy_sample` kernel observation into the SDK's `EntropySample`. */
160
152
  export function entropySampleFromObservation(obs) {
161
153
  return {
@@ -169,31 +161,40 @@ export function entropySampleFromObservation(obs) {
169
161
  windowTurns: obs.window_turns ?? 0,
170
162
  };
171
163
  }
172
- function kernelMessageToSdk(raw) {
164
+ export function kernelMessageToSdk(raw) {
173
165
  const content = raw.content;
166
+ const canonicalParts = typeof content === "string"
167
+ ? decodeCanonicalContentParts(content)
168
+ : undefined;
169
+ const structuredContent = canonicalParts ?? (Array.isArray(content) ? content : undefined);
174
170
  const message = {
175
171
  role: raw.role,
176
- content: typeof content === "string"
177
- ? content
178
- : Array.isArray(content)
172
+ content: canonicalParts
173
+ ? canonicalParts
174
+ .filter(part => part.type === "text")
175
+ .map(part => String(part.text ?? ""))
176
+ .join("")
177
+ : typeof content === "string"
179
178
  ? content
180
- .filter((part) => {
181
- return typeof part === "object" && part !== null && part.type === "text";
182
- })
183
- .map(part => String(part.text ?? ""))
184
- .join("")
185
- : "",
179
+ : Array.isArray(content)
180
+ ? content
181
+ .filter((part) => {
182
+ return typeof part === "object" && part !== null && part.type === "text";
183
+ })
184
+ .map(part => String(part.text ?? ""))
185
+ .join("")
186
+ : "",
186
187
  toolCalls: (raw.tool_calls ?? []).map(tc => ({
187
- id: String(tc.id ?? ""),
188
+ id: String(tc.call_id ?? tc.id ?? ""),
188
189
  name: String(tc.name ?? ""),
189
190
  arguments: JSON.stringify(tc.arguments ?? {}),
190
191
  })),
191
192
  };
192
- if (typeof raw.token_count === "number") {
193
- message.tokenCount = raw.token_count;
193
+ if (typeof (raw.tokens ?? raw.token_count) === "number") {
194
+ message.tokenCount = Number(raw.tokens ?? raw.token_count);
194
195
  }
195
- if (Array.isArray(content)) {
196
- message.contentParts = content
196
+ if (structuredContent) {
197
+ message.contentParts = structuredContent
197
198
  .filter((part) => typeof part === "object" && part !== null)
198
199
  .map(part => {
199
200
  if (part.type === "text") {
@@ -226,9 +227,17 @@ function kernelMessageToSdk(raw) {
226
227
  return { type: "text", text: "" };
227
228
  });
228
229
  }
230
+ else if (typeof raw.tool_call_id === "string") {
231
+ message.contentParts = [{
232
+ type: "tool_result",
233
+ callId: raw.tool_call_id,
234
+ output: message.content,
235
+ isError: false,
236
+ }];
237
+ }
229
238
  return message;
230
239
  }
231
- function renderedContextToSdk(raw) {
240
+ export function renderedContextToSdk(raw) {
232
241
  const rawStateTurn = (raw.state_turn ?? raw.stateTurn);
233
242
  const frozenLen = (raw.frozen_prefix_len ?? raw.frozenPrefixLen);
234
243
  const ctx = {
@@ -243,282 +252,3 @@ function renderedContextToSdk(raw) {
243
252
  ctx.frozenPrefixLen = frozenLen;
244
253
  return ctx;
245
254
  }
246
- function mapKernelAction(raw) {
247
- const effectId = String(raw.effect_id ?? "");
248
- if (!effectId)
249
- throw new Error(`kernel action ${String(raw.kind)} is missing effect_id`);
250
- switch (raw.kind) {
251
- case "call_provider":
252
- return {
253
- kind: "call_provider",
254
- effectId,
255
- context: renderedContextToSdk(raw.context ?? {}),
256
- tools: (raw.tools ?? []).map(t => ({
257
- name: String(t.name ?? ""),
258
- description: String(t.description ?? ""),
259
- parameters: JSON.stringify(t.parameters ?? {}),
260
- })),
261
- };
262
- case "execute_tool":
263
- return {
264
- kind: "execute_tool",
265
- effectId,
266
- calls: (raw.calls ?? []).map(c => ({
267
- id: String(c.id ?? ""),
268
- name: String(c.name ?? ""),
269
- arguments: JSON.stringify(c.arguments ?? {}),
270
- })),
271
- };
272
- case "request_approval":
273
- return {
274
- kind: "request_approval",
275
- effectId,
276
- requests: (raw.requests ?? []).map(request => ({
277
- callId: String(request.call_id ?? ""),
278
- tool: String(request.tool ?? ""),
279
- arguments: JSON.stringify(request.arguments ?? {}),
280
- reason: String(request.reason ?? ""),
281
- })),
282
- };
283
- case "spawn_workflow":
284
- return {
285
- kind: "spawn_workflow",
286
- effectId,
287
- nodes: raw.nodes ?? [],
288
- ...(raw.budget && typeof raw.budget === "object"
289
- ? { budget: raw.budget }
290
- : {}),
291
- };
292
- case "preempt_sub_agents":
293
- return {
294
- kind: "preempt_sub_agents",
295
- effectId,
296
- agentIds: raw.agent_ids ?? [],
297
- reason: String(raw.reason ?? ""),
298
- };
299
- case "persist_memory":
300
- return {
301
- kind: "persist_memory",
302
- effectId,
303
- memory: raw.memory ?? {},
304
- };
305
- case "query_memory":
306
- return {
307
- kind: "query_memory",
308
- effectId,
309
- query: raw.query ?? {},
310
- requestedK: Number(raw.requested_k ?? 0),
311
- };
312
- case "spool_large_result":
313
- return {
314
- kind: "spool_large_result",
315
- effectId,
316
- callId: String(raw.call_id ?? ""),
317
- tool: String(raw.tool ?? ""),
318
- output: String(raw.output ?? ""),
319
- originalSize: Number(raw.original_size ?? 0),
320
- previewSize: Number(raw.preview_size ?? 0),
321
- };
322
- case "archive_page_out":
323
- return {
324
- kind: "archive_page_out",
325
- effectId,
326
- turn: Number(raw.turn ?? 0),
327
- action: String(raw.action ?? "auto_compact"),
328
- ...(typeof raw.summary === "string" ? { summary: raw.summary } : {}),
329
- archived: (raw.archived ?? []).map(kernelMessageToSdk),
330
- tier: String(raw.tier ?? "durable"),
331
- };
332
- case "evaluate_milestone":
333
- return {
334
- kind: "evaluate_milestone",
335
- effectId,
336
- phaseId: String(raw.phase_id ?? ""),
337
- criteria: raw.criteria ?? [],
338
- verifier: raw.verifier,
339
- requiredEvidence: raw.required_evidence ?? [],
340
- };
341
- case "done": {
342
- const result = raw.result ?? {};
343
- const pace = result.pace_decision;
344
- return {
345
- kind: "done",
346
- effectId,
347
- result: {
348
- termination: String(result.termination ?? "error"),
349
- turnsUsed: Number(result.turns_used ?? 0),
350
- totalTokensUsed: Number(result.total_tokens_used ?? 0),
351
- // ③ loop-agent: the kernel-adjudicated after-round decision (absent on non-loop runs).
352
- ...(pace
353
- ? {
354
- paceDecision: {
355
- action: (pace.action ?? "stop"),
356
- delayMs: pace.delay_ms,
357
- reason: pace.reason ?? "",
358
- coercedFrom: pace.coerced_from,
359
- },
360
- }
361
- : {}),
362
- },
363
- };
364
- }
365
- default:
366
- throw new Error(`unknown KernelAction kind: ${String(raw.kind)}`);
367
- }
368
- }
369
- function stepInput(runtime, event) {
370
- let state = kernelWireStates.get(runtime);
371
- if (!state) {
372
- // Globally unique, never a process-local counter: durable session logs key the kernel
373
- // genesis/transaction chains by (sessionId, operationId) and outlive this process, so a
374
- // counter that restarts at 1 collides with yesterday's chain on the same session (genesis
375
- // digest conflict, or step_seq successor violation when the policy digest happens to match).
376
- state = {
377
- operationId: `node-operation-${crypto.randomUUID()}`,
378
- nextEventSequence: 1,
379
- };
380
- kernelWireStates.set(runtime, state);
381
- }
382
- const correlatedEvent = event.kind === "cancel_operation"
383
- ? { ...event, operation_id: state.operationId }
384
- : event;
385
- return JSON.stringify({
386
- version: KERNEL_ABI_VERSION,
387
- operation_id: state.operationId,
388
- event_id: `${state.operationId}-event-${state.nextEventSequence++}`,
389
- observed_at_ms: Date.now(),
390
- event: correlatedEvent,
391
- });
392
- }
393
- const durableKernelStates = new WeakMap();
394
- /**
395
- * Execute one production transition behind the durable action-publish gate. Genesis is persisted
396
- * before prepare; a newly prepared transaction is CAS-appended before commit; only the committed
397
- * step is returned to callers, so actions and observations cannot escape early.
398
- */
399
- export async function durableKernelStep(runtime, sessionLog, sessionId, event) {
400
- const inputJson = stepInput(runtime, event);
401
- const input = JSON.parse(inputJson);
402
- const operationId = String(input.operation_id ?? "");
403
- if (!operationId)
404
- throw new Error("kernel input is missing operation_id");
405
- let durableState = durableKernelStates.get(runtime);
406
- if (!durableState) {
407
- const snapshot = snapshotKernelRuntime(runtime);
408
- const genesis = await createKernelOperationGenesis({
409
- abi_version: KERNEL_ABI_VERSION,
410
- operation_id: operationId,
411
- initial_scheduler_policy: snapshot.initial_policy,
412
- resolved_runtime_defaults: {
413
- snapshot_version: snapshot.snapshot_version,
414
- snapshot_input_limit: snapshot.snapshot_input_limit,
415
- max_input_bytes: snapshot.max_input_bytes,
416
- snapshot_journal_bytes_limit: snapshot.snapshot_journal_bytes_limit,
417
- },
418
- default_policy_version: 1,
419
- });
420
- const receipt = await sessionLog.appendKernelGenesis(sessionId, genesis);
421
- durableState = {
422
- sessionId,
423
- operationId,
424
- genesisDigest: receipt.genesis_digest,
425
- };
426
- durableKernelStates.set(runtime, durableState);
427
- }
428
- else if (durableState.sessionId !== sessionId || durableState.operationId !== operationId) {
429
- throw new Error("kernel runtime cannot change its durable session or operation identity");
430
- }
431
- const prepared = JSON.parse(runtime.prepareStep(inputJson));
432
- if (prepared.status !== "prepared")
433
- return prepared.step;
434
- const token = prepared.prepare_token;
435
- if (!token)
436
- throw new Error("prepared kernel transition is missing its commit token");
437
- let committed = false;
438
- try {
439
- const head = await sessionLog.kernelTransactionHead(sessionId, operationId);
440
- if (!head)
441
- throw new Error("durable kernel genesis is missing before transaction append");
442
- const transaction = await createKernelTransaction({
443
- operation_id: operationId,
444
- step_seq: prepared.step.step_seq,
445
- base_generation: prepared.base_generation,
446
- input: prepared.input,
447
- step: prepared.step,
448
- previous_transaction_digest: head,
449
- });
450
- await sessionLog.compareAndAppendKernelTransaction(sessionId, head, transaction);
451
- const committedStep = parseStep(runtime.commitPrepared(token));
452
- committed = true;
453
- if (kernelRecordDigest(committedStep) !== transaction.step_digest) {
454
- throw new Error("committed kernel step does not match the durable prepared step");
455
- }
456
- return committedStep;
457
- }
458
- catch (transitionError) {
459
- if (!committed) {
460
- try {
461
- runtime.abortPrepared(token);
462
- }
463
- catch (abortError) {
464
- throw new AggregateError([transitionError, abortError], "durable transition failed and the prepared kernel state could not be aborted");
465
- }
466
- }
467
- throw transitionError;
468
- }
469
- }
470
- export async function durableKernelApply(runtime, sessionLog, sessionId, pending, event) {
471
- const step = await durableKernelStep(runtime, sessionLog, sessionId, event);
472
- const fault = step.faults?.[0];
473
- if (fault)
474
- throw new Error(`${fault.code ?? "kernel_fault"}: ${fault.message ?? "kernel transition failed"}`);
475
- pending.push(...step.observations);
476
- return step.observations;
477
- }
478
- export async function durableKernelMaybeAction(runtime, sessionLog, sessionId, pending, event) {
479
- const step = await durableKernelStep(runtime, sessionLog, sessionId, event);
480
- const fault = step.faults?.[0];
481
- if (fault)
482
- throw new Error(`${fault.code ?? "kernel_fault"}: ${fault.message ?? "kernel transition failed"}`);
483
- pending.push(...step.observations);
484
- const raw = step.actions[0];
485
- return raw ? mapKernelAction(raw) : null;
486
- }
487
- export async function durableKernelAction(runtime, sessionLog, sessionId, pending, event) {
488
- const action = await durableKernelMaybeAction(runtime, sessionLog, sessionId, pending, event);
489
- if (!action)
490
- throw new Error("kernel transition must return one action");
491
- return action;
492
- }
493
- export function kernelApply(runtime, pending, event) {
494
- const step = kernelStep(runtime, event);
495
- const fault = step.faults?.[0];
496
- if (fault)
497
- throw new Error(`${fault.code ?? "kernel_fault"}: ${fault.message ?? "kernel transition failed"}`);
498
- pending.push(...step.observations);
499
- return step.observations;
500
- }
501
- export function kernelAction(runtime, pending, event) {
502
- const action = kernelMaybeAction(runtime, pending, event);
503
- if (!action)
504
- throw new Error("kernel transition must return one action");
505
- return action;
506
- }
507
- /**
508
- * Like {@link kernelAction} but tolerates a zero-action step. Used for events
509
- * whose outcome may not drive a provider call — e.g. a signal the kernel queues
510
- * or ignores returns no action. Returns `null` in that case.
511
- */
512
- export function kernelMaybeAction(runtime, pending, event) {
513
- const step = kernelStep(runtime, event);
514
- const fault = step.faults?.[0];
515
- if (fault)
516
- throw new Error(`${fault.code ?? "kernel_fault"}: ${fault.message ?? "kernel transition failed"}`);
517
- pending.push(...step.observations);
518
- const raw = step.actions[0];
519
- return raw ? mapKernelAction(raw) : null;
520
- }
521
- /** Internal ABI-v2 step primitive shared by SDK adapters and conformance tests. */
522
- export function kernelStep(runtime, event) {
523
- return parseStep(runtime.step(stepInput(runtime, event)));
524
- }
@@ -9,7 +9,8 @@ export interface OsSnapshot {
9
9
  processByAgent: Array<{
10
10
  turn: number;
11
11
  agent_id: string;
12
- parent_session_id: string;
12
+ parent_task_id?: string;
13
+ parent_session_id?: string;
13
14
  state: string;
14
15
  }>;
15
16
  budgetExceeded: Array<{
@@ -43,7 +44,6 @@ export interface OsSnapshot {
43
44
  }>;
44
45
  pageOutCount: number;
45
46
  pageInCount: number;
46
- spoolCount: number;
47
47
  toolGatedCount: number;
48
48
  memoryWrittenCount: number;
49
49
  memoryQueriedCount: number;