@deepstrike/wasm 0.2.50 → 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.
Files changed (37) hide show
  1. package/README.md +2 -1
  2. package/dist/index.d.ts +4 -3
  3. package/dist/index.js +3 -2
  4. package/dist/runtime/canonical-kernel-step.d.ts +146 -0
  5. package/dist/runtime/canonical-kernel-step.js +1484 -0
  6. package/dist/runtime/execution-plane.d.ts +0 -3
  7. package/dist/runtime/execution-plane.js +0 -25
  8. package/dist/runtime/facade.js +3 -0
  9. package/dist/runtime/index.d.ts +7 -7
  10. package/dist/runtime/index.js +4 -3
  11. package/dist/runtime/kernel-event-log.d.ts +0 -1
  12. package/dist/runtime/kernel-event-log.js +7 -13
  13. package/dist/runtime/kernel-journal.d.ts +332 -0
  14. package/dist/runtime/kernel-journal.js +681 -0
  15. package/dist/runtime/kernel-step.d.ts +34 -89
  16. package/dist/runtime/kernel-step.js +67 -167
  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 +30 -0
  20. package/dist/runtime/payload-store.js +66 -0
  21. package/dist/runtime/runner.d.ts +27 -75
  22. package/dist/runtime/runner.js +408 -632
  23. package/dist/runtime/session-log.d.ts +24 -27
  24. package/dist/runtime/session-log.js +11 -52
  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 +2 -2
  28. package/dist/runtime/sub-agent-orchestrator.js +36 -40
  29. package/dist/runtime/types/agent.d.ts +13 -16
  30. package/dist/runtime/types/agent.js +16 -41
  31. package/package.json +4 -3
  32. package/dist/runtime/kernel-rebuild.d.ts +0 -8
  33. package/dist/runtime/kernel-rebuild.js +0 -65
  34. package/dist/runtime/kernel-transaction-log.d.ts +0 -61
  35. package/dist/runtime/kernel-transaction-log.js +0 -140
  36. package/dist/runtime/large-result-spool.d.ts +0 -57
  37. package/dist/runtime/large-result-spool.js +0 -169
