@deepstrike/sdk 0.1.4 → 0.1.7
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 +13 -15
- package/dist/agent.d.ts +2 -1
- package/dist/agent.js +14 -18
- package/dist/governance.d.ts +17 -0
- package/dist/governance.js +34 -0
- package/dist/harness/harness.d.ts +33 -1
- package/dist/harness/harness.js +49 -22
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -7
- package/dist/kernel.d.ts +149 -0
- package/dist/kernel.js +9 -0
- package/dist/memory/protocols.d.ts +2 -1
- package/dist/memory/protocols.js +0 -1
- package/dist/safety/permissions.d.ts +1 -0
- package/dist/safety/permissions.js +3 -0
- package/dist/signals/gateway.js +4 -0
- package/dist/signals/scheduled.js +4 -0
- package/dist/signals/types.d.ts +10 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -16,13 +16,15 @@ Pre-built native addons are available for the following platforms:
|
|
|
16
16
|
|
|
17
17
|
| Platform | Package |
|
|
18
18
|
| -------- | ------- |
|
|
19
|
-
| Linux x64 (glibc) | `@deepstrike/core-linux-x64-gnu` |
|
|
20
|
-
| Linux ARM64 (glibc) | `@deepstrike/core-linux-arm64-gnu` |
|
|
21
19
|
| macOS x64 | `@deepstrike/core-darwin-x64` |
|
|
22
20
|
| macOS ARM64 (Apple Silicon) | `@deepstrike/core-darwin-arm64` |
|
|
21
|
+
| Linux x64 (glibc) | `@deepstrike/core-linux-x64-gnu` |
|
|
22
|
+
| Linux x64 (musl / Alpine) | `@deepstrike/core-linux-x64-musl` |
|
|
23
|
+
| Linux ARM64 (glibc) | `@deepstrike/core-linux-arm64-gnu` |
|
|
24
|
+
| Linux ARM64 (musl / Alpine) | `@deepstrike/core-linux-arm64-musl` |
|
|
23
25
|
| Windows x64 | `@deepstrike/core-win32-x64-msvc` |
|
|
24
26
|
|
|
25
|
-
The correct platform package is selected and installed automatically via `optionalDependencies`.
|
|
27
|
+
The correct platform package is selected and installed automatically via `optionalDependencies`. No postinstall download is required.
|
|
26
28
|
|
|
27
29
|
> **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.
|
|
28
30
|
|
|
@@ -33,11 +35,7 @@ The correct platform package is selected and installed automatically via `option
|
|
|
33
35
|
```typescript
|
|
34
36
|
import { Agent, OpenAIProvider, tool } from "@deepstrike/sdk"
|
|
35
37
|
|
|
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
|
-
})
|
|
38
|
+
const provider = new OpenAIProvider(process.env.OPENAI_API_KEY!, "gpt-5-mini")
|
|
41
39
|
|
|
42
40
|
const add = tool("add", "Add two numbers.", {
|
|
43
41
|
type: "object",
|
|
@@ -49,7 +47,7 @@ const agent = new Agent(provider, { maxTokens: 4096 })
|
|
|
49
47
|
agent.register(add)
|
|
50
48
|
|
|
51
49
|
const result = await agent.run("What is 17 + 28?")
|
|
52
|
-
console.log(result)
|
|
50
|
+
console.log(result)
|
|
53
51
|
```
|
|
54
52
|
|
|
55
53
|
Streaming:
|
|
@@ -106,9 +104,8 @@ const agent = new Agent(provider, {
|
|
|
106
104
|
import { tool, readFile } from "@deepstrike/sdk"
|
|
107
105
|
|
|
108
106
|
agent.register(tool("search", "Search.", schema, async (args) => ...))
|
|
109
|
-
agent.register(readFile
|
|
107
|
+
agent.register(readFile) // built-in: read files from disk
|
|
110
108
|
agent.unregister("search")
|
|
111
|
-
agent.blockTool("bash") // governance veto
|
|
112
109
|
```
|
|
113
110
|
|
|
114
111
|
---
|
|
@@ -211,6 +208,9 @@ const gov = new Governance("allow")
|
|
|
211
208
|
gov.addPermissionRule("danger.*", "deny")
|
|
212
209
|
gov.blockTool("rm_rf")
|
|
213
210
|
gov.setRateLimit("api_call", 10, 60_000)
|
|
211
|
+
gov.requireParam("write_file", "path")
|
|
212
|
+
gov.allowParamValues("set_mode", "mode", ["read", "write"])
|
|
213
|
+
gov.limitParamRange("sleep", "seconds", 0, 10)
|
|
214
214
|
|
|
215
215
|
const agent = new Agent(provider, { maxTokens: 4096, governance: gov })
|
|
216
216
|
// Every tool call goes through: Permission → Veto → RateLimit → Constraint → Audit
|
|
@@ -224,12 +224,10 @@ const agent = new Agent(provider, { maxTokens: 4096, governance: gov })
|
|
|
224
224
|
import { SignalGateway, ScheduledPrompt } from "@deepstrike/sdk"
|
|
225
225
|
|
|
226
226
|
const gw = new SignalGateway()
|
|
227
|
-
const rx = gw.subscribe()
|
|
228
|
-
|
|
229
227
|
gw.schedule(new ScheduledPrompt("standup", Date.now() + 3600_000))
|
|
230
|
-
gw.ingest({ kind: "interrupt",
|
|
228
|
+
gw.ingest({ kind: "interrupt", urgency: "critical", payload: {} })
|
|
231
229
|
|
|
232
|
-
const agent = new Agent(provider, { maxTokens: 4096, signalSource:
|
|
230
|
+
const agent = new Agent(provider, { maxTokens: 4096, signalSource: gw })
|
|
233
231
|
// kind="interrupt" → immediately stops the running agent
|
|
234
232
|
|
|
235
233
|
agent.interrupt() // also works directly
|
package/dist/agent.d.ts
CHANGED
|
@@ -34,11 +34,12 @@ export interface AgentOptions {
|
|
|
34
34
|
*/
|
|
35
35
|
agentId?: string;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* SDK Governance instance or any object implementing
|
|
38
38
|
* `evaluate(toolName: string, argsJson: string): { kind: string; reason?: string; retryAfterMs?: number }`.
|
|
39
39
|
* When provided, every tool call is evaluated through the full pipeline.
|
|
40
40
|
*/
|
|
41
41
|
governance?: {
|
|
42
|
+
setTime?(nowMs: bigint): void;
|
|
42
43
|
evaluate(toolName: string, argsJson: string): {
|
|
43
44
|
kind: string;
|
|
44
45
|
reason?: string;
|
package/dist/agent.js
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { executeTools } from "./tools/index.js";
|
|
2
2
|
import { readSkillFile, scanSkillDir } from "./skills/loader.js";
|
|
3
|
-
|
|
4
|
-
async function loadKernel() {
|
|
5
|
-
const mod = await import("@deepstrike/core");
|
|
6
|
-
// CJS modules imported via ESM dynamic import expose exports under `.default`
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
-
return mod.default ?? mod;
|
|
9
|
-
}
|
|
3
|
+
import { getKernel } from "./kernel.js";
|
|
10
4
|
export class Agent {
|
|
11
5
|
provider;
|
|
12
6
|
options;
|
|
@@ -66,12 +60,12 @@ export class Agent {
|
|
|
66
60
|
if (this.knowledgeSource) {
|
|
67
61
|
await this.knowledgeSource.init();
|
|
68
62
|
}
|
|
69
|
-
const kernel =
|
|
63
|
+
const kernel = getKernel();
|
|
70
64
|
const ext = { ...this.extensions, ...(extensions ?? {}) };
|
|
71
65
|
const sm = new kernel.LoopStateMachine({
|
|
72
66
|
maxTokens: this.options.maxTokens,
|
|
73
67
|
maxTurns: this.options.maxTurns ?? 25,
|
|
74
|
-
timeoutMs: this.options.timeoutMs,
|
|
68
|
+
timeoutMs: this.options.timeoutMs === undefined ? undefined : BigInt(this.options.timeoutMs),
|
|
75
69
|
});
|
|
76
70
|
// Per-run SignalRouter — dedup state never leaks between runs.
|
|
77
71
|
const router = new kernel.SignalRouter(256);
|
|
@@ -123,16 +117,14 @@ export class Agent {
|
|
|
123
117
|
if (this.signalSource) {
|
|
124
118
|
const sig = await this.signalSource.nextSignal();
|
|
125
119
|
if (sig) {
|
|
126
|
-
const sigAny = sig;
|
|
127
120
|
const kernelSig = {
|
|
128
121
|
id: crypto.randomUUID(),
|
|
129
|
-
source:
|
|
130
|
-
signalType:
|
|
131
|
-
urgency:
|
|
132
|
-
|
|
133
|
-
summary: String(sig.payload?.goal ?? sig.kind),
|
|
122
|
+
source: sig.source ?? "custom",
|
|
123
|
+
signalType: sig.signalType ?? "event",
|
|
124
|
+
urgency: normalizeSignalUrgency(sig),
|
|
125
|
+
summary: String(sig.payload?.goal ?? sig.kind ?? "signal"),
|
|
134
126
|
payload: JSON.stringify(sig.payload ?? {}),
|
|
135
|
-
dedupeKey:
|
|
127
|
+
dedupeKey: sig.dedupeKey,
|
|
136
128
|
timestampMs: Date.now(),
|
|
137
129
|
};
|
|
138
130
|
const disposition = router.ingest(kernelSig, action.kind === "execute_tools");
|
|
@@ -193,6 +185,7 @@ export class Agent {
|
|
|
193
185
|
const deniedResults = [];
|
|
194
186
|
for (const c of allCalls) {
|
|
195
187
|
if (this.options.governance) {
|
|
188
|
+
this.options.governance.setTime?.(BigInt(Date.now()));
|
|
196
189
|
const verdict = this.options.governance.evaluate(c.name, c.arguments);
|
|
197
190
|
if (verdict.kind === "deny") {
|
|
198
191
|
const msg = `permission denied: ${c.name} — ${verdict.reason ?? ""}`;
|
|
@@ -270,7 +263,7 @@ export class Agent {
|
|
|
270
263
|
const result = action.result;
|
|
271
264
|
this._turn = sm.turn;
|
|
272
265
|
this._pressure = sm.pressure();
|
|
273
|
-
const status = result?.termination
|
|
266
|
+
const status = result?.termination ?? "error";
|
|
274
267
|
const iterations = result ? Math.max(1, result.turnsUsed) : 0;
|
|
275
268
|
if (this.options.dreamStore && this.options.agentId && sessionMsgs.length > 1) {
|
|
276
269
|
try {
|
|
@@ -304,7 +297,7 @@ export class Agent {
|
|
|
304
297
|
async dream(agentId, nowMs = Date.now()) {
|
|
305
298
|
if (!this.dreamStore)
|
|
306
299
|
throw new Error("dreamStore not configured on AgentOptions");
|
|
307
|
-
const kernel =
|
|
300
|
+
const kernel = getKernel();
|
|
308
301
|
const sessions = await this.dreamStore.loadSessions(agentId);
|
|
309
302
|
const existingMemories = await this.dreamStore.loadMemories(agentId);
|
|
310
303
|
if (!sessions.length) {
|
|
@@ -378,3 +371,6 @@ function tryParseJson(s) {
|
|
|
378
371
|
return null;
|
|
379
372
|
}
|
|
380
373
|
}
|
|
374
|
+
function normalizeSignalUrgency(sig) {
|
|
375
|
+
return sig.urgency;
|
|
376
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GovernanceVerdict } from "./kernel.js";
|
|
2
|
+
type GovernanceDefaultAction = "allow" | "deny" | "ask_user";
|
|
3
|
+
type GovernanceRuleAction = "allow" | "deny" | "ask_user";
|
|
4
|
+
export declare class Governance {
|
|
5
|
+
private readonly inner;
|
|
6
|
+
constructor(defaultAction?: GovernanceDefaultAction);
|
|
7
|
+
setIdentity(agentId: string, sessionId: string): void;
|
|
8
|
+
addPermissionRule(pattern: string, action: GovernanceRuleAction): void;
|
|
9
|
+
blockTool(name: string): void;
|
|
10
|
+
setRateLimit(toolName: string, maxCalls: number, windowMs: number): void;
|
|
11
|
+
requireParam(toolName: string, paramPath: string): void;
|
|
12
|
+
allowParamValues(toolName: string, paramPath: string, allowedValues: string[]): void;
|
|
13
|
+
limitParamRange(toolName: string, paramPath: string, min?: number, max?: number): void;
|
|
14
|
+
setTime(nowMs: number | bigint): void;
|
|
15
|
+
evaluate(toolName: string, argsJson: string): GovernanceVerdict;
|
|
16
|
+
}
|
|
17
|
+
export type { GovernanceVerdict };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getKernel } from "./kernel.js";
|
|
2
|
+
export class Governance {
|
|
3
|
+
inner;
|
|
4
|
+
constructor(defaultAction = "allow") {
|
|
5
|
+
this.inner = new (getKernel().Governance)(defaultAction);
|
|
6
|
+
}
|
|
7
|
+
setIdentity(agentId, sessionId) {
|
|
8
|
+
this.inner.setIdentity(agentId, sessionId);
|
|
9
|
+
}
|
|
10
|
+
addPermissionRule(pattern, action) {
|
|
11
|
+
this.inner.addPermissionRule(pattern, action);
|
|
12
|
+
}
|
|
13
|
+
blockTool(name) {
|
|
14
|
+
this.inner.blockTool(name);
|
|
15
|
+
}
|
|
16
|
+
setRateLimit(toolName, maxCalls, windowMs) {
|
|
17
|
+
this.inner.setRateLimit(toolName, maxCalls, BigInt(windowMs));
|
|
18
|
+
}
|
|
19
|
+
requireParam(toolName, paramPath) {
|
|
20
|
+
this.inner.requireParam(toolName, paramPath);
|
|
21
|
+
}
|
|
22
|
+
allowParamValues(toolName, paramPath, allowedValues) {
|
|
23
|
+
this.inner.allowParamValues(toolName, paramPath, allowedValues);
|
|
24
|
+
}
|
|
25
|
+
limitParamRange(toolName, paramPath, min, max) {
|
|
26
|
+
this.inner.limitParamRange(toolName, paramPath, min, max);
|
|
27
|
+
}
|
|
28
|
+
setTime(nowMs) {
|
|
29
|
+
this.inner.setTime(typeof nowMs === "bigint" ? nowMs : BigInt(nowMs));
|
|
30
|
+
}
|
|
31
|
+
evaluate(toolName, argsJson) {
|
|
32
|
+
return this.inner.evaluate(toolName, argsJson);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -25,6 +25,38 @@ export interface HarnessOutcome {
|
|
|
25
25
|
feedback?: string;
|
|
26
26
|
details?: CriterionResult[];
|
|
27
27
|
}
|
|
28
|
+
export interface Verdict {
|
|
29
|
+
passed: boolean;
|
|
30
|
+
overallScore: number;
|
|
31
|
+
feedback: string;
|
|
32
|
+
details: CriterionResult[];
|
|
33
|
+
}
|
|
34
|
+
export type HarnessEvent = {
|
|
35
|
+
type: "token";
|
|
36
|
+
text: string;
|
|
37
|
+
} | {
|
|
38
|
+
type: "tool_call";
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
} | {
|
|
42
|
+
type: "tool_result";
|
|
43
|
+
callId: string;
|
|
44
|
+
content: string;
|
|
45
|
+
isError: boolean;
|
|
46
|
+
} | {
|
|
47
|
+
type: "supervising";
|
|
48
|
+
} | {
|
|
49
|
+
type: "revising";
|
|
50
|
+
verdict: Verdict;
|
|
51
|
+
} | {
|
|
52
|
+
type: "done";
|
|
53
|
+
verdict: Verdict;
|
|
54
|
+
iterations: number;
|
|
55
|
+
totalTokens: number;
|
|
56
|
+
status: string;
|
|
57
|
+
} | {
|
|
58
|
+
type: "max_attempts_reached";
|
|
59
|
+
};
|
|
28
60
|
export interface QualityGate {
|
|
29
61
|
evaluate(request: HarnessRequest, outcome: HarnessOutcome): Promise<boolean>;
|
|
30
62
|
}
|
|
@@ -50,5 +82,5 @@ export declare class HarnessLoop {
|
|
|
50
82
|
private maxAttempts;
|
|
51
83
|
private skillDir?;
|
|
52
84
|
constructor(agent: Agent, evalProvider: import("../types.js").LLMProvider, options?: HarnessLoopOptions);
|
|
53
|
-
|
|
85
|
+
runStreaming(request: HarnessRequest): AsyncIterable<HarnessEvent>;
|
|
54
86
|
}
|
package/dist/harness/harness.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { writeFile } from "fs/promises";
|
|
2
2
|
import path from "path";
|
|
3
|
-
|
|
4
|
-
async function loadKernel() {
|
|
5
|
-
const mod = await import("@deepstrike/core");
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
-
return mod.default ?? mod;
|
|
8
|
-
}
|
|
3
|
+
import { getKernel } from "../kernel.js";
|
|
9
4
|
async function runOnce(agent, req) {
|
|
10
5
|
let text = "";
|
|
11
6
|
let done;
|
|
@@ -56,15 +51,44 @@ export class HarnessLoop {
|
|
|
56
51
|
this.maxAttempts = options.maxAttempts ?? 3;
|
|
57
52
|
this.skillDir = options.skillDir;
|
|
58
53
|
}
|
|
59
|
-
async
|
|
60
|
-
const kernel =
|
|
54
|
+
async *runStreaming(request) {
|
|
55
|
+
const kernel = getKernel();
|
|
61
56
|
const pipeline = new kernel.EvalPipeline({ extractSkillOnPass: true });
|
|
62
57
|
const criteria = request.criteria ?? [];
|
|
63
|
-
|
|
58
|
+
// history tracks the full conversation; agent sees only the current goal message
|
|
59
|
+
// but we inject feedback as user messages to guide revision without discarding prior output
|
|
64
60
|
let currentGoal = request.goal;
|
|
61
|
+
let lastIterations = 0;
|
|
62
|
+
let lastTotalTokens = 0;
|
|
63
|
+
let lastStatus = "error";
|
|
64
|
+
let lastResult = "";
|
|
65
65
|
for (let attempt = 1; attempt <= this.maxAttempts; attempt++) {
|
|
66
|
-
|
|
67
|
-
const
|
|
66
|
+
// Stream agent output directly to caller
|
|
67
|
+
for await (const evt of this.agent.runStreaming(currentGoal, criteria.map(c => c.text), request.extensions)) {
|
|
68
|
+
if (evt.type === "text_delta") {
|
|
69
|
+
lastResult += evt.delta;
|
|
70
|
+
yield { type: "token", text: evt.delta };
|
|
71
|
+
}
|
|
72
|
+
else if (evt.type === "tool_call") {
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
74
|
+
const tc = evt;
|
|
75
|
+
yield { type: "tool_call", id: tc.id, name: tc.name };
|
|
76
|
+
}
|
|
77
|
+
else if (evt.type === "tool_result") {
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
79
|
+
const tr = evt;
|
|
80
|
+
yield { type: "tool_result", callId: tr.callId, content: tr.content, isError: tr.isError };
|
|
81
|
+
}
|
|
82
|
+
else if (evt.type === "done") {
|
|
83
|
+
const d = evt;
|
|
84
|
+
lastIterations = d.iterations;
|
|
85
|
+
lastTotalTokens = d.totalTokens;
|
|
86
|
+
lastStatus = d.status;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Checkpoint: evaluator judges the completed output
|
|
90
|
+
yield { type: "supervising" };
|
|
91
|
+
const evalAction = pipeline.feedOutcome(request.goal, criteria, lastResult, attempt);
|
|
68
92
|
if (evalAction.kind !== "evaluate")
|
|
69
93
|
break;
|
|
70
94
|
let evalText = "";
|
|
@@ -75,26 +99,29 @@ export class HarnessLoop {
|
|
|
75
99
|
const doneAction = pipeline.feedEvalResult(evalText);
|
|
76
100
|
if (doneAction.kind !== "done")
|
|
77
101
|
break;
|
|
78
|
-
|
|
79
|
-
...outcome,
|
|
102
|
+
const verdict = {
|
|
80
103
|
passed: doneAction.passed ?? false,
|
|
81
|
-
overallScore: doneAction.overallScore ??
|
|
82
|
-
feedback: doneAction.feedback ??
|
|
83
|
-
details: doneAction.details ??
|
|
104
|
+
overallScore: doneAction.overallScore ?? 0,
|
|
105
|
+
feedback: doneAction.feedback ?? "",
|
|
106
|
+
details: doneAction.details ?? [],
|
|
84
107
|
};
|
|
85
|
-
if (
|
|
86
|
-
if (doneAction.
|
|
87
|
-
const { name, description, whenToUse, content } = doneAction.
|
|
108
|
+
if (verdict.passed) {
|
|
109
|
+
if (doneAction.skillCandidate && this.skillDir) {
|
|
110
|
+
const { name, description, whenToUse, content } = doneAction.skillCandidate;
|
|
88
111
|
const fm = ["---", `name: ${name}`, `description: ${description}`,
|
|
89
112
|
whenToUse ? `when_to_use: ${whenToUse}` : null, "---", ""]
|
|
90
113
|
.filter(Boolean).join("\n");
|
|
91
114
|
await writeFile(path.join(this.skillDir, `${name}.md`), fm + content, "utf8");
|
|
92
115
|
}
|
|
93
|
-
|
|
116
|
+
yield { type: "done", verdict, iterations: lastIterations, totalTokens: lastTotalTokens, status: lastStatus };
|
|
117
|
+
return;
|
|
94
118
|
}
|
|
95
|
-
|
|
119
|
+
yield { type: "revising", verdict };
|
|
120
|
+
// Inject feedback as next turn's goal — agent sees its prior output + evaluator notes
|
|
121
|
+
currentGoal = `${request.goal}\n\n[Attempt ${attempt} feedback: ${verdict.feedback}]`;
|
|
122
|
+
lastResult = "";
|
|
96
123
|
pipeline.reset();
|
|
97
124
|
}
|
|
98
|
-
|
|
125
|
+
yield { type: "max_attempts_reached" };
|
|
99
126
|
}
|
|
100
127
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,6 @@ export { SignalGateway } from "./signals/gateway.js";
|
|
|
18
18
|
export type { RuntimeSignal, SignalSource } from "./signals/types.js";
|
|
19
19
|
export { PermissionManager, PermissionMode } from "./safety/permissions.js";
|
|
20
20
|
export type { PermissionDecision, Permission } from "./safety/permissions.js";
|
|
21
|
-
export
|
|
22
|
-
export type {
|
|
21
|
+
export { Governance } from "./governance.js";
|
|
22
|
+
export type { GovernanceVerdict } from "./governance.js";
|
|
23
23
|
export type { Message, ToolCall, ToolResult, ToolSchema, ContentPart, TextPart, ImagePart, AudioPart, StreamEvent, TextDelta, ThinkingDelta, ToolCallEvent, ToolResultEvent, DoneEvent, ErrorEvent, PermissionRequestEvent, LLMProvider, RetryConfig, TokenUsage, ProviderToolSpec, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -10,10 +10,4 @@ export { SinglePassHarness, EvalLoopHarness, HarnessLoop } from "./harness/harne
|
|
|
10
10
|
export { ScheduledPrompt } from "./signals/scheduled.js";
|
|
11
11
|
export { SignalGateway } from "./signals/gateway.js";
|
|
12
12
|
export { PermissionManager, PermissionMode } from "./safety/permissions.js";
|
|
13
|
-
|
|
14
|
-
// @deepstrike/core is a CJS native addon; static ESM named re-export doesn't work,
|
|
15
|
-
// so we load it via createRequire and re-export with proper types preserved.
|
|
16
|
-
import { createRequire } from "module";
|
|
17
|
-
const _cjsRequire = createRequire(import.meta.url);
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
-
export const Governance = _cjsRequire("@deepstrike/core").Governance;
|
|
13
|
+
export { Governance } from "./governance.js";
|
package/dist/kernel.d.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { Message, ToolCall, ToolResult, ToolSchema } from "./types.js";
|
|
2
|
+
import type { SkillMetadata } from "./skills/loader.js";
|
|
3
|
+
export interface GovernanceVerdict {
|
|
4
|
+
kind: "allow" | "deny" | "rate_limited" | "ask_user";
|
|
5
|
+
reason?: string;
|
|
6
|
+
retryAfterMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface GovernanceInstance {
|
|
9
|
+
setIdentity(agentId: string, sessionId: string): void;
|
|
10
|
+
addPermissionRule(pattern: string, action: "allow" | "deny" | "ask_user"): void;
|
|
11
|
+
blockTool(name: string): void;
|
|
12
|
+
setRateLimit(toolName: string, maxCalls: number, windowMs: bigint): void;
|
|
13
|
+
requireParam(toolName: string, paramPath: string): void;
|
|
14
|
+
allowParamValues(toolName: string, paramPath: string, allowedValues: string[]): void;
|
|
15
|
+
limitParamRange(toolName: string, paramPath: string, min?: number, max?: number): void;
|
|
16
|
+
setTime(nowMs: bigint): void;
|
|
17
|
+
evaluate(toolName: string, argsJson: string): GovernanceVerdict;
|
|
18
|
+
}
|
|
19
|
+
export interface RuntimeSignal {
|
|
20
|
+
id: string;
|
|
21
|
+
source: "cron" | "gateway" | "heartbeat" | "custom";
|
|
22
|
+
signalType: "event" | "job" | "alert";
|
|
23
|
+
urgency: "low" | "normal" | "high" | "critical";
|
|
24
|
+
summary: string;
|
|
25
|
+
payload: string;
|
|
26
|
+
dedupeKey?: string;
|
|
27
|
+
timestampMs: number;
|
|
28
|
+
}
|
|
29
|
+
export interface LoopAction {
|
|
30
|
+
kind: "call_llm" | "execute_tools" | "done";
|
|
31
|
+
messages?: Message[];
|
|
32
|
+
tools?: ToolSchema[];
|
|
33
|
+
calls?: ToolCall[];
|
|
34
|
+
result?: {
|
|
35
|
+
termination: string;
|
|
36
|
+
turnsUsed: number;
|
|
37
|
+
totalTokensUsed: bigint;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
interface LoopObservation {
|
|
41
|
+
kind: "compressed";
|
|
42
|
+
action?: string;
|
|
43
|
+
rhoAfter?: number;
|
|
44
|
+
}
|
|
45
|
+
interface LoopStateMachineInstance {
|
|
46
|
+
setAvailableSkills(skills: SkillMetadata[]): void;
|
|
47
|
+
setMemoryEnabled(enabled: boolean): void;
|
|
48
|
+
setKnowledgeEnabled(enabled: boolean): void;
|
|
49
|
+
addSystemMessage(content: string, tokens: number): void;
|
|
50
|
+
addMemoryMessage(content: string, tokens: number): void;
|
|
51
|
+
setTools(tools: ToolSchema[]): void;
|
|
52
|
+
start(task: {
|
|
53
|
+
goal: string;
|
|
54
|
+
criteria: string[];
|
|
55
|
+
}): LoopAction;
|
|
56
|
+
feedLlmResponse(message: Message): LoopAction;
|
|
57
|
+
feedToolResults(results: ToolResult[]): LoopAction;
|
|
58
|
+
feedTimeout(): LoopAction;
|
|
59
|
+
isTerminal(): boolean;
|
|
60
|
+
readonly turn: number;
|
|
61
|
+
pressure(): number;
|
|
62
|
+
takeObservations(): LoopObservation[];
|
|
63
|
+
}
|
|
64
|
+
interface SignalRouterInstance {
|
|
65
|
+
ingest(signal: RuntimeSignal, isRunning: boolean): string;
|
|
66
|
+
next(): RuntimeSignal | null;
|
|
67
|
+
}
|
|
68
|
+
interface NativeCriterion {
|
|
69
|
+
text: string;
|
|
70
|
+
required: boolean;
|
|
71
|
+
weight?: number;
|
|
72
|
+
}
|
|
73
|
+
interface EvalPipelineAction {
|
|
74
|
+
kind: "evaluate" | "done";
|
|
75
|
+
messages?: Message[];
|
|
76
|
+
passed?: boolean;
|
|
77
|
+
overallScore?: number;
|
|
78
|
+
feedback?: string;
|
|
79
|
+
details?: Array<{
|
|
80
|
+
criterion: string;
|
|
81
|
+
passed: boolean;
|
|
82
|
+
score: number;
|
|
83
|
+
feedback: string;
|
|
84
|
+
}>;
|
|
85
|
+
skillCandidate?: {
|
|
86
|
+
name: string;
|
|
87
|
+
description: string;
|
|
88
|
+
whenToUse?: string;
|
|
89
|
+
content: string;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
interface EvalPipelineInstance {
|
|
93
|
+
feedOutcome(goal: string, criteria: NativeCriterion[], result: string, attempt: number): EvalPipelineAction;
|
|
94
|
+
feedEvalResult(content: string): EvalPipelineAction;
|
|
95
|
+
reset(): void;
|
|
96
|
+
}
|
|
97
|
+
interface IdlePipelineAction {
|
|
98
|
+
kind: "synthesize_insights" | "commit_memories" | "noop" | "aborted";
|
|
99
|
+
messages?: Message[];
|
|
100
|
+
curationResult?: {
|
|
101
|
+
toAdd?: Array<{
|
|
102
|
+
text: string;
|
|
103
|
+
score: number;
|
|
104
|
+
metadata: string;
|
|
105
|
+
}>;
|
|
106
|
+
toRemoveIndices?: number[];
|
|
107
|
+
stats?: {
|
|
108
|
+
insightsProcessed?: number;
|
|
109
|
+
duplicatesRemoved?: number;
|
|
110
|
+
conflictsResolved?: number;
|
|
111
|
+
entriesAdded?: number;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
runResult?: {
|
|
115
|
+
sessionsProcessed: number;
|
|
116
|
+
insightsExtracted: number;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
interface IdlePipelineInstance {
|
|
120
|
+
feedTrigger(sessions: Array<{
|
|
121
|
+
sessionId: string;
|
|
122
|
+
agentId: string;
|
|
123
|
+
messages: Message[];
|
|
124
|
+
metadata: string;
|
|
125
|
+
createdAtMs: number;
|
|
126
|
+
updatedAtMs: number;
|
|
127
|
+
}>, existingMemories: Array<{
|
|
128
|
+
text: string;
|
|
129
|
+
score: number;
|
|
130
|
+
metadata: string;
|
|
131
|
+
}>, nowMs: number): IdlePipelineAction;
|
|
132
|
+
feedSynthesisResult(content: string): IdlePipelineAction;
|
|
133
|
+
}
|
|
134
|
+
interface KernelModule {
|
|
135
|
+
Governance: new (defaultAction?: "allow" | "deny" | "ask_user") => GovernanceInstance;
|
|
136
|
+
LoopStateMachine: new (policy: {
|
|
137
|
+
maxTokens: number;
|
|
138
|
+
maxTurns?: number;
|
|
139
|
+
maxTotalTokens?: bigint;
|
|
140
|
+
timeoutMs?: bigint;
|
|
141
|
+
}) => LoopStateMachineInstance;
|
|
142
|
+
SignalRouter: new (maxQueueSize: number) => SignalRouterInstance;
|
|
143
|
+
EvalPipeline: new (options?: {
|
|
144
|
+
extractSkillOnPass?: boolean;
|
|
145
|
+
}) => EvalPipelineInstance;
|
|
146
|
+
IdlePipeline: new (agentId: string) => IdlePipelineInstance;
|
|
147
|
+
}
|
|
148
|
+
export declare function getKernel(): KernelModule;
|
|
149
|
+
export {};
|
package/dist/kernel.js
ADDED
package/dist/memory/protocols.js
CHANGED
|
@@ -24,6 +24,7 @@ export declare class PermissionManager {
|
|
|
24
24
|
requiresApproval?: boolean;
|
|
25
25
|
note?: string;
|
|
26
26
|
}): this;
|
|
27
|
+
grantWithApproval(resource: string, action: string, note?: string): this;
|
|
27
28
|
revoke(resource: string, action: string, note?: string): this;
|
|
28
29
|
private matchPermission;
|
|
29
30
|
evaluate(resource: string, action: string): PermissionDecision;
|
|
@@ -19,6 +19,9 @@ export class PermissionManager {
|
|
|
19
19
|
});
|
|
20
20
|
return this;
|
|
21
21
|
}
|
|
22
|
+
grantWithApproval(resource, action, note = "") {
|
|
23
|
+
return this.grant(resource, action, { requiresApproval: true, note });
|
|
24
|
+
}
|
|
22
25
|
revoke(resource, action, note = "") {
|
|
23
26
|
const key = `${resource}:${action}`;
|
|
24
27
|
this.permissions.set(key, { tool: resource, action, allowed: false, requiresApproval: false, note });
|
package/dist/signals/gateway.js
CHANGED
|
@@ -33,6 +33,10 @@ export class SignalGateway {
|
|
|
33
33
|
this.timers.delete(key);
|
|
34
34
|
this.emit({
|
|
35
35
|
kind: "scheduled",
|
|
36
|
+
source: "cron",
|
|
37
|
+
signalType: "job",
|
|
38
|
+
urgency: "normal",
|
|
39
|
+
dedupeKey: key,
|
|
36
40
|
payload: { goal: prompt.goal, criteria: prompt.criteria, runAtMs: prompt.runAtMs, ...prompt.metadata },
|
|
37
41
|
});
|
|
38
42
|
};
|
|
@@ -12,6 +12,10 @@ export class ScheduledPrompt {
|
|
|
12
12
|
toSignal() {
|
|
13
13
|
return {
|
|
14
14
|
kind: "scheduled",
|
|
15
|
+
source: "cron",
|
|
16
|
+
signalType: "job",
|
|
17
|
+
urgency: "normal",
|
|
18
|
+
dedupeKey: `cron:${this.goal}:${this.runAtMs}`,
|
|
15
19
|
payload: { goal: this.goal, criteria: this.criteria, runAtMs: this.runAtMs, ...this.metadata },
|
|
16
20
|
};
|
|
17
21
|
}
|
package/dist/signals/types.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
export type RuntimeSignalSource = "cron" | "gateway" | "heartbeat" | "custom";
|
|
2
|
+
export type RuntimeSignalType = "event" | "job" | "alert";
|
|
3
|
+
export type RuntimeSignalUrgency = "low" | "normal" | "high" | "critical";
|
|
1
4
|
export interface RuntimeSignal {
|
|
2
|
-
|
|
5
|
+
source: RuntimeSignalSource;
|
|
6
|
+
signalType: RuntimeSignalType;
|
|
7
|
+
urgency: RuntimeSignalUrgency;
|
|
3
8
|
payload: Record<string, unknown>;
|
|
9
|
+
dedupeKey?: string;
|
|
10
|
+
/** @deprecated Use source/signalType/urgency directly. */
|
|
11
|
+
kind?: "interrupt" | "scheduled" | "external";
|
|
12
|
+
/** @deprecated Prefer explicit `urgency`. */
|
|
4
13
|
priority?: number;
|
|
5
14
|
}
|
|
6
15
|
export interface SignalSource {
|
package/package.json
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepstrike/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "DeepStrike Node.js SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
-
"files": [
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
9
12
|
"scripts": {
|
|
10
13
|
"build": "tsc",
|
|
11
14
|
"test": "node --experimental-vm-modules node_modules/.bin/jest"
|
|
12
15
|
},
|
|
13
16
|
"dependencies": {
|
|
14
17
|
"@anthropic-ai/sdk": "^0.39.0",
|
|
15
|
-
"@deepstrike/core": "0.1.
|
|
18
|
+
"@deepstrike/core": "0.1.7",
|
|
16
19
|
"openai": "^4.77.0"
|
|
17
20
|
},
|
|
18
21
|
"devDependencies": {
|