@deepstrike/wasm 0.2.5 → 0.2.6

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 CHANGED
@@ -39,6 +39,11 @@ const runner = new RuntimeRunner({
39
39
  executionPlane: plane,
40
40
  maxTokens: 32_000,
41
41
  maxTurns: 10,
42
+ resourceQuota: {
43
+ maxConcurrentSubagents: 4,
44
+ maxSpawnDepth: 2,
45
+ memoryWritesPerWindow: { maxWrites: 20, windowMs: 60_000 },
46
+ },
42
47
  })
43
48
 
44
49
  const answer = await collectText(runner.run({ sessionId: "demo", goal: "What is 2 + 3?" }))
@@ -90,6 +95,8 @@ The kernel (`@deepstrike/wasm-kernel`, Rust/wasm-bindgen) owns:
90
95
 
91
96
  The WASM SDK ships **no `readFile` built-in**. Tools must be pure JS / serializable data. Skills use `skillContentMap` on `RuntimeOptions` (no filesystem).
92
97
 
98
+ `resourceQuota` is supported in the runner and maps to the kernel `set_resource_quota` event during run setup. The write-rate quota is enforced for kernel memory-write syscalls; WASM does not yet expose runner-level `writeMemory` / `queryMemory` helpers.
99
+
93
100
  ---
94
101
 
95
102
  ## Providers
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { RuntimeRunner, collectText, InMemorySessionLog, LocalExecutionPlane, } from "./runtime/index.js";
2
- export type { RuntimeOptions, SessionEvent, SessionLog, RunContext, ExecutionPlane, } from "./runtime/index.js";
1
+ export { RuntimeRunner, collectText, InMemorySessionLog, LocalExecutionPlane, DEFAULT_NATIVE_ATTENTION_POLICY, DEFAULT_NATIVE_GOVERNANCE_POLICY, DEFAULT_SANDBOX_POLICY, assertNativeProfile, osProfile, validateDeclarativePolicy, } from "./runtime/index.js";
2
+ export type { NativeOsProfile, OsProfileId, MemoryPolicy, MemoryWriteRateLimit, ResourceQuota, RuntimeOptions, SchedulerBudget, SessionEvent, SessionLog, RunContext, ExecutionPlane, } from "./runtime/index.js";
3
3
  export { FilteredExecutionPlane } from "./runtime/filtered-plane.js";
4
4
  export { SubAgentOrchestrator, defaultSubAgentOrchestrator, spawnStandalone } from "./runtime/sub-agent-orchestrator.js";
5
5
  export type { SubAgentRunContext } from "./runtime/sub-agent-orchestrator.js";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { RuntimeRunner, collectText, InMemorySessionLog, LocalExecutionPlane, } from "./runtime/index.js";
1
+ export { RuntimeRunner, collectText, InMemorySessionLog, LocalExecutionPlane, DEFAULT_NATIVE_ATTENTION_POLICY, DEFAULT_NATIVE_GOVERNANCE_POLICY, DEFAULT_SANDBOX_POLICY, assertNativeProfile, osProfile, validateDeclarativePolicy, } from "./runtime/index.js";
2
2
  export { FilteredExecutionPlane } from "./runtime/filtered-plane.js";
3
3
  export { SubAgentOrchestrator, defaultSubAgentOrchestrator, spawnStandalone } from "./runtime/sub-agent-orchestrator.js";
4
4
  export { Governance } from "./governance.js";
@@ -2,6 +2,8 @@ export type { SessionEvent, SessionLog } from "./session-log.js";
2
2
  export { InMemorySessionLog } from "./session-log.js";
3
3
  export type { RunContext, ExecutionPlane } from "./execution-plane.js";
4
4
  export { LocalExecutionPlane } from "./execution-plane.js";
5
- export type { RuntimeOptions } from "./runner.js";
5
+ export type { MemoryPolicy, MemoryWriteRateLimit, ResourceQuota, RuntimeOptions, SchedulerBudget } from "./runner.js";
6
6
  export { RuntimeRunner, collectText } from "./runner.js";
7
7
  export { getKernel } from "./kernel.js";
