@deepstrike/sdk 0.2.49 → 0.2.51
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/README.md +83 -60
- package/dist/harness/manifest.d.ts +1 -1
- package/dist/harness/manifest.js +43 -29
- package/dist/index.d.ts +5 -7
- package/dist/index.js +3 -3
- package/dist/kernel.d.ts +61 -31
- package/dist/runtime/canonical-kernel-step.d.ts +143 -0
- package/dist/runtime/canonical-kernel-step.js +1444 -0
- package/dist/runtime/execution-plane.d.ts +0 -3
- package/dist/runtime/execution-plane.js +0 -24
- package/dist/runtime/facade.js +3 -0
- package/dist/runtime/kernel-event-log.js +7 -13
- package/dist/runtime/kernel-journal.d.ts +264 -0
- package/dist/runtime/kernel-journal.js +741 -0
- package/dist/runtime/kernel-primitives-dashboard.d.ts +0 -2
- package/dist/runtime/kernel-primitives-dashboard.js +1 -8
- package/dist/runtime/kernel-step.d.ts +29 -109
- package/dist/runtime/kernel-step.js +47 -317
- package/dist/runtime/os-snapshot.d.ts +2 -2
- package/dist/runtime/os-snapshot.js +2 -6
- package/dist/runtime/payload-store.d.ts +16 -0
- package/dist/runtime/payload-store.js +80 -0
- package/dist/runtime/runner.d.ts +80 -119
- package/dist/runtime/runner.js +706 -779
- package/dist/runtime/session-log.d.ts +34 -32
- package/dist/runtime/session-log.js +21 -131
- package/dist/runtime/session-repair.d.ts +2 -36
- package/dist/runtime/session-repair.js +2 -47
- package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
- package/dist/runtime/sub-agent-orchestrator.js +42 -40
- package/dist/types/agent.d.ts +31 -19
- package/dist/types/agent.js +31 -42
- package/dist/workflow/public.d.ts +1 -1
- package/dist/workflow/public.js +1 -1
- package/package.json +2 -2
- package/dist/runtime/kernel-rebuild.d.ts +0 -13
- package/dist/runtime/kernel-rebuild.js +0 -75
- package/dist/runtime/kernel-transaction-log.d.ts +0 -61
- package/dist/runtime/kernel-transaction-log.js +0 -149
- package/dist/runtime/large-result-spool.d.ts +0 -93
- package/dist/runtime/large-result-spool.js +0 -214
|
@@ -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(
|
|
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
|
-
|
|
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
|
|
142
|
-
action
|
|
76
|
+
turn?: number;
|
|
77
|
+
action?: string;
|
|
143
78
|
summary?: string;
|
|
144
|
-
archived
|
|
145
|
-
tier
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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:
|
|
177
|
-
?
|
|
178
|
-
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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 (
|
|
196
|
-
message.contentParts =
|
|
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
|
-
|
|
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;
|