@@ -1,61 +0,0 @@
1
- export declare const KERNEL_LOG_RECORD_VERSION: 1;
2
- export interface KernelOperationGenesisBody {
3
- record_version: typeof KERNEL_LOG_RECORD_VERSION;
4
- abi_version: number;
5
- operation_id: string;
6
- initial_scheduler_policy: Record<string, unknown>;
7
- resolved_runtime_defaults: Record<string, unknown>;
8
- default_policy_version: number;
9
- }
10
- export interface KernelOperationGenesis extends KernelOperationGenesisBody {
11
- genesis_digest: string;
12
- }
13
- export interface KernelTransactionBody {
14
- record_version: typeof KERNEL_LOG_RECORD_VERSION;
15
- operation_id: string;
16
- step_seq: number;
17
- base_generation: number;
18
- input: Record<string, unknown>;
19
- input_digest: string;
20
- previous_transaction_digest: string;
21
- step_digest: string;
22
- }
23
- export interface KernelTransaction extends KernelTransactionBody {
24
- transaction_digest: string;
25
- }
26
- export interface KernelGenesisReceipt {
27
- log_seq: number;
28
- genesis_digest: string;
29
- }
30
- export interface DurableAppendReceipt {
31
- log_seq: number;
32
- transaction_digest: string;
33
- }
34
- export interface KernelOperationCursor {
35
- operation_id: string;
36
- next_event_sequence: number;
37
- next_step_seq: number;
38
- transaction_head_digest: string;
39
- }
40
- export declare class KernelLogConflictError extends Error {
41
- constructor(message: string);
42
- }
43
- export declare class KernelLogIntegrityError extends Error {
44
- constructor(message: string);
45
- }
46
- export declare function canonicalKernelJson(value: unknown): string;
47
- export declare function kernelRecordDigest(value: unknown): Promise<string>;
48
- export declare function createKernelOperationGenesis(input: Omit<KernelOperationGenesisBody, "record_version">): Promise<KernelOperationGenesis>;
49
- export declare function createKernelTransaction(input: {
50
- operation_id: string;
51
- step_seq: number;
52
- base_generation: number;
53
- input: Record<string, unknown>;
54
- step: Record<string, unknown>;
55
- previous_transaction_digest: string;
56
- }): Promise<KernelTransaction>;
57
- export declare function verifyKernelOperationGenesis(genesis: KernelOperationGenesis): Promise<void>;
58
- export declare function verifyKernelTransaction(transaction: KernelTransaction): Promise<void>;
59
- export declare function verifyKernelTransactionSuccessor(previous: KernelTransaction | undefined, transaction: KernelTransaction): void;
60
- /** Validate one complete authoritative operation stream and derive its next wire cursor. */
61
- export declare function verifyKernelTransactionStream(genesis: KernelOperationGenesis, transactions: readonly KernelTransaction[]): Promise<KernelOperationCursor>;
@@ -1,140 +0,0 @@
1
- export const KERNEL_LOG_RECORD_VERSION = 1;
2
- export class KernelLogConflictError extends Error {
3
- constructor(message) {
4
- super(message);
5
- this.name = "KernelLogConflictError";
6
- }
7
- }
8
- export class KernelLogIntegrityError extends Error {
9
- constructor(message) {
10
- super(message);
11
- this.name = "KernelLogIntegrityError";
12
- }
13
- }
14
- export function canonicalKernelJson(value) {
15
- if (value === null)
16
- return "null";
17
- if (typeof value === "string" || typeof value === "boolean")
18
- return JSON.stringify(value);
19
- if (typeof value === "number") {
20
- if (!Number.isFinite(value))
21
- throw new KernelLogIntegrityError("canonical records require finite numbers");
22
- if (Number.isSafeInteger(value))
23
- return JSON.stringify(Object.is(value, -0) ? 0 : value);
24
- if (Number.isInteger(value)) {
25
- throw new KernelLogIntegrityError("canonical record integer exceeds the cross-SDK safe range");
26
- }
27
- const bytes = new Uint8Array(8);
28
- new DataView(bytes.buffer).setFloat64(0, value, false);
29
- return `f64:${Array.from(bytes, byte => byte.toString(16).padStart(2, "0")).join("")}`;
30
- }
31
- if (Array.isArray(value))
32
- return `[${value.map(canonicalKernelJson).join(",")}]`;
33
- if (typeof value === "object") {
34
- const object = value;
35
- const keys = Object.keys(object).sort();
36
- return `{${keys.map(key => `${JSON.stringify(key)}:${canonicalKernelJson(object[key])}`).join(",")}}`;
37
- }
38
- throw new KernelLogIntegrityError(`unsupported canonical record value: ${typeof value}`);
39
- }
40
- export async function kernelRecordDigest(value) {
41
- const bytes = new TextEncoder().encode(canonicalKernelJson(value));
42
- const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
43
- return Array.from(new Uint8Array(digest), byte => byte.toString(16).padStart(2, "0")).join("");
44
- }
45
- export async function createKernelOperationGenesis(input) {
46
- const body = { record_version: KERNEL_LOG_RECORD_VERSION, ...input };
47
- validateGenesisBody(body);
48
- return { ...body, genesis_digest: await kernelRecordDigest(body) };
49
- }
50
- export async function createKernelTransaction(input) {
51
- const body = {
52
- record_version: KERNEL_LOG_RECORD_VERSION,
53
- operation_id: input.operation_id,
54
- step_seq: input.step_seq,
55
- base_generation: input.base_generation,
56
- input: input.input,
57
- input_digest: await kernelRecordDigest(input.input),
58
- previous_transaction_digest: input.previous_transaction_digest,
59
- step_digest: await kernelRecordDigest(input.step),
60
- };
61
- validateTransactionBody(body);
62
- return { ...body, transaction_digest: await kernelRecordDigest(body) };
63
- }
64
- export async function verifyKernelOperationGenesis(genesis) {
65
- const { genesis_digest, ...body } = genesis;
66
- validateGenesisBody(body);
67
- if (await kernelRecordDigest(body) !== genesis_digest) {
68
- throw new KernelLogIntegrityError("kernel genesis digest does not match its canonical body");
69
- }
70
- }
71
- export async function verifyKernelTransaction(transaction) {
72
- const { transaction_digest, ...body } = transaction;
73
- validateTransactionBody(body);
74
- if (await kernelRecordDigest(body.input) !== body.input_digest) {
75
- throw new KernelLogIntegrityError("kernel transaction input digest does not match its input");
76
- }
77
- if (await kernelRecordDigest(body) !== transaction_digest) {
78
- throw new KernelLogIntegrityError("kernel transaction digest does not match its canonical body");
79
- }
80
- }
81
- export function verifyKernelTransactionSuccessor(previous, transaction) {
82
- const expectedStepSeq = previous ? previous.step_seq + 1 : 1;
83
- const expectedGeneration = previous ? previous.base_generation + 1 : 0;
84
- if (transaction.step_seq !== expectedStepSeq) {
85
- throw new KernelLogIntegrityError(`kernel transaction step_seq ${transaction.step_seq} does not follow ${expectedStepSeq - 1}`);
86
- }
87
- if (transaction.base_generation !== expectedGeneration) {
88
- throw new KernelLogIntegrityError(`kernel transaction base_generation ${transaction.base_generation} does not match ${expectedGeneration}`);
89
- }
90
- if (transaction.input.operation_id !== transaction.operation_id) {
91
- throw new KernelLogIntegrityError("kernel transaction input operation_id does not match its envelope");
92
- }
93
- }
94
- /** Validate one complete authoritative operation stream and derive its next wire cursor. */
95
- export async function verifyKernelTransactionStream(genesis, transactions) {
96
- await verifyKernelOperationGenesis(genesis);
97
- let previous;
98
- let head = genesis.genesis_digest;
99
- for (const transaction of transactions) {
100
- await verifyKernelTransaction(transaction);
101
- if (transaction.operation_id !== genesis.operation_id) {
102
- throw new KernelLogIntegrityError("kernel transaction operation_id does not match genesis");
103
- }
104
- if (transaction.previous_transaction_digest !== head) {
105
- throw new KernelLogIntegrityError("kernel transaction digest chain is not continuous");
106
- }
107
- verifyKernelTransactionSuccessor(previous, transaction);
108
- previous = transaction;
109
- head = transaction.transaction_digest;
110
- }
111
- const nextSequence = (previous?.step_seq ?? 0) + 1;
112
- return {
113
- operation_id: genesis.operation_id,
114
- next_event_sequence: nextSequence,
115
- next_step_seq: nextSequence,
116
- transaction_head_digest: head,
117
- };
118
- }
119
- function validateGenesisBody(genesis) {
120
- if (genesis.record_version !== KERNEL_LOG_RECORD_VERSION)
121
- throw new KernelLogIntegrityError("unsupported kernel genesis record version");
122
- if (!Number.isSafeInteger(genesis.abi_version) || genesis.abi_version <= 0)
123
- throw new KernelLogIntegrityError("kernel genesis abi_version must be a positive safe integer");
124
- if (!genesis.operation_id)
125
- throw new KernelLogIntegrityError("kernel genesis operation_id is required");
126
- if (!Number.isSafeInteger(genesis.default_policy_version) || genesis.default_policy_version <= 0)
127
- throw new KernelLogIntegrityError("kernel genesis default_policy_version must be a positive safe integer");
128
- }
129
- function validateTransactionBody(transaction) {
130
- if (transaction.record_version !== KERNEL_LOG_RECORD_VERSION)
131
- throw new KernelLogIntegrityError("unsupported kernel transaction record version");
132
- if (!transaction.operation_id)
133
- throw new KernelLogIntegrityError("kernel transaction operation_id is required");
134
- if (!Number.isSafeInteger(transaction.step_seq) || transaction.step_seq <= 0)
135
- throw new KernelLogIntegrityError("kernel transaction step_seq must be a positive safe integer");
136
- if (!Number.isSafeInteger(transaction.base_generation) || transaction.base_generation < 0)
137
- throw new KernelLogIntegrityError("kernel transaction base_generation must be a non-negative safe integer");
138
- if (!transaction.previous_transaction_digest)
139
- throw new KernelLogIntegrityError("kernel transaction previous_transaction_digest is required");
140
- }
@@ -1,57 +0,0 @@
1
- export interface ToolResult {
2
- callId: string;
3
- tool: string;
4
- output: string;
5
- isError?: boolean;
6
- }
7
- export interface SpooledToolResult {
8
- originalOutput: string;
9
- preview: string;
10
- spoolRef: string;
11
- wasSpooled: boolean;
12
- }
13
- export interface SpoolConfig {
14
- spoolThresholdBytes: number;
15
- previewTokens: number;
16
- totalMessageLimitBytes: number;
17
- maxAgeMs?: number;
18
- driver?: SpoolStorageDriver;
19
- }
20
- export interface SpoolStorageDriver {
21
- write(key: string, content: string): Promise<void> | void;
22
- read(key: string): Promise<string> | string;
23
- delete(key: string): Promise<void> | void;
24
- list(): Promise<string[]> | string[];
25
- mtime?(key: string): Promise<number> | number;
26
- }
27
- export declare class MemorySpoolDriver implements SpoolStorageDriver {
28
- private cache;
29
- write(key: string, content: string): Promise<void>;
30
- read(key: string): Promise<string>;
31
- delete(key: string): Promise<void>;
32
- list(): Promise<string[]>;
33
- mtime(key: string): Promise<number>;
34
- }
35
- export declare const DEFAULT_SPOOL_CONFIG: SpoolConfig;
36
- export declare class LargeResultSpool {
37
- private config;
38
- private driver;
39
- private activeWrites;
40
- constructor(config?: Partial<SpoolConfig>);
41
- private needsSpool;
42
- private getSpoolKey;
43
- private writeToDriver;
44
- private generatePreview;
45
- processToolResult(result: ToolResult): Promise<SpooledToolResult>;
46
- private callKey;
47
- persistOutput(sessionId: string, callId: string, content: string): Promise<string>;
48
- readSpooledResult(spoolRef: string): Promise<string>;
49
- /**
50
- * O7: locate a spooled output by the tool call's id (the `read_result` meta-tool only knows
51
- * `call_id`, not the content-hashed key `persistOutput` chose). Scans the driver's key list for
52
- * the hashed session-scoped call-key prefix; returns `undefined` if nothing was ever
53
- * spooled for that call.
54
- */
55
- findByCallId(sessionId: string, callId: string): Promise<string | undefined>;
56
- cleanup(maxAgeMs?: number): Promise<number>;
57
- }
@@ -1,169 +0,0 @@
1
- export class MemorySpoolDriver {
2
- cache = new Map();
3
- async write(key, content) {
4
- this.cache.set(key, { content, mtime: Date.now() });
5
- }
6
- async read(key) {
7
- const val = this.cache.get(key);
8
- if (!val)
9
- throw new Error(`Spooled result not found: ${key}`);
10
- return val.content;
11
- }
12
- async delete(key) {
13
- this.cache.delete(key);
14
- }
15
- async list() {
16
- return Array.from(this.cache.keys());
17
- }
18
- async mtime(key) {
19
- return this.cache.get(key)?.mtime ?? 0;
20
- }
21
- }
22
- export const DEFAULT_SPOOL_CONFIG = {
23
- spoolThresholdBytes: 50 * 1024, // 50KB
24
- previewTokens: 500, // ~2KB
25
- totalMessageLimitBytes: 200 * 1024, // 200KB
26
- };
27
- function simpleHash(content) {
28
- let hash = 5381;
29
- for (let i = 0; i < content.length; i++) {
30
- hash = (hash * 33) ^ content.charCodeAt(i);
31
- }
32
- return (hash >>> 0).toString(16);
33
- }
34
- export class LargeResultSpool {
35
- config;
36
- driver;
37
- activeWrites = new Map();
38
- constructor(config = {}) {
39
- this.config = { ...DEFAULT_SPOOL_CONFIG, ...config };
40
- this.driver = this.config.driver ?? new MemorySpoolDriver();
41
- }
42
- needsSpool(result) {
43
- return result.output.length > this.config.spoolThresholdBytes;
44
- }
45
- getSpoolKey(hash) {
46
- return `.spool/${hash}.txt`;
47
- }
48
- async writeToDriver(content, hash) {
49
- const key = this.getSpoolKey(hash);
50
- let promise = this.activeWrites.get(key);
51
- if (!promise) {
52
- promise = (async () => {
53
- try {
54
- await this.driver.write(key, content);
55
- return key;
56
- }
57
- finally {
58
- this.activeWrites.delete(key);
59
- }
60
- })();
61
- this.activeWrites.set(key, promise);
62
- }
63
- return promise;
64
- }
65
- generatePreview(content) {
66
- const previewTokens = Math.min(this.config.previewTokens, content.length / 4);
67
- const preview = content.substring(0, previewTokens);
68
- const omitted = content.length - previewTokens;
69
- return `[tool_result_spooled]
70
- size: ${content.length} bytes
71
- preview: first ${previewTokens} chars
72
- omitted: ${omitted} chars
73
- [full content available via Read tool]
74
- `;
75
- }
76
- async processToolResult(result) {
77
- if (!this.needsSpool(result)) {
78
- return {
79
- originalOutput: result.output,
80
- preview: result.output,
81
- spoolRef: "",
82
- wasSpooled: false,
83
- };
84
- }
85
- const hash = simpleHash(result.output);
86
- const spoolRef = await this.writeToDriver(result.output, hash);
87
- const preview = this.generatePreview(result.output);
88
- return {
89
- originalOutput: result.output,
90
- preview,
91
- spoolRef,
92
- wasSpooled: true,
93
- };
94
- }
95
- callKey(sessionId, callId) {
96
- // Session-scoped and hashed: the driver's key space is shared across sessions and outlives
97
- // runs, while vendor call ids can be index-style ("call_0") and repeat — an unscoped key
98
- // lets read_result in one session fetch another session's spooled output. Hashing also keeps
99
- // untrusted call-id characters out of driver keys (parity with Node/Python).
100
- return simpleHash(`${sessionId}\u0000${callId}`);
101
- }
102
- async persistOutput(sessionId, callId, content) {
103
- const hash = simpleHash(content);
104
- const key = `.spool/${this.callKey(sessionId, callId)}-${hash.slice(0, 16)}.txt`;
105
- let promise = this.activeWrites.get(key);
106
- if (!promise) {
107
- promise = (async () => {
108
- try {
109
- await this.driver.write(key, content);
110
- return key;
111
- }
112
- finally {
113
- this.activeWrites.delete(key);
114
- }
115
- })();
116
- this.activeWrites.set(key, promise);
117
- }
118
- return promise;
119
- }
120
- async readSpooledResult(spoolRef) {
121
- return this.driver.read(spoolRef);
122
- }
123
- /**
124
- * O7: locate a spooled output by the tool call's id (the `read_result` meta-tool only knows
125
- * `call_id`, not the content-hashed key `persistOutput` chose). Scans the driver's key list for
126
- * the hashed session-scoped call-key prefix; returns `undefined` if nothing was ever
127
- * spooled for that call.
128
- */
129
- async findByCallId(sessionId, callId) {
130
- let keys;
131
- try {
132
- keys = await this.driver.list();
133
- }
134
- catch {
135
- return undefined;
136
- }
137
- const prefix = `.spool/${this.callKey(sessionId, callId)}-`;
138
- const match = keys.find(k => k.startsWith(prefix) && k.endsWith('.txt'));
139
- if (!match)
140
- return undefined;
141
- try {
142
- return await this.driver.read(match);
143
- }
144
- catch {
145
- return undefined;
146
- }
147
- }
148
- async cleanup(maxAgeMs) {
149
- const limit = maxAgeMs ?? this.config.maxAgeMs ?? 7 * 24 * 60 * 60 * 1000;
150
- try {
151
- const keys = await this.driver.list();
152
- let count = 0;
153
- const now = Date.now();
154
- for (const key of keys) {
155
- if (this.driver.mtime) {
156
- const mtime = await this.driver.mtime(key);
157
- if (now - mtime > limit) {
158
- await this.driver.delete(key);
159
- count++;
160
- }
161
- }
162
- }
163
- return count;
164
- }
165
- catch {
166
- return 0;
167
- }
168
- }
169
- }