8
+ export { DEFAULT_NATIVE_ATTENTION_POLICY, DEFAULT_NATIVE_GOVERNANCE_POLICY, DEFAULT_SANDBOX_POLICY, assertNativeProfile, osProfile, validateDeclarativePolicy, } from "./os-profile.js";
9
+ export type { NativeOsProfile, OsProfileId } from "./os-profile.js";
@@ -2,3 +2,4 @@ export { InMemorySessionLog } from "./session-log.js";
2
2
  export { LocalExecutionPlane } from "./execution-plane.js";
3
3
  export { RuntimeRunner, collectText } from "./runner.js";
4
4
  export { getKernel } from "./kernel.js";
5
+ export { DEFAULT_NATIVE_ATTENTION_POLICY, DEFAULT_NATIVE_GOVERNANCE_POLICY, DEFAULT_SANDBOX_POLICY, assertNativeProfile, osProfile, validateDeclarativePolicy, } from "./os-profile.js";
@@ -12,6 +12,7 @@ export function categoryForKind(kind) {
12
12
  case "large_result_spooled":
13
13
  case "memory_written":
14
14
  case "memory_queried":
15
+ case "memory_validation_failed":
15
16
  return "mm";
16
17
  case "agent_process_changed":
17
18
  return "proc";
@@ -190,6 +191,13 @@ export function kernelObservationToSessionEvent(obs, turn, opts = {}) {
190
191
  requested_k: obs.requested_k ?? 0,
191
192
  requires_async_response: obs.requires_async_response ?? false,
192
193
  });
194
+ case "memory_validation_failed":
195
+ return withCategory({
196
+ kind: "memory_validation_failed",
197
+ turn: t,
198
+ memory_id: obs.memory_id ?? "",
199
+ error: obs.error ?? "",
200
+ });
193
201
  default:
194
202
  return null;
195
203
  }
@@ -91,6 +91,8 @@ export interface KernelObservation {
91
91
  query_context?: string;
92
92
  requested_k?: number;
93
93
  requires_async_response?: boolean;
94
+ /** memory_validation_failed (Phase 7). */
95
+ error?: string;
94
96
  }
95
97
  export declare function toolSchemaToKernel(schema: ToolSchema): Record<string, unknown>;
96
98
  export declare function skillMetadataToKernel(skill: SkillMetadata): Record<string, unknown>;
@@ -1,7 +1,30 @@
1
1
  import type { GovernancePolicy } from "../governance.js";
2
+ export type OsProfileId = "native";
3
+ export interface NativeOsProfile {
4
+ id: OsProfileId;
5
+ attentionPolicy: {
6
+ maxQueueSize?: number;
7
+ };
8
+ governancePolicy: GovernancePolicy;
9
+ }
2
10
  /** Default attention policy for native profile smoke tests. */
3
11
  export declare const DEFAULT_NATIVE_ATTENTION_POLICY: {
4
12
  maxQueueSize: number;
5
13
  };
6
14
  /** Permissive governance policy for native runs that do not need AskUser. */
7
15
  export declare const DEFAULT_NATIVE_GOVERNANCE_POLICY: GovernancePolicy;
16
+ /** Default restrictive sandbox policy template requiring confirmation for modification/execution. */
17
+ export declare const DEFAULT_SANDBOX_POLICY: GovernancePolicy;
18
+ /** Resolve a named OS profile into concrete kernel-owned policy defaults. */
19
+ export declare function osProfile(profile?: OsProfileId | NativeOsProfile): NativeOsProfile;
20
+ /** Assert that a runtime is using a valid native microkernel policy profile. */
21
+ export declare function assertNativeProfile(profile?: OsProfileId | NativeOsProfile): NativeOsProfile;
22
+ /**
23
+ * Validates the declarative policies statically to prevent runtime crashes when loaded into the microkernel.
24
+ */
25
+ export declare function validateDeclarativePolicy(govPolicy?: GovernancePolicy, attentionPolicy?: {
26
+ maxQueueSize?: number;
27
+ }): {
28
+ valid: boolean;
29
+ errors: string[];
30
+ };
@@ -4,3 +4,68 @@ export const DEFAULT_NATIVE_ATTENTION_POLICY = { maxQueueSize: 64 };
4
4
  export const DEFAULT_NATIVE_GOVERNANCE_POLICY = {
5
5
  rules: [{ pattern: "*", action: "allow" }],
6
6
  };
