@deepstrike/sdk 0.2.35 → 0.2.37

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 (35) hide show
  1. package/README.md +6 -6
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +2 -0
  4. package/dist/os/public.d.ts +1 -1
  5. package/dist/os/public.js +1 -1
  6. package/dist/runtime/facade.js +11 -11
  7. package/dist/runtime/kernel-event-log.d.ts +0 -6
  8. package/dist/runtime/kernel-event-log.js +38 -62
  9. package/dist/runtime/kernel-step.d.ts +11 -0
  10. package/dist/runtime/kernel-step.js +12 -0
  11. package/dist/runtime/large-result-spool.d.ts +7 -0
  12. package/dist/runtime/large-result-spool.js +25 -0
  13. package/dist/runtime/loop-driver.d.ts +108 -0
  14. package/dist/runtime/loop-driver.js +198 -0
  15. package/dist/runtime/os-snapshot.d.ts +0 -1
  16. package/dist/runtime/os-snapshot.js +0 -19
  17. package/dist/runtime/reactive-session.d.ts +5 -2
  18. package/dist/runtime/reactive-session.js +17 -4
  19. package/dist/runtime/run-group.d.ts +9 -0
  20. package/dist/runtime/run-group.js +18 -4
  21. package/dist/runtime/runner.d.ts +151 -12
  22. package/dist/runtime/runner.js +568 -155
  23. package/dist/runtime/session-log.d.ts +31 -54
  24. package/dist/runtime/session-repair.d.ts +29 -7
  25. package/dist/runtime/session-repair.js +37 -9
  26. package/dist/runtime/sub-agent-orchestrator.d.ts +12 -0
  27. package/dist/runtime/sub-agent-orchestrator.js +54 -30
  28. package/dist/runtime/workflow-control-flow.d.ts +10 -2
  29. package/dist/runtime/workflow-control-flow.js +27 -6
  30. package/dist/signals/gateway.d.ts +4 -2
  31. package/dist/signals/gateway.js +8 -1
  32. package/dist/types/agent.d.ts +40 -2
  33. package/dist/types/agent.js +25 -1
  34. package/dist/types.d.ts +2 -0
  35. package/package.json +2 -2
@@ -2,7 +2,12 @@ import type { Message, ToolSchema } from "../types.js";
2
2
  export type KernelAgentRole = "explore" | "plan" | "implement" | "verify" | "custom";
3
3
  export type AgentIsolation = "shared" | "read_only" | "worktree" | "remote";
4
4
  export type ContextInheritance = "none" | "system_only" | "full";
5
- export type TerminationReason = "completed" | "max_turns" | "token_budget" | "timeout" | "user_abort" | "error" | "milestone_exceeded";
5
+ export type TerminationReason = "completed" | "max_turns" | "token_budget" | "timeout" | "user_abort" | "error" | "milestone_exceeded"
6
+ /** v0.2.35 recovery ladder: compaction exhausted and the prompt still exceeds the provider window. */
7
+ | "context_overflow"
8
+ /** Repeat-fuse escalation: the same tool call (name AND args) re-issued past `terminateAfter` —
9
+ * a stall, distinct from `max_turns` which productive runs can also hit. */
10
+ | "no_progress";
6
11
  export type MilestonePolicy = "require_verifier" | "terminate" | "auto_pass";
