@deepstrike/wasm 0.2.74 → 0.2.75

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.
@@ -0,0 +1,24 @@
1
+ /** Tool-call argument text is model-authored. A call whose arguments are not a JSON object (a
2
+ * truncated stream, prose, an array) must reach the executor as-is so it fails as an invalid
3
+ * call — rewriting it to `{}` would run the tool with empty arguments the model never wrote. */
4
+ /** Canonical text for a model-authored argument string: re-serialized when it is a JSON object,
5
+ * `{}` when empty, and the raw text verbatim otherwise. */
6
+ export declare function toolArgumentsText(raw: string | undefined): string;
7
+ /** Wire value handed to the kernel: the object when the text is one, the raw string otherwise
8
+ * (the kernel carries arguments opaquely and hands the same value back on `execute_tools`). */
9
+ export declare function toolArgumentsToWire(raw: string | undefined): Record<string, unknown> | string;
10
+ /** Inverse of {@link toolArgumentsToWire}: kernel-carried arguments back to SDK text. */
11
+ export declare function toolArgumentsFromWire(value: unknown): string;
12
+ /** `{ rawArguments }` for a streamed `tool_call` event whose text is not a JSON object. */
13
+ export declare function malformedToolArguments(raw: string | undefined): {
14
+ rawArguments?: string;
15
+ };
16
+ export type ParsedToolArguments = {
17
+ ok: true;
18
+ args: Record<string, unknown>;
19
+ } | {
20
+ ok: false;
21
+ error: string;
22
+ };
23
+ /** Parse arguments for execution. Anything but a JSON object is an invalid call. */
24
+ export declare function parseToolCallArguments(raw: string | undefined): ParsedToolArguments;
@@ -0,0 +1,61 @@
1
+ /** Tool-call argument text is model-authored. A call whose arguments are not a JSON object (a
2
+ * truncated stream, prose, an array) must reach the executor as-is so it fails as an invalid
3
+ * call — rewriting it to `{}` would run the tool with empty arguments the model never wrote. */
4
+ /** Canonical text for a model-authored argument string: re-serialized when it is a JSON object,
5
+ * `{}` when empty, and the raw text verbatim otherwise. */
6
+ export function toolArgumentsText(raw) {
7
+ const text = raw ?? "";
8
+ if (text.trim() === "")
9
+ return "{}";
10
+ const parsed = tryParse(text);
11
+ return isJsonObject(parsed) ? JSON.stringify(parsed) : text;
12
+ }
13
+ /** Wire value handed to the kernel: the object when the text is one, the raw string otherwise
14
+ * (the kernel carries arguments opaquely and hands the same value back on `execute_tools`). */
15
+ export function toolArgumentsToWire(raw) {
16
+ const text = raw ?? "";
17
+ if (text.trim() === "")
18
+ return {};
19
+ const parsed = tryParse(text);
20
+ return isJsonObject(parsed) ? parsed : text;
21
+ }
22
+ /** Inverse of {@link toolArgumentsToWire}: kernel-carried arguments back to SDK text. */
23
+ export function toolArgumentsFromWire(value) {
24
+ if (typeof value === "string")
25
+ return value;
26
+ return JSON.stringify(value ?? {});
27
+ }
28
+ /** `{ rawArguments }` for a streamed `tool_call` event whose text is not a JSON object. */
29
+ export function malformedToolArguments(raw) {
30
+ const text = raw ?? "";
31
+ if (text.trim() === "")
32
+ return {};
33
+ return isJsonObject(tryParse(text)) ? {} : { rawArguments: text };
34
+ }
35
+ /** Parse arguments for execution. Anything but a JSON object is an invalid call. */
36
+ export function parseToolCallArguments(raw) {
37
+ const text = raw ?? "";
38
+ if (text.trim() === "")
39
+ return { ok: true, args: {} };
40
+ let parsed;
41
+ try {
42
+ parsed = JSON.parse(text);
43
+ }
44
+ catch (err) {
45
+ return { ok: false, error: `arguments are not valid JSON (${err.message})` };
46
+ }
47
+ if (!isJsonObject(parsed))
48
+ return { ok: false, error: "arguments must be a JSON object" };
49
+ return { ok: true, args: parsed };
50
+ }
51
+ function tryParse(text) {
52
+ try {
53
+ return JSON.parse(text);
54
+ }
55
+ catch {
56
+ return undefined;
57
+ }
58
+ }
59
+ function isJsonObject(value) {
60
+ return typeof value === "object" && value !== null && !Array.isArray(value);
61
+ }
@@ -159,6 +159,8 @@ export interface SchedulingFactors {
159
159
  }
