@deepstrike/sdk 0.1.1 → 0.1.4

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
@@ -1,6 +1,6 @@
1
1
  # DeepStrike Node.js SDK
2
2
 
3
- Agent framework built on a Rust kernel. The kernel handles loop control, context compression, skill selection, and termination — the SDK handles all I/O.
3
+ Agent framework built on a Rust kernel. The kernel handles loop control, context compression, skill routing, governance, signal prioritization — the SDK handles all I/O.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,28 +8,48 @@ Agent framework built on a Rust kernel. The kernel handles loop control, context
8
8
  npm install @deepstrike/sdk
9
9
  ```
10
10
 
11
- Requires Node.js 18+. The Rust kernel is distributed as a pre-built native addon (`@deepstrike/core`).
11
+ Requires Node.js 18+.
12
+
13
+ ### Platform support
14
+
15
+ Pre-built native addons are available for the following platforms:
16
+
17
+ | Platform | Package |
18
+ | -------- | ------- |
19
+ | Linux x64 (glibc) | `@deepstrike/core-linux-x64-gnu` |
20
+ | Linux ARM64 (glibc) | `@deepstrike/core-linux-arm64-gnu` |
21
+ | macOS x64 | `@deepstrike/core-darwin-x64` |
22
+ | macOS ARM64 (Apple Silicon) | `@deepstrike/core-darwin-arm64` |
23
+ | Windows x64 | `@deepstrike/core-win32-x64-msvc` |
24
+
25
+ The correct platform package is selected and installed automatically via `optionalDependencies`.
26
+
27
+ > **Note:** `@deepstrike/core` is the low-level native addon package and is not intended for direct use. It is an internal dependency automatically managed by `@deepstrike/sdk`. Direct installation is only relevant when building from Rust source.
12
28
 
13
29
  ---
14
30
 
15
31
  ## Quick start
16
32
 
17
33
  ```typescript
18
- import { Agent, AnthropicProvider, tool } from "@deepstrike/sdk"
34
+ import { Agent, OpenAIProvider, tool } from "@deepstrike/sdk"
35
+
36
+ const provider = new OpenAIProvider({
37
+ apiKey: process.env.OPENAI_API_KEY,
38
+ model: "gpt-5-mini",
39
+ baseUrl: "https://api.openai.com/v1",
40
+ })
19
41
 
20
42
  const add = tool("add", "Add two numbers.", {
21
43
  type: "object",
22
44
  properties: { x: { type: "number" }, y: { type: "number" } },
23
45
  required: ["x", "y"],
24
- }, async ({ x, y }) => String((x as number) + (y as number)))
46
+ }, async ({ x, y }) => String(Number(x) + Number(y)))
25
47
 
26
- const agent = new Agent(
27
- new AnthropicProvider("sk-..."),
28
- { maxTokens: 32_000, maxTurns: 10 },
29
- )
48
+ const agent = new Agent(provider, { maxTokens: 4096 })
30
49
  agent.register(add)
31
50
 
32
- await agent.run("What is 2 + 3?")
51
+ const result = await agent.run("What is 17 + 28?")
52
+ console.log(result) // "done in 2 turns (completed)"
33
53
  ```
34
54
 
35
55
  Streaming:
@@ -38,63 +58,44 @@ Streaming:
38
58
  for await (const event of agent.runStreaming("Summarize README.md")) {
39
59
  if (event.type === "text_delta") process.stdout.write(event.delta)
40
60
  else if (event.type === "tool_call") console.log(`\n[→ ${event.name}]`)
61
+ else if (event.type === "tool_result") console.log(` = ${event.content}`)
41
62
  else if (event.type === "done") console.log(`\ndone in ${event.iterations} turns (${event.status})`)
42
63
  }
43
64
  ```
44
65
 
45
66
  ---
46
67
 
