@deepstrike/wasm 0.2.39 → 0.2.40
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 +14 -13
- package/dist/harness/index.d.ts +127 -61
- package/dist/harness/index.js +212 -83
- package/dist/index.d.ts +9 -6
- package/dist/index.js +4 -2
- package/dist/memory/extraction.d.ts +4 -0
- package/dist/memory/extraction.js +48 -0
- package/dist/memory/in-memory-store.d.ts +19 -9
- package/dist/memory/in-memory-store.js +68 -23
- package/dist/memory/index.d.ts +52 -24
- package/dist/memory/ranking.d.ts +33 -0
- package/dist/memory/ranking.js +77 -0
- package/dist/memory/retention.d.ts +17 -0
- package/dist/memory/retention.js +54 -0
- package/dist/providers/base.d.ts +5 -0
- package/dist/providers/base.js +32 -0
- package/dist/runtime/context-policy.d.ts +35 -0
- package/dist/runtime/context-policy.js +66 -0
- package/dist/runtime/eval.d.ts +2 -0
- package/dist/runtime/execution-plane.d.ts +2 -1
- package/dist/runtime/execution-plane.js +3 -3
- package/dist/runtime/facade.js +2 -1
- package/dist/runtime/index.d.ts +11 -4
- package/dist/runtime/index.js +5 -1
- package/dist/runtime/kernel-event-log.js +46 -13
- package/dist/runtime/kernel-rebuild.d.ts +8 -0
- package/dist/runtime/kernel-rebuild.js +65 -0
- package/dist/runtime/kernel-step.d.ts +139 -7
- package/dist/runtime/kernel-step.js +110 -10
- package/dist/runtime/kernel-transaction-log.d.ts +61 -0
- package/dist/runtime/kernel-transaction-log.js +140 -0
- package/dist/runtime/os-profile.d.ts +9 -10
- package/dist/runtime/os-profile.js +14 -10
- package/dist/runtime/os-snapshot.d.ts +19 -0
- package/dist/runtime/os-snapshot.js +16 -3
- package/dist/runtime/runner.d.ts +73 -41
- package/dist/runtime/runner.js +562 -290
- package/dist/runtime/session-log.d.ts +55 -10
- package/dist/runtime/session-log.js +60 -3
- package/dist/runtime/session-repair.d.ts +11 -7
- package/dist/runtime/session-repair.js +11 -8
- package/dist/runtime/sub-agent-orchestrator.js +1 -1
- package/dist/runtime/types/agent.d.ts +31 -0
- package/dist/runtime/types/agent.js +35 -0
- package/dist/signals/index.d.ts +21 -1
- package/dist/signals/index.js +1 -0
- package/dist/types.d.ts +7 -2
- package/package.json +2 -2
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { ProviderReplay, ToolCall, ToolErrorKind } from "../types.js";
|
|
2
|
+
import type { MemoryRecall, MemoryScope } from "../memory/index.js";
|
|
2
3
|
import type { KernelPrimitive } from "./kernel-event-log.js";
|
|
4
|
+
import type { DurableAppendReceipt, KernelGenesisReceipt, KernelOperationGenesis, KernelTransaction } from "./kernel-transaction-log.js";
|
|
5
|
+
export interface KernelTransactionEntry {
|
|
6
|
+
log_seq: number;
|
|
7
|
+
transaction: KernelTransaction;
|
|
8
|
+
}
|
|
3
9
|
export type RollbackReason = {
|
|
4
10
|
kind: "fatal_tool_error";
|
|
5
11
|
tool_name: string;
|
|
@@ -26,6 +32,7 @@ export type SessionEvent = {
|
|
|
26
32
|
criteria: string[];
|
|
27
33
|
agent_id?: string;
|
|
28
34
|
system_prompt?: string;
|
|
35
|
+
attachments?: import("../types.js").ContentPart[];
|
|
29
36
|
} | {
|
|
30
37
|
kind: "llm_completed";
|
|
31
38
|
turn: number;
|
|
@@ -78,7 +85,6 @@ export type SessionEvent = {
|
|
|
78
85
|
action?: "snip_compact" | "micro_compact" | "context_collapse" | "auto_compact";
|
|
79
86
|
summary?: string;
|
|
80
87
|
summary_tokens?: number;
|
|
81
|
-
archive_ref?: string;
|
|
82
88
|
preserved_refs?: string[];
|
|
83
89
|
} | {
|
|
84
90
|
kind: "page_out";
|
|
@@ -87,6 +93,7 @@ export type SessionEvent = {
|
|
|
87
93
|
summary?: string;
|
|
88
94
|
tier_hint?: string;
|
|
89
95
|
message_count?: number;
|
|
96
|
+
archive_ref?: string;
|
|
90
97
|
} | {
|
|
91
98
|
kind: "page_in";
|
|
92
99
|
turn: number;
|
|
@@ -136,15 +143,34 @@ export type SessionEvent = {
|
|
|
136
143
|
tool: string;
|
|
137
144
|
reason: string;
|
|
138
145
|
} | {
|
|
139
|
-
kind: "
|
|
146
|
+
kind: "signal_delivery_disposed";
|
|
140
147
|
turn: number;
|
|
148
|
+
operation_id: string;
|
|
149
|
+
delivery_id: string;
|
|
150
|
+
attempt: number;
|
|
141
151
|
signal_id: string;
|
|
142
152
|
disposition: string;
|
|
143
153
|
queue_depth: number;
|
|
144
154
|
} | {
|
|
145
155
|
kind: "budget_exceeded";
|
|
146
156
|
turn: number;
|
|
157
|
+
operation_id: string;
|
|
158
|
+
reservation_id?: string;
|
|
147
159
|
budget: string;
|
|
160
|
+
} | {
|
|
161
|
+
kind: "budget_usage_reported";
|
|
162
|
+
turn: number;
|
|
163
|
+
operation_id: string;
|
|
164
|
+
reservation_id: string;
|
|
165
|
+
tokens: number;
|
|
166
|
+
subagents: number;
|
|
167
|
+
rounds: number;
|
|
168
|
+
} | {
|
|
169
|
+
kind: "operation_cancelled";
|
|
170
|
+
turn: number;
|
|
171
|
+
operation_id: string;
|
|
172
|
+
reason: "user" | "deadline" | "lease_lost" | "host_shutdown";
|
|
173
|
+
pending_call_ids: string[];
|
|
148
174
|
} | {
|
|
149
175
|
kind: "milestone_advanced";
|
|
150
176
|
turn: number;
|
|
@@ -188,33 +214,38 @@ export type SessionEvent = {
|
|
|
188
214
|
} | {
|
|
189
215
|
kind: "memory_written";
|
|
190
216
|
turn: number;
|
|
191
|
-
|
|
217
|
+
record_id: string;
|
|
218
|
+
scope: MemoryScope;
|
|
192
219
|
memory_kind: string;
|
|
220
|
+
name: string;
|
|
193
221
|
size_bytes: number;
|
|
194
222
|
} | {
|
|
195
223
|
kind: "memory_queried";
|
|
196
224
|
turn: number;
|
|
197
|
-
|
|
225
|
+
scope: MemoryScope;
|
|
226
|
+
query: string;
|
|
198
227
|
requested_k: number;
|
|
199
228
|
requires_async_response: boolean;
|
|
200
229
|
} | {
|
|
201
230
|
kind: "memory_validation_failed";
|
|
202
231
|
turn: number;
|
|
203
|
-
|
|
232
|
+
record_id: string;
|
|
204
233
|
error: string;
|
|
234
|
+
} | {
|
|
235
|
+
kind: "memory_retrieval_result";
|
|
236
|
+
hits: MemoryRecall[];
|
|
205
237
|
} | {
|
|
206
238
|
kind: "workflow_node_completed";
|
|
207
239
|
turn: number;
|
|
208
240
|
agent_id: string;
|
|
241
|
+
status: import("./types/agent.js").WorkflowNodeStatus;
|
|
209
242
|
termination: string;
|
|
210
243
|
/** W-1: result-borne control signals, persisted so resume replays control flow faithfully —
|
|
211
244
|
* a classifier re-prunes its rejected branches, a recorded loop stop is honored. */
|
|
212
245
|
classify_branch?: string;
|
|
213
246
|
tournament_winner?: string;
|
|
214
247
|
loop_continue?: boolean;
|
|
215
|
-
|
|
216
|
-
* post-resume reduce/judge/dependent nodes still see their dependencies' outputs. */
|
|
217
|
-
output?: string;
|
|
248
|
+
output?: import("../types.js").Message;
|
|
218
249
|
} | {
|
|
219
250
|
kind: "workflow_nodes_submitted";
|
|
220
251
|
turn: number;
|
|
@@ -234,8 +265,7 @@ export type SessionEvent = {
|
|
|
234
265
|
} | {
|
|
235
266
|
kind: "workflow_completed";
|
|
236
267
|
turn: number;
|
|
237
|
-
|
|
238
|
-
failed: string[];
|
|
268
|
+
node_outcomes: import("./types/agent.js").KernelWorkflowNodeOutcome[];
|
|
239
269
|
total_nodes: number;
|
|
240
270
|
} | {
|
|
241
271
|
kind: "run_terminal";
|
|
@@ -254,13 +284,28 @@ export interface SessionLog {
|
|
|
254
284
|
event: SessionEvent;
|
|
255
285
|
}>>;
|
|
256
286
|
latestSeq(sessionId: string): Promise<number>;
|
|
287
|
+
appendKernelGenesis(sessionId: string, genesis: KernelOperationGenesis): Promise<KernelGenesisReceipt>;
|
|
288
|
+
readKernelGenesis(sessionId: string, operationId: string): Promise<KernelOperationGenesis | undefined>;
|
|
289
|
+
compareAndAppendKernelTransaction(sessionId: string, expectedTransactionHead: string, transaction: KernelTransaction): Promise<DurableAppendReceipt>;
|
|
290
|
+
readKernelTransactions(sessionId: string, operationId: string, fromStepSeq?: number): Promise<KernelTransactionEntry[]>;
|
|
291
|
+
kernelTransactionHead(sessionId: string, operationId: string): Promise<string | undefined>;
|
|
257
292
|
}
|
|
258
293
|
export declare class InMemorySessionLog implements SessionLog {
|
|
259
294
|
private store;
|
|
295
|
+
private seqCounters;
|
|
296
|
+
private genesisStore;
|
|
297
|
+
private transactionStore;
|
|
298
|
+
private operationKey;
|
|
299
|
+
private nextSeq;
|
|
260
300
|
append(sessionId: string, event: SessionEvent): Promise<number>;
|
|
261
301
|
read(sessionId: string, fromSeq?: number, primitiveFilter?: KernelPrimitive): Promise<Array<{
|
|
262
302
|
seq: number;
|
|
263
303
|
event: SessionEvent;
|
|
264
304
|
}>>;
|
|
265
305
|
latestSeq(sessionId: string): Promise<number>;
|
|
306
|
+
appendKernelGenesis(sessionId: string, genesis: KernelOperationGenesis): Promise<KernelGenesisReceipt>;
|
|
307
|
+
readKernelGenesis(sessionId: string, operationId: string): Promise<KernelOperationGenesis | undefined>;
|
|
308
|
+
compareAndAppendKernelTransaction(sessionId: string, expectedTransactionHead: string, transaction: KernelTransaction): Promise<DurableAppendReceipt>;
|
|
309
|
+
readKernelTransactions(sessionId: string, operationId: string, fromStepSeq?: number): Promise<KernelTransactionEntry[]>;
|
|
310
|
+
kernelTransactionHead(sessionId: string, operationId: string): Promise<string | undefined>;
|
|
266
311
|
}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import { primitiveForKind } from "./kernel-event-log.js";
|
|
2
|
+
import { KernelLogConflictError, KernelLogIntegrityError, verifyKernelOperationGenesis, verifyKernelTransaction, verifyKernelTransactionSuccessor, } from "./kernel-transaction-log.js";
|
|
2
3
|
export class InMemorySessionLog {
|
|
3
4
|
store = new Map();
|
|
5
|
+
seqCounters = new Map();
|
|
6
|
+
genesisStore = new Map();
|
|
7
|
+
transactionStore = new Map();
|
|
8
|
+
operationKey(sessionId, operationId) {
|
|
9
|
+
return `${sessionId}\u0000${operationId}`;
|
|
10
|
+
}
|
|
11
|
+
nextSeq(sessionId) {
|
|
12
|
+
const seq = this.seqCounters.get(sessionId) ?? 0;
|
|
13
|
+
this.seqCounters.set(sessionId, seq + 1);
|
|
14
|
+
return seq;
|
|
15
|
+
}
|
|
4
16
|
async append(sessionId, event) {
|
|
5
17
|
if (!this.store.has(sessionId))
|
|
6
18
|
this.store.set(sessionId, []);
|
|
7
19
|
const entries = this.store.get(sessionId);
|
|
8
|
-
const seq =
|
|
20
|
+
const seq = this.nextSeq(sessionId);
|
|
9
21
|
entries.push({ seq, event });
|
|
10
22
|
return seq;
|
|
11
23
|
}
|
|
@@ -20,7 +32,52 @@ export class InMemorySessionLog {
|
|
|
20
32
|
});
|
|
21
33
|
}
|
|
22
34
|
async latestSeq(sessionId) {
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
return (this.seqCounters.get(sessionId) ?? 0) - 1;
|
|
36
|
+
}
|
|
37
|
+
async appendKernelGenesis(sessionId, genesis) {
|
|
38
|
+
await verifyKernelOperationGenesis(genesis);
|
|
39
|
+
const operationKey = this.operationKey(sessionId, genesis.operation_id);
|
|
40
|
+
const existing = this.genesisStore.get(operationKey);
|
|
41
|
+
if (existing) {
|
|
42
|
+
if (existing.genesis.genesis_digest !== genesis.genesis_digest) {
|
|
43
|
+
throw new KernelLogConflictError("session already has a different kernel operation genesis");
|
|
44
|
+
}
|
|
45
|
+
return { log_seq: existing.log_seq, genesis_digest: genesis.genesis_digest };
|
|
46
|
+
}
|
|
47
|
+
const log_seq = this.nextSeq(sessionId);
|
|
48
|
+
this.genesisStore.set(operationKey, { log_seq, genesis });
|
|
49
|
+
return { log_seq, genesis_digest: genesis.genesis_digest };
|
|
50
|
+
}
|
|
51
|
+
async readKernelGenesis(sessionId, operationId) {
|
|
52
|
+
return this.genesisStore.get(this.operationKey(sessionId, operationId))?.genesis;
|
|
53
|
+
}
|
|
54
|
+
async compareAndAppendKernelTransaction(sessionId, expectedTransactionHead, transaction) {
|
|
55
|
+
await verifyKernelTransaction(transaction);
|
|
56
|
+
const operationKey = this.operationKey(sessionId, transaction.operation_id);
|
|
57
|
+
const genesis = this.genesisStore.get(operationKey)?.genesis;
|
|
58
|
+
if (!genesis)
|
|
59
|
+
throw new KernelLogIntegrityError("kernel transaction requires a durable genesis");
|
|
60
|
+
if (transaction.operation_id !== genesis.operation_id) {
|
|
61
|
+
throw new KernelLogIntegrityError("kernel transaction operation_id does not match genesis");
|
|
62
|
+
}
|
|
63
|
+
const head = await this.kernelTransactionHead(sessionId, transaction.operation_id);
|
|
64
|
+
if (head !== expectedTransactionHead || transaction.previous_transaction_digest !== head) {
|
|
65
|
+
throw new KernelLogConflictError("kernel transaction head changed before compare-and-append");
|
|
66
|
+
}
|
|
67
|
+
const entries = this.transactionStore.get(operationKey) ?? [];
|
|
68
|
+
verifyKernelTransactionSuccessor(entries.at(-1)?.transaction, transaction);
|
|
69
|
+
const log_seq = this.nextSeq(sessionId);
|
|
70
|
+
entries.push({ log_seq, transaction });
|
|
71
|
+
this.transactionStore.set(operationKey, entries);
|
|
72
|
+
return { log_seq, transaction_digest: transaction.transaction_digest };
|
|
73
|
+
}
|
|
74
|
+
async readKernelTransactions(sessionId, operationId, fromStepSeq = 1) {
|
|
75
|
+
return (this.transactionStore.get(this.operationKey(sessionId, operationId)) ?? []).filter(entry => entry.transaction.step_seq >= fromStepSeq);
|
|
76
|
+
}
|
|
77
|
+
async kernelTransactionHead(sessionId, operationId) {
|
|
78
|
+
const operationKey = this.operationKey(sessionId, operationId);
|
|
79
|
+
const entries = this.transactionStore.get(operationKey) ?? [];
|
|
80
|
+
return entries.at(-1)?.transaction.transaction_digest
|
|
81
|
+
?? this.genesisStore.get(operationKey)?.genesis.genesis_digest;
|
|
25
82
|
}
|
|
26
83
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { ProviderReplay, ToolCall } from "../types.js";
|
|
1
|
+
import type { Message, ProviderReplay, ToolCall } from "../types.js";
|
|
2
2
|
import type { SessionEvent } from "./session-log.js";
|
|
3
|
+
import type { WorkflowNodeStatus } from "./types/agent.js";
|
|
3
4
|
export { REPLAY_CONTENT_MAX_BYTES as RECOVERY_CONTENT_MAX_BYTES } from "./replay-sanitize.js";
|
|
4
5
|
/**
|
|
5
6
|
* Normalize a persisted llm_completed event for recovery. Content is sanitized
|
|
@@ -41,33 +42,36 @@ export declare function buildRunTerminalEvent(input: {
|
|
|
41
42
|
export declare function buildWorkflowNodeCompletedEvent(input: {
|
|
42
43
|
turn: number;
|
|
43
44
|
agentId: string;
|
|
45
|
+
status: WorkflowNodeStatus;
|
|
44
46
|
termination: string;
|
|
45
47
|
classifyBranch?: string;
|
|
46
48
|
tournamentWinner?: string;
|
|
47
49
|
loopContinue?: boolean;
|
|
48
|
-
output?:
|
|
50
|
+
output?: Message;
|
|
49
51
|
}): Extract<SessionEvent, {
|
|
50
52
|
kind: "workflow_node_completed";
|
|
51
53
|
}>;
|
|
52
54
|
/** One recovered node completion: the agent id plus its persisted control signals and output. */
|
|
53
|
-
export interface
|
|
55
|
+
export interface RecoveredNodeOutcome {
|
|
54
56
|
agentId: string;
|
|
57
|
+
status: WorkflowNodeStatus;
|
|
58
|
+
termination: string;
|
|
55
59
|
classifyBranch?: string;
|
|
56
60
|
tournamentWinner?: string;
|
|
57
61
|
loopContinue?: boolean;
|
|
58
|
-
output?:
|
|
62
|
+
output?: Message;
|
|
59
63
|
}
|
|
60
64
|
/**
|
|
61
65
|
* Recover completed workflow node records from a session event stream. Scans for
|
|
62
66
|
* workflow_node_completed events with termination "completed" and returns them WITH their
|
|
63
67
|
* result-borne control signals (W-1) — resumeWorkflow lowers these to the kernel's
|
|
64
|
-
* `
|
|
68
|
+
* `resumed_outcomes` so a classifier re-prunes and a loop stop is honored, and re-seeds the
|
|
65
69
|
* driver's outputs map from the persisted output text.
|
|
66
70
|
*/
|
|
67
|
-
export declare function
|
|
71
|
+
export declare function recoverWorkflowNodeOutcomes(events: Array<{
|
|
68
72
|
seq: number;
|
|
69
73
|
event: SessionEvent;
|
|
70
|
-
}>):
|
|
74
|
+
}>): RecoveredNodeOutcome[];
|
|
71
75
|
/** R3-1: build workflow_nodes_submitted for persistence after a runtime submission, so resume can
|
|
72
76
|
* re-apply it. `nodes` is the kernel-shape (snake_case) submitted node array. */
|
|
73
77
|
export declare function buildWorkflowNodesSubmittedEvent(input: {
|
|
@@ -55,6 +55,7 @@ export function buildWorkflowNodeCompletedEvent(input) {
|
|
|
55
55
|
kind: "workflow_node_completed",
|
|
56
56
|
turn: input.turn,
|
|
57
57
|
agent_id: input.agentId,
|
|
58
|
+
status: input.status,
|
|
58
59
|
termination: input.termination,
|
|
59
60
|
...(input.classifyBranch !== undefined ? { classify_branch: input.classifyBranch } : {}),
|
|
60
61
|
...(input.tournamentWinner !== undefined ? { tournament_winner: input.tournamentWinner } : {}),
|
|
@@ -66,15 +67,17 @@ export function buildWorkflowNodeCompletedEvent(input) {
|
|
|
66
67
|
* Recover completed workflow node records from a session event stream. Scans for
|
|
67
68
|
* workflow_node_completed events with termination "completed" and returns them WITH their
|
|
68
69
|
* result-borne control signals (W-1) — resumeWorkflow lowers these to the kernel's
|
|
69
|
-
* `
|
|
70
|
+
* `resumed_outcomes` so a classifier re-prunes and a loop stop is honored, and re-seeds the
|
|
70
71
|
* driver's outputs map from the persisted output text.
|
|
71
72
|
*/
|
|
72
|
-
export function
|
|
73
|
+
export function recoverWorkflowNodeOutcomes(events) {
|
|
73
74
|
const completed = [];
|
|
74
75
|
for (const { event } of events) {
|
|
75
|
-
if (event.kind === "workflow_node_completed"
|
|
76
|
+
if (event.kind === "workflow_node_completed") {
|
|
76
77
|
completed.push({
|
|
77
78
|
agentId: event.agent_id,
|
|
79
|
+
status: event.status,
|
|
80
|
+
termination: event.termination,
|
|
78
81
|
...(event.classify_branch !== undefined ? { classifyBranch: event.classify_branch } : {}),
|
|
79
82
|
...(event.tournament_winner !== undefined ? { tournamentWinner: event.tournament_winner } : {}),
|
|
80
83
|
...(event.loop_continue !== undefined ? { loopContinue: event.loop_continue } : {}),
|
|
@@ -106,11 +109,11 @@ export function recoverSubmittedWorkflowNodes(events) {
|
|
|
106
109
|
if (event.kind === "workflow_nodes_submitted") {
|
|
107
110
|
submissions.push(event.nodes);
|
|
108
111
|
submitters.push(event.submitter_agent_id);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
if (event.base_index === undefined) {
|
|
113
|
+
throw new Error("workflow_nodes_submitted is missing required base_index");
|
|
114
|
+
}
|
|
115
|
+
bases.push(event.base_index);
|
|
113
116
|
}
|
|
114
117
|
}
|
|
115
|
-
return { submissions, bases
|
|
118
|
+
return { submissions, bases, submitters };
|
|
116
119
|
}
|
|
@@ -157,7 +157,7 @@ export async function spawnStandalone(parentOpts, parentSessionId, spec, orchest
|
|
|
157
157
|
const runtime = new kernel.KernelRuntime({
|
|
158
158
|
maxTokens: parentOpts.maxTokens,
|
|
159
159
|
maxTurns: parentOpts.maxTurns ?? 25,
|
|
160
|
-
timeoutMs: parentOpts.timeoutMs
|
|
160
|
+
timeoutMs: parentOpts.timeoutMs,
|
|
161
161
|
});
|
|
162
162
|
const pending = [];
|
|
163
163
|
kernelApply(runtime, pending, { kind: "start_run", task: { goal: "coordinator", criteria: [] } });
|
|
@@ -126,6 +126,9 @@ export type WorkflowTaskSpec = {
|
|
|
126
126
|
} | string;
|
|
127
127
|
/** One node in a declarative workflow DAG (camelCase host shape). */
|
|
128
128
|
export type NodeTrust = "trusted" | "quarantined";
|
|
129
|
+
export type WorkflowDependencyPolicy = "all_success" | "accept_partial" | "all_terminal" | "optional";
|
|
130
|
+
export type WorkflowNodeStatus = "completed" | "completed_partial" | "failed" | "skipped_upstream_failed";
|
|
131
|
+
export declare function workflowNodeStatusFromTermination(termination: TerminationReason | string): WorkflowNodeStatus;
|
|
129
132
|
export interface WorkflowNodeSpec {
|
|
130
133
|
task: WorkflowTaskSpec;
|
|
131
134
|
role: KernelAgentRole;
|
|
@@ -165,11 +168,39 @@ export interface WorkflowNodeSpec {
|
|
|
165
168
|
maxWallMs?: number;
|
|
166
169
|
/** Indices of nodes this node depends on. */
|
|
167
170
|
dependsOn?: number[];
|
|
171
|
+
/** How dependency terminal states gate this node. Defaults to `all_success`. */
|
|
172
|
+
depPolicy?: WorkflowDependencyPolicy;
|
|
168
173
|
}
|
|
169
174
|
/** A declarative workflow DAG the kernel runs node-by-node, gating each spawn. */
|
|
170
175
|
export interface WorkflowSpec {
|
|
171
176
|
nodes: WorkflowNodeSpec[];
|
|
172
177
|
}
|
|
178
|
+
export interface KernelWorkflowNodeOutcome {
|
|
179
|
+
node_id: string;
|
|
180
|
+
status: WorkflowNodeStatus;
|
|
181
|
+
termination?: TerminationReason;
|
|
182
|
+
output?: {
|
|
183
|
+
role: Message["role"];
|
|
184
|
+
content: string;
|
|
185
|
+
tool_calls?: Array<{
|
|
186
|
+
id: string;
|
|
187
|
+
name: string;
|
|
188
|
+
arguments?: Record<string, unknown>;
|
|
189
|
+
}>;
|
|
190
|
+
token_count?: number;
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
export interface WorkflowNodeOutcome {
|
|
194
|
+
nodeId: string;
|
|
195
|
+
status: WorkflowNodeStatus;
|
|
196
|
+
termination?: TerminationReason;
|
|
197
|
+
output?: Message;
|
|
198
|
+
}
|
|
199
|
+
export interface WorkflowOutcome {
|
|
200
|
+
nodeOutcomes: WorkflowNodeOutcome[];
|
|
201
|
+
outputs: Record<string, string>;
|
|
202
|
+
}
|
|
203
|
+
export declare function workflowNodeOutcomeFromKernel(raw: KernelWorkflowNodeOutcome): WorkflowNodeOutcome;
|
|
173
204
|
/** Per-node spawn descriptor carried in the `workflow_batch_spawned` observation. */
|
|
174
205
|
export interface WorkflowSpawnInfo {
|
|
175
206
|
agent_id: string;
|
|
@@ -121,6 +121,35 @@ export function milestoneCheckPass(phaseId) {
|
|
|
121
121
|
export function milestoneCheckFail(phaseId, reason) {
|
|
122
122
|
return { phaseId, passed: false, reason };
|
|
123
123
|
}
|
|
124
|
+
export function workflowNodeStatusFromTermination(termination) {
|
|
125
|
+
if (termination === "completed")
|
|
126
|
+
return "completed";
|
|
127
|
+
if (termination === "error" || termination === "user_abort")
|
|
128
|
+
return "failed";
|
|
129
|
+
return "completed_partial";
|
|
130
|
+
}
|
|
131
|
+
export function workflowNodeOutcomeFromKernel(raw) {
|
|
132
|
+
const output = raw.output;
|
|
133
|
+
return {
|
|
134
|
+
nodeId: raw.node_id,
|
|
135
|
+
status: raw.status,
|
|
136
|
+
...(raw.termination ? { termination: raw.termination } : {}),
|
|
137
|
+
...(output
|
|
138
|
+
? {
|
|
139
|
+
output: {
|
|
140
|
+
role: output.role,
|
|
141
|
+
content: output.content,
|
|
142
|
+
toolCalls: (output.tool_calls ?? []).map(call => ({
|
|
143
|
+
id: call.id,
|
|
144
|
+
name: call.name,
|
|
145
|
+
arguments: JSON.stringify(call.arguments ?? {}),
|
|
146
|
+
})),
|
|
147
|
+
...(output.token_count != null ? { tokenCount: output.token_count } : {}),
|
|
148
|
+
},
|
|
149
|
+
}
|
|
150
|
+
: {}),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
124
153
|
/** G4: a concise budget note appended to a coordinator node's goal. "" when nothing is bounded. */
|
|
125
154
|
export function workflowBudgetNote(budget) {
|
|
126
155
|
if (!budget)
|
|
@@ -188,6 +217,7 @@ export function workflowNodeSpecToKernel(n) {
|
|
|
188
217
|
...(n.maxTurns != null ? { max_turns: n.maxTurns } : {}),
|
|
189
218
|
...(n.maxWallMs != null ? { max_wall_ms: n.maxWallMs } : {}),
|
|
190
219
|
...(n.dependsOn && n.dependsOn.length ? { depends_on: n.dependsOn } : {}),
|
|
220
|
+
dep_policy: n.depPolicy ?? "all_success",
|
|
191
221
|
};
|
|
192
222
|
}
|
|
193
223
|
export function workflowSpecToKernel(spec) {
|
|
@@ -274,6 +304,11 @@ const workflowNodesArraySchema = {
|
|
|
274
304
|
},
|
|
275
305
|
tokenBudget: { type: "integer", description: "Cap this node's child run at this many cumulative tokens." },
|
|
276
306
|
dependsOn: { type: "array", items: { type: "integer" } },
|
|
307
|
+
depPolicy: {
|
|
308
|
+
type: "string",
|
|
309
|
+
enum: ["all_success", "accept_partial", "all_terminal", "optional"],
|
|
310
|
+
description: "How dependency terminal states gate this node; defaults to all_success.",
|
|
311
|
+
},
|
|
277
312
|
},
|
|
278
313
|
required: ["task", "role"],
|
|
279
314
|
},
|
package/dist/signals/index.d.ts
CHANGED
|
@@ -4,9 +4,29 @@ export interface RuntimeSignal {
|
|
|
4
4
|
urgency: "low" | "normal" | "high" | "critical";
|
|
5
5
|
payload: Record<string, unknown>;
|
|
6
6
|
dedupeKey?: string;
|
|
7
|
+
/** Target a specific session loop. Omitted means a shared signal. */
|
|
8
|
+
recipient?: string;
|
|
9
|
+
/** Absolute journal-clock deadline for optional urgency escalation. */
|
|
10
|
+
deadlineMs?: number;
|
|
11
|
+
/** Merge with an unconsumed queued signal carrying the same key. */
|
|
12
|
+
coalesceKey?: string;
|
|
13
|
+
/** Number of host signals deterministically represented by this signal. */
|
|
14
|
+
coalescedCount?: number;
|
|
7
15
|
}
|
|
8
16
|
export interface SignalSource {
|
|
9
|
-
|
|
17
|
+
claimSignal(): Promise<SignalClaim | null>;
|
|
18
|
+
ackSignal(receipt: SignalDeliveryReceipt): Promise<boolean>;
|
|
19
|
+
nackSignal(receipt: SignalDeliveryReceipt): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
export interface SignalDeliveryReceipt {
|
|
22
|
+
deliveryId: string;
|
|
23
|
+
leaseToken: string;
|
|
24
|
+
}
|
|
25
|
+
export interface SignalClaim extends SignalDeliveryReceipt {
|
|
26
|
+
signalId: string;
|
|
27
|
+
deliveryAttempt: number;
|
|
28
|
+
signal: RuntimeSignal;
|
|
29
|
+
leaseExpiresAtMs: number;
|
|
10
30
|
}
|
|
11
31
|
export declare class ScheduledPrompt {
|
|
12
32
|
readonly goal: string;
|
package/dist/signals/index.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -54,6 +54,12 @@ export interface RenderedContext {
|
|
|
54
54
|
/** Message count of the frozen history prefix (compaction boundary). When set,
|
|
55
55
|
* Anthropic pins a deep cache breakpoint here instead of the rolling pair. */
|
|
56
56
|
frozenPrefixLen?: number;
|
|
57
|
+
budgetOverflow?: ContextBudgetOverflow;
|
|
58
|
+
}
|
|
59
|
+
export interface ContextBudgetOverflow {
|
|
60
|
+
kind: "fixed_context" | "protected_tail";
|
|
61
|
+
requiredTokens: number;
|
|
62
|
+
maxTokens: number;
|
|
57
63
|
}
|
|
58
64
|
export interface StreamEvent {
|
|
59
65
|
type: string;
|
|
@@ -104,8 +110,7 @@ export interface DoneEvent extends StreamEvent {
|
|
|
104
110
|
type: "done";
|
|
105
111
|
iterations: number;
|
|
106
112
|
totalTokens: number;
|
|
107
|
-
status: string;
|
|
108
|
-
dreamResult?: import("./memory/index.js").DreamResult; /** ③ loop-agent: the kernel-adjudicated after-round decision (absent on non-loop runs). */
|
|
113
|
+
status: string; /** ③ loop-agent: the kernel-adjudicated after-round decision (absent on non-loop runs). */
|
|
109
114
|
paceDecision?: import("./runtime/kernel-step.js").PaceDecision;
|
|
110
115
|
}
|
|
111
116
|
export interface ErrorEvent extends StreamEvent {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepstrike/wasm",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.40",
|
|
4
4
|
"description": "DeepStrike WASM SDK — browser, Cloudflare Workers, Deno Deploy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"test": "node --experimental-vm-modules node_modules/.bin/jest"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@deepstrike/wasm-kernel": "0.2.
|
|
18
|
+
"@deepstrike/wasm-kernel": "0.2.40"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/jest": "^30.0.0",
|