160
160
  export declare function workflowNodeStatusFromTermination(termination: TerminationReason | string): WorkflowNodeStatus;
161
161
  export interface WorkflowNodeSpec {
162
+ /** Caller-declared wire identity; absent ⇒ the canonical lowering assigns a positional id. */
163
+ nodeId?: string;
162
164
  task: WorkflowTaskSpec;
163
165
  role: KernelAgentRole;
164
166
  isolation?: AgentIsolation;
@@ -240,6 +242,8 @@ export declare function workflowNodeOutcomeFromKernel(raw: KernelWorkflowNodeOut
240
242
  /** Per-node spawn descriptor carried in the `workflow_batch_spawned` observation. */
241
243
  export interface WorkflowSpawnInfo {
242
244
  agent_id: string;
245
+ /** The kernel-minted attempt this launch runs as; echoed back on the node's completion. */
246
+ attempt_id?: string;
243
247
  goal: string;
244
248
  role: string;
245
249
  isolation: string;
@@ -203,6 +203,7 @@ export function workflowNodeSpecToKernel(n) {
203
203
  const kind = nodeKindToKernel(n);
204
204
  const schedulingFactors = schedulingFactorsToKernel(n.schedulingFactors);
205
205
  return {
206
+ ...(n.nodeId ? { node_id: n.nodeId } : {}),
206
207
  task: workflowTaskToKernel(n.task),
207
208
  role: n.role,
208
209
  isolation: n.isolation ?? "shared",
@@ -254,6 +255,7 @@ export function workflowSpecToKernel(spec) {
254
255
  * (append) and `start_workflow` (workflow authoring: author a sub-workflow), so the two tools never drift. */
255
256
  const workflowNodesArraySchema = {
256
257
  type: "array",
258
+ description: "Workflow nodes (a DAG); each runs as a gated sub-agent. `dependsOn` is batch-relative.",
257
259
  items: {
258
260
  type: "object",
259
261
  properties: {
@@ -261,58 +263,9 @@ const workflowNodesArraySchema = {
261
263
  role: { type: "string", enum: ["explore", "plan", "implement", "verify", "custom"] },
262
264
  isolation: { type: "string", enum: ["shared", "read_only", "worktree", "remote"] },
263
265
  contextInheritance: { type: "string", enum: ["none", "system_only", "full"] },
264
- trust: { type: "string", enum: ["trusted", "quarantined"] },
265
266
  outputSchema: { type: "object", description: "Optional JSON Schema the node's output must conform to." },
266
267
  modelHint: { type: "string", description: "Preferred model for this node (e.g. \"opus\"/\"sonnet\"); the host routes it." },
267
- reducer: { type: "string", description: "Make this a deterministic reduce node (no LLM); names a registered reducer." },
268
- loop: {
269
- type: "object",
270
- description: "Make this a loop node: re-run up to maxIters times, ending early when the agent reports done.",
271
- properties: { maxIters: { type: "integer", description: "Hard iteration cap." } },
272
- required: ["maxIters"],
273
- },
274
- classify: {
275
- type: "object",
276
- description: "Make this a classify node: pick one branch label; that branch's nodes run, the rest are pruned.",
277
- properties: {
278
- branches: {
279
- type: "array",
280
- items: {
281
- type: "object",
282
- properties: {
283
- label: { type: "string" },
284
- nodes: { type: "array", items: { type: "integer" }, description: "Batch-relative node indices for this branch." },
285
- },
286
- required: ["label", "nodes"],
287
- },
288
- },
289
- },
290
- required: ["branches"],
291
- },
292
- tournament: {
293
- type: "object",
294
- description: "Make this a tournament controller: generate each entrant, then pairwise-judge to one winner.",
295
- properties: {
296
- entrants: {
297
- type: "array",
298
- description: "≥2 candidate tasks to generate and judge.",
299
- items: {
300
- oneOf: [
301
- { type: "string" },
302
- { type: "object", properties: { goal: { type: "string" }, criteria: { type: "array", items: { type: "string" } } }, required: ["goal"] },
303
- ],
304
- },
305
- },
306
- },
307
- required: ["entrants"],
308
- },
309
- tokenBudget: { type: "integer", description: "Cap this node's child run at this many cumulative tokens." },
310
268
  dependsOn: { type: "array", items: { type: "integer" } },
311
- depPolicy: {
312
- type: "string",
313
- enum: ["all_success", "accept_partial", "all_terminal", "optional"],
314
- description: "How dependency terminal states gate this node; defaults to all_success.",
315
- },
316
269
  },
317
270
  required: ["task", "role"],
318
271
  },
@@ -321,9 +274,7 @@ export const submitWorkflowNodesTool = {
321
274
  name: "submit_workflow_nodes",
322
275
  description: "Append new nodes to the running workflow DAG (dynamic fan-out / loop-until-done). Each node " +
323
276
  "spawns as a gated sub-agent. Use when you discover more work that should run as its own node. " +
324
- "A node may declare ONE control-flow kind — `loop` / `classify` / `tournament` / `reducer` — " +
325
- "otherwise it is a plain spawn. Within a submission, `dependsOn` and `classify.branches[].nodes` " +
326
- "are batch-relative (index 0 = this batch's first node).",
277
+ "Within a submission, `dependsOn` is batch-relative (index 0 = this batch's first node).",
327
278
  parameters: JSON.stringify({
328
279
  type: "object",
329
280
  properties: { nodes: workflowNodesArraySchema },
@@ -335,9 +286,9 @@ export const submitWorkflowNodesTool = {
335
286
  * (a `WorkflowSpec` is a node batch). Top-level bootstrap uses (the `LoadWorkflow` syscall). */
336
287
  export const startWorkflowTool = {
337
288
  name: "start_workflow",
338
- description: "Author and run a sub-workflow: a DAG of nodes (fan-out / classify / tournament / loop / reduce) " +
339
- "composed onto the current run. Use to structure a multi-step task as its own harness. The nodes " +
340
- "spawn as gated sub-agents; `dependsOn` / `classify.branches[].nodes` are spec-relative.",
289
+ description: "Author and run a sub-workflow: a DAG of nodes (fan-out / fan-in) composed onto the current run. " +
290
+ "Use to structure a multi-step task as its own harness. The nodes spawn as gated sub-agents; " +
291
+ "`dependsOn` is spec-relative.",
341
292
  parameters: JSON.stringify({
342
293
  type: "object",
343
294
  properties: {
package/dist/types.d.ts CHANGED
@@ -114,7 +114,8 @@ export interface ToolCallEvent extends StreamEvent {
114
114
  type: "tool_call";
115
115
  id: string;
116
116
  name: string;
117
- arguments: Record<string, unknown>;
117
+ arguments: Record<string, unknown>; /** The model's argument text, present only when it was not a JSON object (then `arguments` is `{}`); executed so the call fails as invalid. */
118
+ rawArguments?: string;
118
119
  }
119
120
  export interface ToolResultEvent extends StreamEvent {
120
121
  type: "tool_result";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstrike/wasm",
3
- "version": "0.2.74",
3
+ "version": "0.2.75",
4
4
  "description": "DeepStrike WASM SDK — browser, Cloudflare Workers, Deno Deploy",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -14,10 +14,10 @@
14
14
  "build:wasm": "wasm-pack build ../crates/deepstrike-wasm --target bundler --out-dir ../../wasm/pkg",
15
15
  "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc",
16
16
  "test": "node --experimental-vm-modules node_modules/.bin/jest",
17
- "test:canonical-binding": "wasm-pack build ../crates/deepstrike-wasm --target nodejs --dev --out-dir ../../wasm/pkg-node && node tests/canonical-binding.node.cjs && node tests/golden-fixtures-sweep.node.cjs"
17
+ "test:canonical-binding": "wasm-pack build ../crates/deepstrike-wasm --target nodejs --dev --out-dir ../../wasm/pkg-node && node tests/canonical-binding.node.cjs && node tests/golden-fixtures-sweep.node.cjs && npm run build && node tests/boundary-p0-regressions.node.mjs && node tests/boundary-p1-regressions.node.mjs && node tests/boundary-p2-regressions.node.mjs"
18
18
  },
19
19
  "dependencies": {
20
- "@deepstrike/wasm-kernel": "0.2.74"
20
+ "@deepstrike/wasm-kernel": "0.2.75"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/jest": "^30.0.0",