7
+ /** Default restrictive sandbox policy template requiring confirmation for modification/execution. */
8
+ export const DEFAULT_SANDBOX_POLICY = {
9
+ rules: [
10
+ { pattern: "read_file", action: "allow" },
11
+ { pattern: "write_file", action: "ask_user" },
12
+ { pattern: "run_command", action: "ask_user" },
13
+ { pattern: "*", action: "deny" },
14
+ ],
15
+ };
16
+ /** Resolve a named OS profile into concrete kernel-owned policy defaults. */
17
+ export function osProfile(profile = "native") {
18
+ if (typeof profile !== "string")
19
+ return profile;
20
+ if (profile !== "native")
21
+ throw new Error(`Unsupported OS profile: ${profile}`);
22
+ return {
23
+ id: "native",
24
+ attentionPolicy: DEFAULT_NATIVE_ATTENTION_POLICY,
25
+ governancePolicy: DEFAULT_NATIVE_GOVERNANCE_POLICY,
26
+ };
27
+ }
28
+ /** Assert that a runtime is using a valid native microkernel policy profile. */
29
+ export function assertNativeProfile(profile = "native") {
30
+ const resolved = osProfile(profile);
31
+ if (resolved.id !== "native") {
32
+ throw new Error(`Unsupported OS profile: ${resolved.id}`);
33
+ }
34
+ const validation = validateDeclarativePolicy(resolved.governancePolicy, resolved.attentionPolicy);
35
+ if (!validation.valid) {
36
+ throw new Error(`Invalid native OS profile: ${validation.errors.join("; ")}`);
37
+ }
38
+ return resolved;
39
+ }
40
+ /**
41
+ * Validates the declarative policies statically to prevent runtime crashes when loaded into the microkernel.
42
+ */
43
+ export function validateDeclarativePolicy(govPolicy, attentionPolicy) {
44
+ const errors = [];
45
+ if (govPolicy) {
46
+ if (!Array.isArray(govPolicy.rules)) {
47
+ errors.push("GovernancePolicy rules must be an array");
48
+ }
49
+ else {
50
+ govPolicy.rules.forEach((rule, idx) => {
51
+ if (!rule.pattern || typeof rule.pattern !== "string") {
52
+ errors.push(`Rule[${idx}] pattern is missing or not a string`);
53
+ }
54
+ if (!["allow", "deny", "ask_user"].includes(rule.action)) {
55
+ errors.push(`Rule[${idx}] action '${rule.action}' is invalid. Allowed: allow, deny, ask_user`);
56
+ }
57
+ });
58
+ }
59
+ }
60
+ if (attentionPolicy) {
61
+ if (attentionPolicy.maxQueueSize !== undefined) {
62
+ if (typeof attentionPolicy.maxQueueSize !== "number" || attentionPolicy.maxQueueSize <= 0) {
63
+ errors.push("AttentionPolicy maxQueueSize must be a positive integer");
64
+ }
65
+ }
66
+ }
67
+ return {
68
+ valid: errors.length === 0,
69
+ errors,
70
+ };
71
+ }
@@ -8,7 +8,37 @@ import type { ExecutionPlane } from "./execution-plane.js";
8
8
  import { type GovernancePolicy } from "../governance.js";
9
9
  import type { AgentRunSpec, SubAgentResult, MilestonePolicy, MilestoneContract, MilestoneCheckResult } from "./types/agent.js";
10
10
  import { type SubAgentOrchestrator } from "./sub-agent-orchestrator.js";
11
+ import { type NativeOsProfile, type OsProfileId } from "./os-profile.js";
11
12
  import { LargeResultSpool } from "./large-result-spool.js";