47
- ## Architecture
48
-
49
- ```
50
- src/
51
- ├── index.ts # Public exports
52
- ├── agent.ts # Agent — top-level entry point
53
- ├── types.ts # Shared type definitions
54
- ├── providers/ # LLM adapters (HTTP + streaming)
55
- ├── tools/ # tool() helper, executeTools, built-ins
56
- ├── skills/ # SkillLoader — .md file loading
57
- ├── memory/ # WorkingMemory + MemorySource/Extractor interfaces
58
- ├── knowledge/ # KnowledgeSource interface
59
- ├── harness/ # SinglePassHarness, EvalLoopHarness, QualityGate
60
- ├── signals/ # RuntimeSignal, SignalSource, ScheduledPrompt
61
- └── safety/ # PermissionManager
62
- ```
63
-
64
- The kernel (`@deepstrike/core`, Rust/NAPI) owns:
65
- - `LoopStateMachine` — drives `call_llm → execute_tools → load_skills → done`
66
- - `ContextEngine` — 5-partition context with pressure-based compression
67
- - `Governance` — tool veto authority
68
- - `SignalRouter` — external interrupt queue
69
-
70
- ---
71
-
72
68
  ## Providers
73
69
 
74
70
  | Class | Backend | Notes |
75
71
  |-------|---------|-------|
76
- | `AnthropicProvider` | Anthropic API | Native SSE, `ThinkingDelta` support |
77
72
  | `OpenAIProvider` | OpenAI API | SSE tool-call accumulation |
73
+ | `AnthropicProvider` | Anthropic API | Native SSE, `ThinkingDelta` support |
78
74
  | `QwenProvider` | DashScope | `enable_thinking` via extensions |
79
75
  | `DeepSeekProvider` | DeepSeek API | Reasoner models strip tools automatically |
80
76
  | `MiniMaxProvider` | MiniMax API | M1 reasoning via `expose_reasoning` |
81
77
  | `OllamaProvider` | Local Ollama | `http://localhost:11434` default |
78
+ | `KimiProvider` | Moonshot API | |
82
79
 
83
- ```typescript
84
- import { AnthropicProvider } from "@deepstrike/sdk"
80
+ All providers accept `RetryConfig` for exponential backoff and share a `CircuitBreaker`.
85
81
 
86
- const provider = new AnthropicProvider("sk-...", "claude-opus-4-7", {
87
- maxRetries: 5,
88
- baseDelay: 2000,
89
- })
90
- ```
82
+ ---
91
83
 
92
- Thinking / reasoning:
84
+ ## Agent options
93
85
 
94
86
  ```typescript
95
- for await (const event of agent.runStreaming("...", undefined, { enable_thinking: true })) {
96
- if (event.type === "thinking_delta") process.stdout.write(event.delta)
97
- }
87
+ const agent = new Agent(provider, {
88
+ maxTokens: 4096, // context window size
89
+ maxTurns: 25, // max turns (default 25)
90
+ timeoutMs: 60_000, // timeout in ms
91
+ extensions: { temperature: 0.1 }, // pass-through to LLM
92
+ skillDir: "./skills", // skill .md files directory
93
+ knowledgeSource: myKS, // KnowledgeSource implementation
94
+ signalSource: rx, // SignalSource for external signals
95
+ dreamStore: myStore, // DreamStore for long-term memory
96
+ agentId: "my-agent", // required with dreamStore for memory meta-tool
97
+ governance: gov, // Governance pipeline instance
98
+ })
98
99
  ```
99
100
 
100
101
  ---
