@deepstrike/wasm 0.2.27 → 0.2.28
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/dist/runtime/runner.d.ts +19 -1
- package/dist/runtime/runner.js +122 -67
- package/package.json +2 -2
package/dist/runtime/runner.d.ts
CHANGED
|
@@ -186,9 +186,25 @@ export declare class RuntimeRunner {
|
|
|
186
186
|
* through the syscall trap; this driver runs each kernel-emitted batch of nodes in parallel,
|
|
187
187
|
* feeds their results back, and loops until the kernel reports the workflow complete.
|
|
188
188
|
*/
|
|
189
|
+
/**
|
|
190
|
+
* Lower the declarative governance / attention / scheduler-budget / resource-quota / memory policies
|
|
191
|
+
* into a freshly-created kernel. Shared by `execute()` (full run) and `bootstrapWorkflowKernel()`
|
|
192
|
+
* (standalone workflow) so a DAG's node spawns are gated and quota'd exactly as a mid-run spawn.
|
|
193
|
+
* Must run BEFORE `start_run`. No config ⇒ native-profile defaults.
|
|
194
|
+
*/
|
|
195
|
+
private applyKernelPolicies;
|
|
196
|
+
/**
|
|
197
|
+
* Bootstrap a standalone kernel for a host-driven workflow with no active parent run — the path a
|
|
198
|
+
* stateless handler (browser/edge worker) takes when it calls `runWorkflow(spec)` directly. Mirrors
|
|
199
|
+
* `execute()`'s pre-run setup (policies via `applyKernelPolicies`, then `start_run`) and records a
|
|
200
|
+
* best-effort `run_started` so the run is resumable. `runWorkflow` tears the kernel down afterward.
|
|
201
|
+
*/
|
|
202
|
+
private bootstrapWorkflowKernel;
|
|
189
203
|
runWorkflow(spec: WorkflowSpec, opts?: {
|
|
190
204
|
resumedCompleted?: string[];
|
|
191
205
|
resumedSubmissions?: Record<string, unknown>[][];
|
|
206
|
+
/** Standalone session id when bootstrapping (no active parent run). Defaults to a fresh uuid. */
|
|
207
|
+
sessionId?: string;
|
|
192
208
|
}): Promise<{
|
|
193
209
|
completed: string[];
|
|
194
210
|
failed: string[];
|
|
@@ -233,7 +249,9 @@ export declare class RuntimeRunner {
|
|
|
233
249
|
* Reads the session log, extracts completed workflow node agent_ids, and
|
|
234
250
|
* calls runWorkflow with resumedCompleted so the kernel skips those nodes.
|
|
235
251
|
*/
|
|
236
|
-
resumeWorkflow(spec: WorkflowSpec
|
|
252
|
+
resumeWorkflow(spec: WorkflowSpec, opts?: {
|
|
253
|
+
sessionId?: string;
|
|
254
|
+
}): Promise<{
|
|
237
255
|
completed: string[];
|
|
238
256
|
failed: string[];
|
|
239
257
|
}>;
|
package/dist/runtime/runner.js
CHANGED
|
@@ -385,56 +385,7 @@ export class RuntimeRunner {
|
|
|
385
385
|
: baseSpec;
|
|
386
386
|
startPayload.run_spec = agentRunSpecToKernel(spec);
|
|
387
387
|
}
|
|
388
|
-
|
|
389
|
-
const attentionPolicy = this.opts.attentionPolicy ?? osProfile.attentionPolicy;
|
|
390
|
-
const governancePolicy = this.opts.governancePolicy ?? osProfile.governancePolicy;
|
|
391
|
-
kernelApply(runtime, this.pendingObservations, governancePolicyToKernelEvent(governancePolicy));
|
|
392
|
-
kernelApply(runtime, this.pendingObservations, {
|
|
393
|
-
kind: "set_attention_policy",
|
|
394
|
-
...(attentionPolicy.maxQueueSize !== undefined
|
|
395
|
-
? { max_queue_size: attentionPolicy.maxQueueSize }
|
|
396
|
-
: {}),
|
|
397
|
-
});
|
|
398
|
-
if (this.opts.schedulerBudget) {
|
|
399
|
-
kernelApply(runtime, this.pendingObservations, {
|
|
400
|
-
kind: "set_scheduler_budget",
|
|
401
|
-
...(this.opts.schedulerBudget.maxWallMs !== undefined
|
|
402
|
-
? { max_wall_ms: this.opts.schedulerBudget.maxWallMs }
|
|
403
|
-
: {}),
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
if (this.opts.resourceQuota) {
|
|
407
|
-
const q = this.opts.resourceQuota;
|
|
408
|
-
kernelApply(runtime, this.pendingObservations, {
|
|
409
|
-
kind: "set_resource_quota",
|
|
410
|
-
quota: {
|
|
411
|
-
...(q.maxConcurrentSubagents !== undefined
|
|
412
|
-
? { max_concurrent_subagents: q.maxConcurrentSubagents }
|
|
413
|
-
: {}),
|
|
414
|
-
...(q.maxSpawnDepth !== undefined ? { max_spawn_depth: q.maxSpawnDepth } : {}),
|
|
415
|
-
...(q.memoryWritesPerWindow !== undefined
|
|
416
|
-
? {
|
|
417
|
-
memory_writes_per_window: [
|
|
418
|
-
q.memoryWritesPerWindow.maxWrites,
|
|
419
|
-
q.memoryWritesPerWindow.windowMs,
|
|
420
|
-
],
|
|
421
|
-
}
|
|
422
|
-
: {}),
|
|
423
|
-
},
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
if (this.opts.memoryPolicy) {
|
|
427
|
-
const m = this.opts.memoryPolicy;
|
|
428
|
-
kernelApply(runtime, this.pendingObservations, {
|
|
429
|
-
kind: "set_memory_policy",
|
|
430
|
-
...(m.memoryPath !== undefined ? { memory_path: m.memoryPath } : {}),
|
|
431
|
-
...(m.staleWarningDays !== undefined ? { stale_warning_days: m.staleWarningDays } : {}),
|
|
432
|
-
...(m.retrievalTopK !== undefined ? { retrieval_top_k: m.retrievalTopK } : {}),
|
|
433
|
-
...(m.validationEnabled !== undefined ? { validation_enabled: m.validationEnabled } : {}),
|
|
434
|
-
...(m.maxContentBytes !== undefined ? { max_content_bytes: m.maxContentBytes } : {}),
|
|
435
|
-
...(m.maxNameLength !== undefined ? { max_name_length: m.maxNameLength } : {}),
|
|
436
|
-
});
|
|
437
|
-
}
|
|
388
|
+
this.applyKernelPolicies(runtime);
|
|
438
389
|
// I4: pre-fetch memory into the knowledge partition before the first LLM turn (mirrors Node).
|
|
439
390
|
if (!resumeMidRun && this.opts.preQueryMemory && this.opts.dreamStore && this.opts.agentId) {
|
|
440
391
|
try {
|
|
@@ -1007,22 +958,124 @@ export class RuntimeRunner {
|
|
|
1007
958
|
* through the syscall trap; this driver runs each kernel-emitted batch of nodes in parallel,
|
|
1008
959
|
* feeds their results back, and loops until the kernel reports the workflow complete.
|
|
1009
960
|
*/
|
|
961
|
+
/**
|
|
962
|
+
* Lower the declarative governance / attention / scheduler-budget / resource-quota / memory policies
|
|
963
|
+
* into a freshly-created kernel. Shared by `execute()` (full run) and `bootstrapWorkflowKernel()`
|
|
964
|
+
* (standalone workflow) so a DAG's node spawns are gated and quota'd exactly as a mid-run spawn.
|
|
965
|
+
* Must run BEFORE `start_run`. No config ⇒ native-profile defaults.
|
|
966
|
+
*/
|
|
967
|
+
applyKernelPolicies(runtime) {
|
|
968
|
+
const osProfile = assertNativeProfile(this.opts.osProfile ?? "native");
|
|
969
|
+
const attentionPolicy = this.opts.attentionPolicy ?? osProfile.attentionPolicy;
|
|
970
|
+
const governancePolicy = this.opts.governancePolicy ?? osProfile.governancePolicy;
|
|
971
|
+
kernelApply(runtime, this.pendingObservations, governancePolicyToKernelEvent(governancePolicy));
|
|
972
|
+
kernelApply(runtime, this.pendingObservations, {
|
|
973
|
+
kind: "set_attention_policy",
|
|
974
|
+
...(attentionPolicy.maxQueueSize !== undefined
|
|
975
|
+
? { max_queue_size: attentionPolicy.maxQueueSize }
|
|
976
|
+
: {}),
|
|
977
|
+
});
|
|
978
|
+
if (this.opts.schedulerBudget) {
|
|
979
|
+
kernelApply(runtime, this.pendingObservations, {
|
|
980
|
+
kind: "set_scheduler_budget",
|
|
981
|
+
...(this.opts.schedulerBudget.maxWallMs !== undefined
|
|
982
|
+
? { max_wall_ms: this.opts.schedulerBudget.maxWallMs }
|
|
983
|
+
: {}),
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
if (this.opts.resourceQuota) {
|
|
987
|
+
const q = this.opts.resourceQuota;
|
|
988
|
+
kernelApply(runtime, this.pendingObservations, {
|
|
989
|
+
kind: "set_resource_quota",
|
|
990
|
+
quota: {
|
|
991
|
+
...(q.maxConcurrentSubagents !== undefined
|
|
992
|
+
? { max_concurrent_subagents: q.maxConcurrentSubagents }
|
|
993
|
+
: {}),
|
|
994
|
+
...(q.maxSpawnDepth !== undefined ? { max_spawn_depth: q.maxSpawnDepth } : {}),
|
|
995
|
+
...(q.memoryWritesPerWindow !== undefined
|
|
996
|
+
? {
|
|
997
|
+
memory_writes_per_window: [
|
|
998
|
+
q.memoryWritesPerWindow.maxWrites,
|
|
999
|
+
q.memoryWritesPerWindow.windowMs,
|
|
1000
|
+
],
|
|
1001
|
+
}
|
|
1002
|
+
: {}),
|
|
1003
|
+
},
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
if (this.opts.memoryPolicy) {
|
|
1007
|
+
const m = this.opts.memoryPolicy;
|
|
1008
|
+
kernelApply(runtime, this.pendingObservations, {
|
|
1009
|
+
kind: "set_memory_policy",
|
|
1010
|
+
...(m.memoryPath !== undefined ? { memory_path: m.memoryPath } : {}),
|
|
1011
|
+
...(m.staleWarningDays !== undefined ? { stale_warning_days: m.staleWarningDays } : {}),
|
|
1012
|
+
...(m.retrievalTopK !== undefined ? { retrieval_top_k: m.retrievalTopK } : {}),
|
|
1013
|
+
...(m.validationEnabled !== undefined ? { validation_enabled: m.validationEnabled } : {}),
|
|
1014
|
+
...(m.maxContentBytes !== undefined ? { max_content_bytes: m.maxContentBytes } : {}),
|
|
1015
|
+
...(m.maxNameLength !== undefined ? { max_name_length: m.maxNameLength } : {}),
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Bootstrap a standalone kernel for a host-driven workflow with no active parent run — the path a
|
|
1021
|
+
* stateless handler (browser/edge worker) takes when it calls `runWorkflow(spec)` directly. Mirrors
|
|
1022
|
+
* `execute()`'s pre-run setup (policies via `applyKernelPolicies`, then `start_run`) and records a
|
|
1023
|
+
* best-effort `run_started` so the run is resumable. `runWorkflow` tears the kernel down afterward.
|
|
1024
|
+
*/
|
|
1025
|
+
async bootstrapWorkflowKernel(sessionId, spec) {
|
|
1026
|
+
this.interrupted = false;
|
|
1027
|
+
this.pendingObservations = [];
|
|
1028
|
+
this.pendingSpoolOutputs.clear();
|
|
1029
|
+
this.currentSessionId = sessionId;
|
|
1030
|
+
const kernel = await getKernel();
|
|
1031
|
+
const runtime = new kernel.KernelRuntime({
|
|
1032
|
+
maxTokens: this.opts.maxTokens,
|
|
1033
|
+
maxTurns: this.opts.maxTurns ?? 25,
|
|
1034
|
+
...(this.opts.maxTotalTokens !== undefined ? { maxTotalTokens: this.opts.maxTotalTokens } : {}),
|
|
1035
|
+
timeoutMs: this.opts.timeoutMs !== undefined ? BigInt(this.opts.timeoutMs) : undefined,
|
|
1036
|
+
});
|
|
1037
|
+
this.activeKernel = runtime;
|
|
1038
|
+
const goal = `workflow:${spec.nodes.length} nodes`;
|
|
1039
|
+
void Promise.resolve(this.opts.sessionLog.append(sessionId, {
|
|
1040
|
+
kind: "run_started",
|
|
1041
|
+
run_id: crypto.randomUUID(),
|
|
1042
|
+
goal,
|
|
1043
|
+
criteria: [],
|
|
1044
|
+
...(this.opts.agentId ? { agent_id: this.opts.agentId } : {}),
|
|
1045
|
+
})).catch(() => { });
|
|
1046
|
+
this.applyKernelPolicies(runtime);
|
|
1047
|
+
kernelApply(runtime, this.pendingObservations, { kind: "start_run", task: { goal, criteria: [] } });
|
|
1048
|
+
return runtime;
|
|
1049
|
+
}
|
|
1010
1050
|
async runWorkflow(spec, opts) {
|
|
1011
|
-
|
|
1012
|
-
|
|
1051
|
+
// Standalone entry: with no active parent run, auto-bootstrap a kernel that owns the DAG (same
|
|
1052
|
+
// governance/quota policies a full run gets), drive it, then tear it down so the runner is reusable.
|
|
1053
|
+
// Mid-run callers keep the original in-place behavior with no teardown.
|
|
1054
|
+
const bootstrapped = !this.activeKernel || !this.currentSessionId;
|
|
1055
|
+
if (bootstrapped) {
|
|
1056
|
+
await this.bootstrapWorkflowKernel(opts?.sessionId ?? `wf-${crypto.randomUUID()}`, spec);
|
|
1013
1057
|
}
|
|
1014
1058
|
const parentSessionId = this.currentSessionId;
|
|
1015
1059
|
const runtime = this.activeKernel;
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1060
|
+
try {
|
|
1061
|
+
const observations = kernelApply(runtime, this.pendingObservations, {
|
|
1062
|
+
kind: "load_workflow",
|
|
1063
|
+
spec: workflowSpecToKernel(spec),
|
|
1064
|
+
parent_session_id: parentSessionId,
|
|
1065
|
+
// W0-ABI resume: skip nodes already completed before an interruption.
|
|
1066
|
+
...(opts?.resumedCompleted && opts.resumedCompleted.length ? { resumed_completed: opts.resumedCompleted } : {}),
|
|
1067
|
+
// R3-1: re-apply recorded runtime submissions so dynamically-appended nodes are reconstructed.
|
|
1068
|
+
...(opts?.resumedSubmissions && opts.resumedSubmissions.length ? { resumed_submissions: opts.resumedSubmissions } : {}),
|
|
1069
|
+
});
|
|
1070
|
+
return await this.driveWorkflow(observations, parentSessionId, runtime);
|
|
1071
|
+
}
|
|
1072
|
+
finally {
|
|
1073
|
+
if (bootstrapped) {
|
|
1074
|
+
this.activeKernel = null;
|
|
1075
|
+
this.currentSessionId = null;
|
|
1076
|
+
this.pendingObservations = [];
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1026
1079
|
}
|
|
1027
1080
|
/**
|
|
1028
1081
|
* M5/G1: bootstrap an **agent-authored** workflow ("the model writes its own harness"). Routes the
|
|
@@ -1169,14 +1222,16 @@ export class RuntimeRunner {
|
|
|
1169
1222
|
* Reads the session log, extracts completed workflow node agent_ids, and
|
|
1170
1223
|
* calls runWorkflow with resumedCompleted so the kernel skips those nodes.
|
|
1171
1224
|
*/
|
|
1172
|
-
async resumeWorkflow(spec) {
|
|
1173
|
-
|
|
1174
|
-
|
|
1225
|
+
async resumeWorkflow(spec, opts) {
|
|
1226
|
+
// Standalone resume: a stateless handler passes the prior `sessionId`; mid-run callers omit it.
|
|
1227
|
+
const sessionId = opts?.sessionId ?? this.currentSessionId;
|
|
1228
|
+
if (!sessionId) {
|
|
1229
|
+
throw new Error("resumeWorkflow requires an active parent run or an explicit sessionId");
|
|
1175
1230
|
}
|
|
1176
|
-
const events = await this.opts.sessionLog.read(
|
|
1231
|
+
const events = await this.opts.sessionLog.read(sessionId);
|
|
1177
1232
|
const resumedCompleted = recoverCompletedWorkflowNodes(events);
|
|
1178
1233
|
const resumedSubmissions = recoverSubmittedWorkflowNodes(events);
|
|
1179
|
-
return this.runWorkflow(spec, { resumedCompleted, resumedSubmissions });
|
|
1234
|
+
return this.runWorkflow(spec, { resumedCompleted, resumedSubmissions, sessionId });
|
|
1180
1235
|
}
|
|
1181
1236
|
async appendObservations(sessionId, runtime, nextArchiveStart) {
|
|
1182
1237
|
const turn = runtime.turn();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepstrike/wasm",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.28",
|
|
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.28"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/jest": "^30.0.0",
|