13
+ export interface MemoryWriteRateLimit {
14
+ maxWrites: number;
15
+ windowMs: number;
16
+ }
17
+ export interface ResourceQuota {
18
+ /** Max sub-agents in the `running` state at once; further spawns are denied while at cap. */
19
+ maxConcurrentSubagents?: number;
20
+ /** Max sub-agent nesting depth (direct children of the root loop are depth 1). */
21
+ maxSpawnDepth?: number;
22
+ /** Rolling-window memory-write rate limit: at most `maxWrites` per any `windowMs` span. */
23
+ memoryWritesPerWindow?: MemoryWriteRateLimit;
24
+ }
25
+ export interface SchedulerBudget {
26
+ maxWallMs?: number;
27
+ }
28
+ /**
29
+ * Long-term memory policy (`set_memory_policy`) — opt-in, kernel-enforced. `validationEnabled:
30
+ * false` admits writes without validation, `maxContentBytes` / `maxNameLength` override the
31
+ * validation limits, and `retrievalTopK` caps `query_memory` breadth. `memoryPath` /
32
+ * `staleWarningDays` are carried for SDK recall I/O. Omitted fields keep the kernel defaults.
33
+ */
34
+ export interface MemoryPolicy {
35
+ memoryPath?: string;
36
+ staleWarningDays?: number;
37
+ retrievalTopK?: number;
38
+ validationEnabled?: boolean;
39
+ maxContentBytes?: number;
40
+ maxNameLength?: number;
41
+ }
12
42
  export interface RuntimeOptions {
13
43
  provider: LLMProvider;
14
44
  sessionLog: SessionLog;
@@ -25,10 +55,17 @@ export interface RuntimeOptions {
25
55
  knowledgeSource?: KnowledgeSource;
26
56
  signalSource?: SignalSource;
27
57
  extensions?: Record<string, unknown>;
58
+ /** Named or concrete OS profile. Defaults to the native microkernel profile. */
59
+ osProfile?: OsProfileId | NativeOsProfile;
28
60
  governancePolicy?: GovernancePolicy;
29
61
  attentionPolicy?: {
30
62
  maxQueueSize?: number;
31
63
  };
64
+ schedulerBudget?: SchedulerBudget;
65
+ resourceQuota?: ResourceQuota;
66
+ memoryPolicy?: MemoryPolicy;
67
+ tokenizer?: string;
68
+ enablePlanTool?: boolean;
32
69
  onToolSuspend?: (event: ToolSuspendEvent) => Promise<unknown> | unknown;
33
70
  onPermissionRequest?: (event: PermissionRequestEvent) => Promise<PermissionResponse | boolean> | PermissionResponse | boolean;
34
71
  subAgentOrchestrator?: SubAgentOrchestrator;
@@ -8,7 +8,7 @@ import { forceCompact, kernelAction, kernelApply, kernelMaybeAction, messageToKe
8
8
  import { agentRunSpecToKernel, findSpawnProcessObservation, milestoneCheckPass, milestoneCheckResultToKernel, spawnObservationToManifest, subAgentResultToKernel, } from "./types/agent.js";
9
9
  import { defaultSubAgentOrchestrator } from "./sub-agent-orchestrator.js";
10
10
  import { kernelObservationToSessionEvent, withCategory } from "./kernel-event-log.js";
11
- import { DEFAULT_NATIVE_ATTENTION_POLICY, DEFAULT_NATIVE_GOVERNANCE_POLICY } from "./os-profile.js";
11
+ import { assertNativeProfile } from "./os-profile.js";
12
12
  import { LargeResultSpool } from "./large-result-spool.js";
13
13
  export class RuntimeRunner {
14
14
  opts;
@@ -259,6 +259,18 @@ export class RuntimeRunner {
259
259
  timeoutMs: effectiveTimeoutMs !== undefined ? BigInt(effectiveTimeoutMs) : undefined,
260
260
  });
261
261
  this.activeKernel = runtime;
262
+ if (this.opts.tokenizer) {
263
+ kernelApply(runtime, this.pendingObservations, {
264
+ kind: "set_tokenizer",
265
+ name: this.opts.tokenizer,
266
+ });
267
+ }
268
+ if (this.opts.enablePlanTool !== undefined) {
269
+ kernelApply(runtime, this.pendingObservations, {
270
+ kind: "set_plan_tool_enabled",
271
+ enabled: this.opts.enablePlanTool,
272
+ });
273
+ }
262
274
  kernelApply(runtime, this.pendingObservations, {
263
275
  kind: "set_tools",
264
276
  tools: this.opts.executionPlane.schemas().map(toolSchemaToKernel),
@@ -273,7 +285,7 @@ export class RuntimeRunner {
273
285
  if (this.opts.initialMemory) {
274
286
  for (const mem of this.opts.initialMemory) {
275
287
  kernelApply(runtime, this.pendingObservations, {
276
- kind: "add_memory_message",
288
+ kind: "add_knowledge_message",
277
289
  content: mem,
278
290
  tokens: Math.max(1, Math.ceil(mem.length / 4)),
279
291
  });
@@ -327,8 +339,9 @@ export class RuntimeRunner {
327
339
  if (this.opts.runSpec) {
328
340
  startPayload.run_spec = agentRunSpecToKernel(this.opts.runSpec);
329
341
  }
330
- const attentionPolicy = this.opts.attentionPolicy ?? DEFAULT_NATIVE_ATTENTION_POLICY;
331
- const governancePolicy = this.opts.governancePolicy ?? DEFAULT_NATIVE_GOVERNANCE_POLICY;
342
+ const osProfile = assertNativeProfile(this.opts.osProfile ?? "native");
343
+ const attentionPolicy = this.opts.attentionPolicy ?? osProfile.attentionPolicy;
344
+ const governancePolicy = this.opts.governancePolicy ?? osProfile.governancePolicy;
332
345
  kernelApply(runtime, this.pendingObservations, governancePolicyToKernelEvent(governancePolicy));
333
346
  kernelApply(runtime, this.pendingObservations, {
334
347
  kind: "set_attention_policy",
@@ -336,6 +349,46 @@ export class RuntimeRunner {
336
349
  ? { max_queue_size: attentionPolicy.maxQueueSize }
337
350
  : {}),
338
351
  });
352
+ if (this.opts.schedulerBudget) {
353
+ kernelApply(runtime, this.pendingObservations, {
354
+ kind: "set_scheduler_budget",
355
+ ...(this.opts.schedulerBudget.maxWallMs !== undefined
356
+ ? { max_wall_ms: this.opts.schedulerBudget.maxWallMs }
357
+ : {}),
358
+ });
359
+ }
360
+ if (this.opts.resourceQuota) {
361
+ const q = this.opts.resourceQuota;
362
+ kernelApply(runtime, this.pendingObservations, {
363
+ kind: "set_resource_quota",
364
+ quota: {
365
+ ...(q.maxConcurrentSubagents !== undefined
366
+ ? { max_concurrent_subagents: q.maxConcurrentSubagents }
367
+ : {}),
368
+ ...(q.maxSpawnDepth !== undefined ? { max_spawn_depth: q.maxSpawnDepth } : {}),
369
+ ...(q.memoryWritesPerWindow !== undefined
370
+ ? {
371
+ memory_writes_per_window: [
372
+ q.memoryWritesPerWindow.maxWrites,
373
+ q.memoryWritesPerWindow.windowMs,
374
+ ],
375
+ }
376
+ : {}),
377
+ },
378
+ });
379
+ }
380
+ if (this.opts.memoryPolicy) {
381
+ const m = this.opts.memoryPolicy;
382
+ kernelApply(runtime, this.pendingObservations, {
383
+ kind: "set_memory_policy",
384
+ ...(m.memoryPath !== undefined ? { memory_path: m.memoryPath } : {}),
385
+ ...(m.staleWarningDays !== undefined ? { stale_warning_days: m.staleWarningDays } : {}),
386
+ ...(m.retrievalTopK !== undefined ? { retrieval_top_k: m.retrievalTopK } : {}),
387
+ ...(m.validationEnabled !== undefined ? { validation_enabled: m.validationEnabled } : {}),
388
+ ...(m.maxContentBytes !== undefined ? { max_content_bytes: m.maxContentBytes } : {}),
389
+ ...(m.maxNameLength !== undefined ? { max_name_length: m.maxNameLength } : {}),
390
+ });
391
+ }
339
392
  let action = resumeMidRun
340
393
  ? kernelAction(runtime, this.pendingObservations, { kind: "resume" })
341
394
  : kernelAction(runtime, this.pendingObservations, startPayload);
@@ -225,6 +225,13 @@ export type SessionEvent = {
225
225
  query_context: string;
226
226
  requested_k: number;
227
227
  requires_async_response: boolean;
228
+ } | {
229
+ kind: "memory_validation_failed";
230
+ turn: number;
231
+ category?: KernelEventCategory;
232
+ primitive?: KernelPrimitive;
233
+ memory_id: string;
234
+ error: string;
228
235
  } | {
229
236
  kind: "run_terminal";
230
237
  reason: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstrike/wasm",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
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.5"
18
+ "@deepstrike/wasm-kernel": "0.2.6"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/jest": "^30.0.0",