7
12
  export interface AgentIdentity {
8
13
  agentId: string;
@@ -14,6 +19,16 @@ export interface AgentCapabilityFilter {
14
19
  allowedKinds?: string[];
15
20
  allowedIds?: string[];
16
21
  }
22
+ export interface LoopRoundSpec {
23
+ /** Hard round cap across the loop's lifetime; continue/sleep at the cap is coerced to stop. */
24
+ maxRounds?: number;
25
+ /** Sleep clamp floor (ms). */
26
+ minSleepMs?: number;
27
+ /** Sleep clamp ceiling (ms). */
28
+ maxSleepMs?: number;
29
+ /** Fallback when a round ends without a pace call: "stop" (goal loops, default) | "sleep" (cron loops). */
30
+ defaultAction?: "stop" | "sleep";
31
+ }
17
32
  export interface AgentRunSpec {
18
33
  identity: AgentIdentity;
19
34
  role: KernelAgentRole;
@@ -23,11 +38,20 @@ export interface AgentRunSpec {
23
38
  capabilityFilter?: AgentCapabilityFilter;
24
39
  milestones?: MilestoneContract;
25
40
  metadata?: Record<string, unknown>;
41
+ /** ③ loop-agent rounds: presence makes this run ONE round of a paced loop (gates the
42
+ * kernel `pace` meta-tool and arms the pacing trap). */
43
+ loopRound?: LoopRoundSpec;
26
44
  /** M1/G3: per-agent model preference (e.g. "opus"/"sonnet"/"haiku"); the host resolves it to a
27
45
  * provider via `RuntimeOptions.providerFor`. Host-side routing only — not sent to the kernel. */
28
46
  modelHint?: string;
29
47
  /** M4/G5: cumulative token cap for this sub-agent's run (sets the child kernel's `maxTotalTokens`). */
30
48
  tokenBudget?: number;
49
+ /** O3: per-child turn cap (sets the child runner's `maxTurns`; falls back to the parent's). A child
50
+ * that exhausts it terminates `max_turns` — the parent reads the termination and decides retry/skip. */
51
+ maxTurns?: number;
52
+ /** O3: per-child wall-clock cap in milliseconds (sets the child runner's `timeoutMs`; falls back to
53
+ * the parent's). A hung child terminates `timeout` instead of stalling the parent indefinitely. */
54
+ maxWallMs?: number;
31
55
  }
32
56
  /** Kernel process-table observation (Phase 3 canonical spawn signal). */
33
57
  export interface AgentProcessChangedObservation {
@@ -61,6 +85,11 @@ export interface LoopResult {
61
85
  classifyBranch?: string;
62
86
  /** A#2 tournament verdict: a judge reports the winning entrant's agent id here. Sent only when set. */
63
87
  tournamentWinner?: string;
88
+ /** ③ loop-agent pacing: the kernel-adjudicated after-round decision, surfaced by the orchestrator
89
+ * from the child's done event. For a loop-node iteration this is the PRIMARY continuation
90
+ * vocabulary (stop → loopContinue=false); the legacy text-sniffed signal is the fallback.
91
+ * SDK-internal — stripped by `subAgentResultToKernel`. */
92
+ paceDecision?: import("../runtime/kernel-step.js").PaceDecision;
64
93
  }
65
94
  export interface SubAgentResult {
66
95
  agentId: string;
@@ -136,6 +165,10 @@ export interface WorkflowNodeSpec {
136
165
  };
137
166
  /** M4/G5: cap this node's child run at `tokenBudget` cumulative tokens (the per-node "use N tokens"). */
138
167
  tokenBudget?: number;
168
+ /** O3: cap this node's child run at `maxTurns` provider turns (falls back to the parent's). */
169
+ maxTurns?: number;
170
+ /** O3: cap this node's child run at `maxWallMs` wall-clock milliseconds. */
171
+ maxWallMs?: number;
139
172
  /** Indices of nodes this node depends on. */
140
173
  dependsOn?: number[];
141
174
  }
@@ -157,7 +190,8 @@ export interface WorkflowSpawnInfo {
157
190
  output_schema?: Record<string, unknown>;
158
191
  /** G2: for a reduce node, the name of the registered host function to run (no LLM). */
159
192
  reducer?: string;
160
- /** G2: the dependency agent ids whose outputs a reduce node consumes. */
193
+ /** The dependency agent ids for EVERY dependent node (W-N2: a DAG edge carries data). A reduce
194
+ * node's registered function consumes them; every other node gets its deps' outputs in context. */
161
195
  input_agent_ids?: string[];
162
196
  /** A#2: present only for a tournament *judge* spawn — the two entrant agent ids whose produced
163
197
  * outputs this judge compares. The runner looks them up and reports the winner as `tournamentWinner`. */
@@ -173,6 +207,10 @@ export interface WorkflowSpawnInfo {
173
207
  classify_labels?: string[];
174
208
  /** M4/G5: the node's per-node cumulative token cap, if set — the runner caps the child run here. */
175
209
  token_budget?: number;
210
+ /** O3: per-node turn cap → the child run's `maxTurns`. */
211
+ max_turns?: number;
212
+ /** O3: per-node wall-clock cap (ms) → the child run's timeout. */
213
+ max_wall_ms?: number;
176
214
  }
177
215
  /** G4 budget-as-signal: the workflow's remaining headroom under the active quota, carried on the
178
216
  * `workflow_batch_spawned` observation so a coordinator node can scale its next submission. */
@@ -46,6 +46,14 @@ export function agentRunSpecToKernel(spec) {
46
46
  out.verification_contract_id = spec.verificationContractId;
47
47
  if (spec.milestones)
48
48
  out.milestones = milestoneContractToKernel(spec.milestones);
49
+ if (spec.loopRound) {
50
+ out.loop_round = {
51
+ ...(spec.loopRound.maxRounds !== undefined ? { max_rounds: spec.loopRound.maxRounds } : {}),
52
+ ...(spec.loopRound.minSleepMs !== undefined ? { min_sleep_ms: spec.loopRound.minSleepMs } : {}),
53
+ ...(spec.loopRound.maxSleepMs !== undefined ? { max_sleep_ms: spec.loopRound.maxSleepMs } : {}),
54
+ ...(spec.loopRound.defaultAction !== undefined ? { default_action: spec.loopRound.defaultAction } : {}),
55
+ };
56
+ }
49
57
  return out;
50
58
  }
51
59
  export function milestoneContractToKernel(contract) {
@@ -180,6 +188,9 @@ export function workflowNodeSpecToKernel(n) {
180
188
  ...(kind ? { kind } : {}),
181
189
  // M4/G5: per-node token cap (additive; omitted when unset).
182
190
  ...(n.tokenBudget != null ? { token_budget: n.tokenBudget } : {}),
191
+ // O3: per-node turn / wall-clock caps (additive; omitted when unset).
192
+ ...(n.maxTurns != null ? { max_turns: n.maxTurns } : {}),
193
+ ...(n.maxWallMs != null ? { max_wall_ms: n.maxWallMs } : {}),
183
194
  ...(n.dependsOn && n.dependsOn.length ? { depends_on: n.dependsOn } : {}),
184
195
  };
185
196
  }
@@ -356,10 +367,15 @@ export const startWorkflowTool = {
356
367
  };
357
368
  /** Build a sub-agent run spec for a kernel-generated workflow node. */
358
369
  export function workflowNodeToSpec(node, parentSessionId) {
370
+ // W-N6 transcript-as-carry: a loop node's iterations share ONE stable session id (the `-i{k}`
371
+ // suffix names the spawn, not the session), so iteration k replays the transcript of 0..k-1 —
372
+ // "do the next increment" actually sees the previous increments. The agent_id keeps the
373
+ // per-iteration suffix (kernel completion routing).
374
+ const sessionNodeId = node.loop_max_iters != null ? node.agent_id.replace(/-i\d+$/, "") : node.agent_id;
359
375
  return {
360
376
  identity: {
361
377
  agentId: node.agent_id,
362
- sessionId: `${parentSessionId}-${node.agent_id}`,
378
+ sessionId: `${parentSessionId}-${sessionNodeId}`,
363
379
  isSubAgent: true,
364
380
  parentSessionId,
365
381
  },
@@ -370,6 +386,14 @@ export function workflowNodeToSpec(node, parentSessionId) {
370
386
  ...(node.model_hint ? { modelHint: node.model_hint } : {}),
371
387
  // M4/G5: carry the node's token cap so the orchestrator can bound the child run.
372
388
  ...(node.token_budget != null ? { tokenBudget: node.token_budget } : {}),
389
+ // O3: carry the node's turn / wall-clock caps (the orchestrator already honors these).
390
+ ...(node.max_turns != null ? { maxTurns: node.max_turns } : {}),
391
+ ...(node.max_wall_ms != null ? { maxWallMs: node.max_wall_ms } : {}),
392
+ // DW-3 one continuation vocabulary: a loop ITERATION runs with the pacing trap armed, so the
393
+ // agent signals continue/stop through the kernel-adjudicated `pace` meta-tool instead of a
394
+ // text-sniffed JSON blob. One iteration = one round; the DAG (not max_rounds) caps iterations,
395
+ // and default stop means "ended without pacing" = done — the CC silence-is-completion contract.
396
+ ...(node.loop_max_iters != null ? { loopRound: { defaultAction: "stop" } } : {}),
373
397
  };
374
398
  }
375
399
  /** Build the host manifest for a kernel-generated workflow node. */
package/dist/types.d.ts CHANGED
@@ -155,6 +155,8 @@ export interface DoneEvent extends StreamEvent {
155
155
  totalTokens: number;
156
156
  status: string;
157
157
  dreamResult?: import("./memory/protocols.js").DreamResult;
158
+ /** ③ loop-agent: the kernel-adjudicated after-round decision (absent on non-loop runs). */
159
+ paceDecision?: import("./runtime/kernel-step.js").PaceDecision;
158
160
  }
159
161
  export interface ErrorEvent extends StreamEvent {
160
162
  type: "error";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstrike/sdk",
3
- "version": "0.2.35",
3
+ "version": "0.2.37",
4
4
  "description": "DeepStrike Node.js SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -72,7 +72,7 @@
72
72
  },
73
73
  "dependencies": {
74
74
  "@anthropic-ai/sdk": "^0.99.0",
75
- "@deepstrike/core": "0.2.35",
75
+ "@deepstrike/core": "0.2.37",
76
76
  "@google/generative-ai": "^0.24.1",
77
77
  "openai": "^5.23.2"
78
78
  },