@@ -102,195 +103,177 @@ for await (const event of agent.runStreaming("...", undefined, { enable_thinking
102
103
  ## Tools
103
104
 
104
105
  ```typescript
105
- import { tool, Agent } from "@deepstrike/sdk"
106
-
107
- const search = tool("search", "Search the knowledge base.", {
108
- type: "object",
109
- properties: { query: { type: "string" }, topK: { type: "number" } },
110
- required: ["query"],
111
- }, async ({ query, topK }) => mySearch(query as string, topK as number))
106
+ import { tool, readFile } from "@deepstrike/sdk"
112
107
 
113
- agent.register(search)
108
+ agent.register(tool("search", "Search.", schema, async (args) => ...))
109
+ agent.register(readFile()) // built-in: read files from disk
114
110
  agent.unregister("search")
115
- agent.blockTool("bash") // governance veto — permanent for this agent instance
111
+ agent.blockTool("bash") // governance veto
116
112
  ```
117
113
 
118
- Built-in tools: `readFile`.
119
-
120
114
  ---
121
115
 
122
116
  ## Skills
123
117
 
124
- Skills are `.md` files with YAML frontmatter. The kernel selects and injects them automatically.
118
+ Skills are `.md` files with YAML frontmatter. Set `skillDir` on the agent — the kernel auto-injects a `skill` meta-tool, and the LLM loads skills by name on demand.
119
+
120
+ ```typescript
121
+ const agent = new Agent(provider, { maxTokens: 4096, skillDir: "./skills" })
122
+ ```
125
123
 
126
124
  ```markdown
127
125
  ---
128
- name: debug
129
- description: Step-by-step debugging guide
130
- when_to_use: error, traceback, exception
131
- effort: 2
132
- estimated_tokens: 800
126
+ name: summarize
127
+ description: Summarize text into 2-3 concise bullet points
128
+ when_to_use: When you need to condense long text
129
+ effort: 1
133
130
  ---
134
-
135
- ## Debug protocol
136
- 1. Read the traceback carefully ...
137
- ```
138
-
139
- ```typescript
140
- import { Agent, SkillLoader } from "@deepstrike/sdk"
141
-
142
- const loader = new SkillLoader("~/.deepstrike/skills")
143
- const agent = new Agent(provider, { maxTokens: 32_000, maxTurns: 10, skillLoader: loader })
131
+ 1. Identify the 2-3 most important points
132
+ 2. Express each as a concise bullet
144
133
  ```
145
134
 
146
135
  ---
147
136
 
148
- ## Memory
137
+ ## Knowledge
149
138
 
150
- Implement `MemorySource` to inject persistent context before a run, and `MemoryExtractor` to persist what was learned after.
139
+ Implement `KnowledgeSource` to connect any RAG system. The kernel injects a `knowledge` meta-tool that the LLM calls on demand.
151
140
 
152
141
  ```typescript
153
- import type { MemorySource, MemoryExtractor } from "@deepstrike/sdk"
154
-
155
- class MyMemorySource implements MemorySource {
156
- async load(goal: string): Promise<string[]> {
157
- return db.query(goal)
158
- }
159
- }
160
-
161
- class MyMemoryExtractor implements MemoryExtractor {
162
- async extract(goal: string, finalText: string, turns: number): Promise<void> {
163
- await db.save(goal, finalText)
164
- }
165
- }
166
-
167
142
  const agent = new Agent(provider, {
168
- maxTokens: 32_000,
169
- maxTurns: 10,
170
- memorySource: new MyMemorySource(),
171
- memoryExtractor: new MyMemoryExtractor(),
143
+ maxTokens: 4096,
144
+ knowledgeSource: {
145
+ async retrieve(query: string, topK: number): Promise<string[]> {
146
+ return vectorDb.search(query, topK)
147
+ }
148
+ }
172
149
  })
173
150
  ```
174
151
 
175
- `WorkingMemory` is an in-process scratch pad for within-run state:
152
+ ---
153
+
154
+ ## Memory
155
+
156
+ ### WorkingMemory (in-session scratch pad)
176
157
 
177
158
  ```typescript
178
159
  import { WorkingMemory } from "@deepstrike/sdk"
179
-
180
160
  const mem = new WorkingMemory()
181
161
  mem.set("step", 1)
182
- mem.get("step") // 1
162
+ mem.get("step") // 1
163
+ mem.clear()
183
164
  ```
184
165
 
185
- ---
186
-
187
- ## Knowledge
188
-
189
- Inject run-scoped evidence (RAG results, API responses) without polluting long-term memory:
166
+ ### DreamStore (long-term memory + dreaming pipeline)
190
167
 
191
168
  ```typescript
192
- import type { KnowledgeSource } from "@deepstrike/sdk"
169
+ import type { DreamStore } from "@deepstrike/sdk"
193
170
 
194
- class VectorSearch implements KnowledgeSource {
195
- async retrieve(goal: string, topK = 5): Promise<string[]> {
196
- return vectorDb.search(goal, topK)
197
- }
171
+ class MyStore implements DreamStore {
172
+ async loadSessions(agentId) { ... }
173
+ async loadMemories(agentId) { ... }
174
+ async commit(agentId, result, existing) { ... }
175
+ async search(agentId, query, topK) { ... }
198
176
  }
199
177
 
200
178
  const agent = new Agent(provider, {
201
- maxTokens: 32_000,
202
- maxTurns: 10,
203
- knowledgeSource: new VectorSearch(),
179
+ maxTokens: 4096,
180
+ dreamStore: new MyStore(),
181
+ agentId: "my-agent", // enables `memory` meta-tool
204
182
  })
205
- ```
206
183
 
207
- Snippets are prepended as a system message before the first LLM call.
184
+ // In-session: LLM calls memory(query) → DreamStore.search()
185
+ // Post-session: trigger memory consolidation
186
+ const result = await agent.dream("my-agent", Date.now())
187
+ ```
208
188
 
209
189
  ---
210
190
 
211
- ## Harness
191
+ ## Governance
212
192
 
213
- Control how runs are attempted:
193
+ ### SDK PermissionManager
214
194
 
215
195
  ```typescript
216
- import { Agent, SinglePassHarness, EvalLoopHarness, HarnessRequest } from "@deepstrike/sdk"
217
- import type { QualityGate, HarnessOutcome } from "@deepstrike/sdk"
196
+ import { PermissionManager, PermissionMode } from "@deepstrike/sdk"
218
197
 
219
- // Single pass
220
- const harness = new SinglePassHarness(agent)
221
- const outcome = await harness.run({ goal: "Write a haiku" })
198
+ const pm = new PermissionManager(PermissionMode.DEFAULT)
199
+ pm.grant("fs", "read")
200
+ pm.grantWithApproval("db", "write", "Needs DBA approval")
201
+ pm.revoke("db", "drop")
202
+ pm.evaluate("fs", "read") // { allowed: true, ... }
203
+ ```
222
204
 
223
- // Eval loop — retry until QualityGate passes (max 3 attempts)
224
- class LengthGate implements QualityGate {
225
- async evaluate(request: HarnessRequest, outcome: HarnessOutcome): Promise<boolean> {
226
- return outcome.result.length > 50
227
- }
228
- }
205
+ ### Kernel Governance (full pipeline)
229
206
 
230
- const evalHarness = new EvalLoopHarness(agent, new LengthGate(), 3)
231
- const result = await evalHarness.run({ goal: "Write a haiku" })
232
- console.log(result.passed, result.iterations)
207
+ ```typescript
208
+ import { Governance } from "@deepstrike/sdk"
209
+
210
+ const gov = new Governance("allow")
211
+ gov.addPermissionRule("danger.*", "deny")
212
+ gov.blockTool("rm_rf")
213
+ gov.setRateLimit("api_call", 10, 60_000)
214
+
215
+ const agent = new Agent(provider, { maxTokens: 4096, governance: gov })
216
+ // Every tool call goes through: Permission → Veto → RateLimit → Constraint → Audit
233
217
  ```
234
218
 
235
219
  ---
236
220
 
237
- ## Signals & interrupts
221
+ ## Signals
238
222
 
239
223
  ```typescript
240
- import { ScheduledPrompt } from "@deepstrike/sdk"
241
- import type { SignalSource, RuntimeSignal } from "@deepstrike/sdk"
224
+ import { SignalGateway, ScheduledPrompt } from "@deepstrike/sdk"
242
225
 
243
- // Interrupt a running agent
244
- setTimeout(() => agent.interrupt(), 30_000)
226
+ const gw = new SignalGateway()
227
+ const rx = gw.subscribe()
245
228
 
246
- // Convert a scheduled prompt to a RuntimeSignal
247
- const prompt = new ScheduledPrompt("Daily standup summary", 1_700_000_000_000)
248
- const signal = prompt.toSignal()
249
- // signal.kind === "scheduled"
250
- // signal.payload === { goal: "Daily standup summary", criteria: [], runAtMs: ... }
251
- ```
229
+ gw.schedule(new ScheduledPrompt("standup", Date.now() + 3600_000))
230
+ gw.ingest({ kind: "interrupt", payload: {}, priority: 10 })
252
231
 
253
- Implement `SignalSource` to feed signals from any external source:
232
+ const agent = new Agent(provider, { maxTokens: 4096, signalSource: rx })
233
+ // kind="interrupt" → immediately stops the running agent
254
234
 
255
- ```typescript
256
- class WebhookSource implements SignalSource {
257
- async nextSignal(): Promise<RuntimeSignal | null> {
258
- const event = await webhookQueue.get()
259
- return { kind: "external", payload: event }
260
- }
261
- }
235
+ agent.interrupt() // also works directly
236
+ gw.destroy()
262
237
  ```
263
238
 
264
239
  ---
265
240
 
266
- ## Permissions
241
+ ## Harness (evaluation framework)
267
242
 
268
243
  ```typescript
269
- import { PermissionManager, PermissionMode } from "@deepstrike/sdk"
244
+ import { SinglePassHarness, EvalLoopHarness, HarnessLoop } from "@deepstrike/sdk"
270
245
 
271
- const pm = new PermissionManager(PermissionMode.DEFAULT)
272
- pm.grant("bash", "execute")
273
- pm.grant("fs", "*") // wildcard: all actions on fs
274
- pm.revoke("bash", "execute")
246
+ // 1. SinglePass — run once, always passes
247
+ const outcome = await new SinglePassHarness(agent).run({ goal: "Say hello" })
275
248
 
276
- const decision = pm.evaluate("bash", "execute")
277
- decision.allowed // boolean
278
- decision.reason // string
279
- ```
249
+ // 2. EvalLoop — retry until QualityGate passes
250
+ const harness = new EvalLoopHarness(agent, {
251
+ gate: async (req, out) => out.result.includes("hello"),
252
+ maxAttempts: 3,
253
+ })
280
254
 
281
- Modes: `DEFAULT` (evaluate grants), `PLAN` (block all), `AUTO` (allow all).
255
+ // 3. HarnessLoop — LLM-as-judge with feedback injection + skill extraction
256
+ const loop = new HarnessLoop(agent, {
257
+ evalProvider,
258
+ maxAttempts: 3,
259
+ skillDir: "./skills",
260
+ })
261
+ const out = await loop.run({ goal: "Write a haiku", criteria: ["Must be 3 lines"] })
262
+ console.log(out.passed, out.feedback)
263
+ ```
282
264
 
283
265
  ---
284
266
 
285
267
  ## Stream events
286
268
 
287
- | Event type | Fields |
288
- |------------|--------|
289
- | `text_delta` | `delta: string` |
290
- | `thinking_delta` | `delta: string` |
291
- | `tool_call` | `id, name, arguments` |
292
- | `tool_result` | `callId, name, content, isError` |
293
- | `done` | `iterations, totalTokens, status` |
294
- | `error` | `message: string` |
295
-
296
- `status` mirrors the kernel termination reason: `completed` / `max_turns` / `token_budget` / `timeout` / `user_abort` / `error`.
269
+ | Event type | Key fields |
270
+ |------------|------------|
271
+ | `text_delta` | `delta` |
272
+ | `thinking_delta` | `delta` |
273
+ | `tool_call` | `id`, `name`, `arguments` |
274
+ | `tool_result` | `callId`, `content`, `isError` |
275
+ | `permission_request` | `toolName`, `reason` |
276
+ | `done` | `iterations`, `totalTokens`, `status` |
277
+ | `error` | `message` |
278
+
279
+ `status`: `completed` · `max_turns` · `token_budget` · `timeout` · `user_abort` · `error`
package/dist/agent.d.ts CHANGED
@@ -9,8 +9,19 @@ export interface AgentOptions {
9
9
  timeoutMs?: number;
10
10
  extensions?: Record<string, unknown>;
11
11
  /**
12
- * Directory containing skill `.md` files. The kernel will auto-inject a
13
- * `skill` meta-tool so the model can load any skill by name on demand.
12
+ * System-level instructions prepended to every context render.
13
+ * Passed to the kernel's `system` partition before the first LLM call.
14
+ */
15
+ systemPrompt?: string;
16
+ /**
17
+ * Long-term memory snippets pre-seeded into the context before the first LLM call.
18
+ * Each string is pushed to the kernel's `memory` partition (highest-priority context
19
+ * after system). Use to inject memories retrieved from a DreamStore before a run.
20
+ */
21
+ initialMemory?: string[];
22
+ /**
23
+ * Directory containing skill `.md` files. The kernel auto-injects a `skill`
24
+ * meta-tool so the model can load any skill by name on demand.
14
25
  */
15
26
  skillDir?: string;
16
27
  knowledgeSource?: KnowledgeSource;
@@ -19,15 +30,19 @@ export interface AgentOptions {
19
30
  dreamStore?: DreamStore;
20
31
  /**
21
32
  * Stable identifier for this agent. Required to enable in-session memory retrieval
22
- * when `dreamStore` is configured — the kernel injects a `memory` meta-tool and
23
- * the SDK calls `dreamStore.search(agentId, query)` on demand.
33
+ * when `dreamStore` is configured.
24
34
  */
25
35
  agentId?: string;
26
- /** Governance instance from @deepstrike/core for permission checks on tool calls. */
36
+ /**
37
+ * Kernel Governance instance (from `@deepstrike/core`) or any object implementing
38
+ * `evaluate(toolName: string, argsJson: string): { kind: string; reason?: string; retryAfterMs?: number }`.
39
+ * When provided, every tool call is evaluated through the full pipeline.
40
+ */
27
41
  governance?: {
28
- evaluate(toolName: string, args: string): {
42
+ evaluate(toolName: string, argsJson: string): {
29
43
  kind: string;
30
44
  reason?: string;
45
+ retryAfterMs?: number;
31
46
  };
32
47
  };
33
48
  }
@@ -35,7 +50,6 @@ export declare class Agent {
35
50
  private readonly provider;
36
51
  private readonly options;
37
52
  private tools;
38
- private blockedTools;
39
53
  private extensions;
40
54
  private skillDir?;
41
55
  private knowledgeSource?;
@@ -43,20 +57,30 @@ export declare class Agent {
43
57
  private dreamStore?;
44
58
  private interrupted;
45
59
  private pendingInterrupt;
60
+ private _turn;
61
+ private _pressure;
46
62
  constructor(provider: LLMProvider, options: AgentOptions);
63
+ /** Current turn index within the active run (0 before a run starts). */
64
+ get turn(): number;
65
+ /** Context pressure ratio [0–1] from the kernel. Values > 0.8 trigger compression. */
66
+ get pressure(): number;
47
67
  interrupt(): void;
48
68
  register(...tools: RegisteredTool[]): this;
49
69
  unregister(name: string): this;
50
- blockTool(name: string): this;
70
+ /**
71
+ * Collect the full text response and return it.
72
+ * For richer control (streaming, tool events, token counts) use `runStreaming`.
73
+ */
51
74
  run(goal: string, criteria?: string[], extensions?: Record<string, unknown>): Promise<string>;
52
75
  runStreaming(goal: string, criteria?: string[], extensions?: Record<string, unknown>): AsyncIterable<StreamEvent>;
53
76
  /**
54
- * Trigger an idle dreaming cycle for the given agent.
77
+ * Trigger the idle dreaming cycle for this agent.
78
+ * Requires `dreamStore` and `agentId` to be configured.
55
79
  *
56
- * Phase 1 — kernel rule-based analysis + LLM prompt assembly (kernel, pure computation)
57
- * Phase 2 — LLM synthesis call (SDK, I/O here)
58
- * Phase 3 — kernel parses + curates results (kernel, pure computation)
59
- * Phase 4 — commit delta to DreamStore (SDK, I/O here)
80
+ * Phase 1 — kernel rule-based analysis + LLM prompt assembly
81
+ * Phase 2 — LLM synthesis call (I/O)
82
+ * Phase 3 — kernel parses + curates results
83
+ * Phase 4 — commit delta to DreamStore (I/O)
60
84
  */
61
85
  dream(agentId: string, nowMs?: number): Promise<DreamResult>;
62
86
  }