@deepstrike/core 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/Cargo.toml +0 -2
- package/index.d.ts +337 -0
- package/index.js +274 -26
- package/npm/darwin-arm64/README.md +20 -1
- package/npm/darwin-arm64/package.json +1 -1
- package/npm/darwin-x64/README.md +20 -1
- package/npm/darwin-x64/package.json +1 -1
- package/npm/linux-arm64-gnu/README.md +20 -1
- package/npm/linux-arm64-gnu/package.json +1 -1
- package/npm/linux-arm64-musl/README.md +20 -1
- package/npm/linux-arm64-musl/package.json +1 -1
- package/npm/linux-x64-gnu/README.md +20 -1
- package/npm/linux-x64-gnu/package.json +1 -1
- package/npm/linux-x64-musl/README.md +20 -1
- package/npm/linux-x64-musl/package.json +1 -1
- package/npm/win32-x64-msvc/README.md +20 -1
- package/npm/win32-x64-msvc/package.json +1 -1
- package/package.json +6 -6
- package/src/lib.rs +222 -26
- package/npm/darwin-arm64/deepstrike-core.darwin-arm64.node +0 -0
- package/npm/darwin-x64/deepstrike-core.darwin-x64.node +0 -0
- package/npm/linux-arm64-gnu/deepstrike-core.linux-arm64-gnu.node +0 -0
- package/npm/linux-x64-gnu/deepstrike-core.linux-x64-gnu.node +0 -0
- package/npm/win32-x64-msvc/deepstrike-core.win32-x64-msvc.node +0 -0
package/Cargo.toml
CHANGED
package/index.d.ts
CHANGED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
export interface ContentPartObj {
|
|
7
|
+
/** `"text"` | `"image"` | `"audio"` | `"tool_result"` */
|
|
8
|
+
type: string
|
|
9
|
+
text?: string
|
|
10
|
+
url?: string
|
|
11
|
+
data?: string
|
|
12
|
+
mediaType?: string
|
|
13
|
+
detail?: string
|
|
14
|
+
callId?: string
|
|
15
|
+
output?: string
|
|
16
|
+
isError?: boolean
|
|
17
|
+
}
|
|
18
|
+
export interface Message {
|
|
19
|
+
role: string
|
|
20
|
+
/**
|
|
21
|
+
* Plain-text content. When `content_parts` is present, this holds only the
|
|
22
|
+
* concatenated text segments for backward compatibility.
|
|
23
|
+
*/
|
|
24
|
+
content: string
|
|
25
|
+
/** Structured multimodal content parts. When present, takes precedence over `content`. */
|
|
26
|
+
contentParts?: Array<ContentPartObj>
|
|
27
|
+
tokenCount?: number
|
|
28
|
+
toolCalls: Array<ToolCall>
|
|
29
|
+
}
|
|
30
|
+
export interface ToolCall {
|
|
31
|
+
id: string
|
|
32
|
+
name: string
|
|
33
|
+
/** JSON-encoded arguments. JS: `JSON.stringify(args)`. */
|
|
34
|
+
arguments: string
|
|
35
|
+
}
|
|
36
|
+
export interface ToolResult {
|
|
37
|
+
callId: string
|
|
38
|
+
output: string
|
|
39
|
+
isError: boolean
|
|
40
|
+
tokenCount?: number
|
|
41
|
+
}
|
|
42
|
+
export interface ToolSchema {
|
|
43
|
+
name: string
|
|
44
|
+
description: string
|
|
45
|
+
/** JSON-encoded JSON Schema. JS: `JSON.stringify(schema)`. */
|
|
46
|
+
parameters: string
|
|
47
|
+
}
|
|
48
|
+
export interface RuntimeTask {
|
|
49
|
+
goal: string
|
|
50
|
+
criteria?: Array<string>
|
|
51
|
+
}
|
|
52
|
+
export interface LoopPolicy {
|
|
53
|
+
maxTokens: number
|
|
54
|
+
maxTurns?: number
|
|
55
|
+
maxTotalTokens?: bigint
|
|
56
|
+
timeoutMs?: bigint
|
|
57
|
+
}
|
|
58
|
+
export interface LoopResult {
|
|
59
|
+
termination: string
|
|
60
|
+
finalMessage?: Message
|
|
61
|
+
turnsUsed: number
|
|
62
|
+
totalTokensUsed: bigint
|
|
63
|
+
}
|
|
64
|
+
/** Unified RuntimeSignal exposed to Node.js — mirrors the kernel type. */
|
|
65
|
+
export interface RuntimeSignal {
|
|
66
|
+
id: string
|
|
67
|
+
/** "cron" | "gateway" | "heartbeat" | "custom" */
|
|
68
|
+
source: string
|
|
69
|
+
/** "event" | "job" | "alert" */
|
|
70
|
+
signalType: string
|
|
71
|
+
/** "low" | "normal" | "high" | "critical" */
|
|
72
|
+
urgency: string
|
|
73
|
+
summary: string
|
|
74
|
+
/** JSON-encoded payload. */
|
|
75
|
+
payload: string
|
|
76
|
+
dedupeKey?: string
|
|
77
|
+
timestampMs: number
|
|
78
|
+
}
|
|
79
|
+
export interface SkillMetadata {
|
|
80
|
+
name: string
|
|
81
|
+
description: string
|
|
82
|
+
whenToUse?: string
|
|
83
|
+
allowedTools?: Array<string>
|
|
84
|
+
effort?: number
|
|
85
|
+
estimatedTokens: number
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Discriminated union. Inspect `kind`:
|
|
89
|
+
* - `"call_llm"` → `messages`, `tools` (includes `skill` meta-tool when skills are registered)
|
|
90
|
+
* - `"execute_tools"` → `calls`
|
|
91
|
+
* - `"done"` → `result`
|
|
92
|
+
*/
|
|
93
|
+
export interface LoopAction {
|
|
94
|
+
kind: string
|
|
95
|
+
messages?: Array<Message>
|
|
96
|
+
tools?: Array<ToolSchema>
|
|
97
|
+
calls?: Array<ToolCall>
|
|
98
|
+
result?: LoopResult
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Discriminated union for observations:
|
|
102
|
+
* - `"compressed"` → `action`, `rho_after`
|
|
103
|
+
*/
|
|
104
|
+
export interface LoopObservation {
|
|
105
|
+
kind: string
|
|
106
|
+
action?: string
|
|
107
|
+
rhoAfter?: number
|
|
108
|
+
}
|
|
109
|
+
/** JS-friendly governance verdict returned by `Governance.evaluate`. */
|
|
110
|
+
export interface GovernanceVerdictObj {
|
|
111
|
+
/** `"allow"` | `"deny"` | `"rate_limited"` | `"ask_user"` */
|
|
112
|
+
kind: string
|
|
113
|
+
reason?: string
|
|
114
|
+
/** Milliseconds until the tool may be retried. Only set when `kind === "rate_limited"`. */
|
|
115
|
+
retryAfterMs?: number
|
|
116
|
+
}
|
|
117
|
+
/** A single session of agent messages, used as input to `IdlePipeline.feedTrigger`. */
|
|
118
|
+
export interface SessionData {
|
|
119
|
+
sessionId: string
|
|
120
|
+
agentId: string
|
|
121
|
+
/** Messages from this session. */
|
|
122
|
+
messages: Array<Message>
|
|
123
|
+
/** JSON-encoded metadata blob. */
|
|
124
|
+
metadata: string
|
|
125
|
+
/** Unix ms timestamp. */
|
|
126
|
+
createdAtMs: number
|
|
127
|
+
/** Unix ms timestamp. */
|
|
128
|
+
updatedAtMs: number
|
|
129
|
+
}
|
|
130
|
+
/** A long-term memory entry as stored by the agent. */
|
|
131
|
+
export interface MemoryEntry {
|
|
132
|
+
text: string
|
|
133
|
+
score: number
|
|
134
|
+
/** JSON-encoded metadata blob. */
|
|
135
|
+
metadata: string
|
|
136
|
+
}
|
|
137
|
+
export interface CurationStats {
|
|
138
|
+
insightsProcessed: number
|
|
139
|
+
duplicatesRemoved: number
|
|
140
|
+
conflictsResolved: number
|
|
141
|
+
entriesAdded: number
|
|
142
|
+
}
|
|
143
|
+
/** The delta the `DreamStore.commit` must apply: add `toAdd`, remove `toRemoveIndices`. */
|
|
144
|
+
export interface CurationResult {
|
|
145
|
+
toAdd: Array<MemoryEntry>
|
|
146
|
+
/** Indices into the `existingMemories` slice passed to `feedTrigger`. */
|
|
147
|
+
toRemoveIndices: Array<number>
|
|
148
|
+
stats: CurationStats
|
|
149
|
+
}
|
|
150
|
+
export interface IdleRunResult {
|
|
151
|
+
sessionsProcessed: number
|
|
152
|
+
insightsExtracted: number
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Discriminated union returned by `IdlePipeline` methods. Inspect `kind`:
|
|
156
|
+
* - `"synthesize_insights"` → `messages` (SDK must call LLM, then `feedSynthesisResult`)
|
|
157
|
+
* - `"commit_memories"` → `agentId`, `curationResult`, `runResult`
|
|
158
|
+
* - `"noop"` | `"aborted"`
|
|
159
|
+
*/
|
|
160
|
+
export interface IdlePipelineAction {
|
|
161
|
+
kind: string
|
|
162
|
+
messages?: Array<Message>
|
|
163
|
+
agentId?: string
|
|
164
|
+
curationResult?: CurationResult
|
|
165
|
+
runResult?: IdleRunResult
|
|
166
|
+
}
|
|
167
|
+
export interface Criterion {
|
|
168
|
+
text: string
|
|
169
|
+
required: boolean
|
|
170
|
+
weight?: number
|
|
171
|
+
}
|
|
172
|
+
export interface CriterionResult {
|
|
173
|
+
criterion: string
|
|
174
|
+
passed: boolean
|
|
175
|
+
score: number
|
|
176
|
+
feedback: string
|
|
177
|
+
}
|
|
178
|
+
export interface EvalPipelineOptions {
|
|
179
|
+
extractSkillOnPass?: boolean
|
|
180
|
+
}
|
|
181
|
+
export interface SkillCandidate {
|
|
182
|
+
name: string
|
|
183
|
+
description: string
|
|
184
|
+
whenToUse?: string
|
|
185
|
+
content: string
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Discriminated union returned by `EvalPipeline` methods. Inspect `kind`:
|
|
189
|
+
* - `"evaluate"` → `messages` (SDK must call evaluator LLM, then `feedEvalResult`)
|
|
190
|
+
* - `"done"` → `passed`, `overallScore`, `feedback`, `details`, optional `skillCandidate`
|
|
191
|
+
*/
|
|
192
|
+
export interface EvalPipelineAction {
|
|
193
|
+
kind: string
|
|
194
|
+
messages?: Array<Message>
|
|
195
|
+
passed?: boolean
|
|
196
|
+
overallScore?: number
|
|
197
|
+
feedback?: string
|
|
198
|
+
details?: Array<CriterionResult>
|
|
199
|
+
skillCandidate?: SkillCandidate
|
|
200
|
+
}
|
|
201
|
+
export declare class ContextEngine {
|
|
202
|
+
constructor(maxTokens: number)
|
|
203
|
+
addSystemMessage(content: string, tokens: number): void
|
|
204
|
+
addUserMessage(content: string, tokens: number): void
|
|
205
|
+
addAssistantMessage(content: string, tokens: number): void
|
|
206
|
+
pressure(): number
|
|
207
|
+
totalTokens(): number
|
|
208
|
+
/**
|
|
209
|
+
* Run compression at the level the current pressure recommends.
|
|
210
|
+
* Returns tokens saved.
|
|
211
|
+
*/
|
|
212
|
+
compress(): number
|
|
213
|
+
render(): Array<Message>
|
|
214
|
+
/**
|
|
215
|
+
* Replace the available-skills set with frontmatter-only metadata.
|
|
216
|
+
* The kernel will auto-inject the `skill` meta-tool into every `CallLLM` action.
|
|
217
|
+
*/
|
|
218
|
+
setAvailableSkills(skills: Array<SkillMetadata>): void
|
|
219
|
+
}
|
|
220
|
+
export declare class LoopStateMachine {
|
|
221
|
+
constructor(policy: LoopPolicy)
|
|
222
|
+
/**
|
|
223
|
+
* Convenience: register skills directly on the state machine without
|
|
224
|
+
* reaching into the inner ContextEngine.
|
|
225
|
+
*/
|
|
226
|
+
setAvailableSkills(skills: Array<SkillMetadata>): void
|
|
227
|
+
/**
|
|
228
|
+
* Enable the `memory` meta-tool. Call with `true` when a DreamStore and agentId
|
|
229
|
+
* are configured — the SDK layer intercepts `memory` tool calls and runs the search.
|
|
230
|
+
*/
|
|
231
|
+
setMemoryEnabled(enabled: boolean): void
|
|
232
|
+
/**
|
|
233
|
+
* Enable the `knowledge` meta-tool. Call with `true` when a KnowledgeSource
|
|
234
|
+
* is configured — the SDK layer intercepts `knowledge` tool calls and runs retrieval.
|
|
235
|
+
*/
|
|
236
|
+
setKnowledgeEnabled(enabled: boolean): void
|
|
237
|
+
/**
|
|
238
|
+
* Prepend a system-level instruction to the context. Must be called before `start`.
|
|
239
|
+
* `tokens` is a caller-supplied estimate (use `content.length / 4` if unsure).
|
|
240
|
+
* The renderer skips messages with `tokens == 0`, so always pass at least 1.
|
|
241
|
+
*/
|
|
242
|
+
addSystemMessage(content: string, tokens: number): void
|
|
243
|
+
/**
|
|
244
|
+
* Pre-populate the memory partition with a long-term memory snippet.
|
|
245
|
+
* Must be called before `start`. Use for seeding known context from past sessions.
|
|
246
|
+
* `tokens` is a caller-supplied estimate; pass at least 1.
|
|
247
|
+
*/
|
|
248
|
+
addMemoryMessage(content: string, tokens: number): void
|
|
249
|
+
setTools(tools: Array<ToolSchema>): void
|
|
250
|
+
start(task: RuntimeTask): LoopAction
|
|
251
|
+
feedLlmResponse(message: Message): LoopAction
|
|
252
|
+
feedToolResults(results: Array<ToolResult>): LoopAction
|
|
253
|
+
feedTimeout(): LoopAction
|
|
254
|
+
isTerminal(): boolean
|
|
255
|
+
turn(): number
|
|
256
|
+
pressure(): number
|
|
257
|
+
/** Drain observations emitted during the most recent feed call. */
|
|
258
|
+
takeObservations(): Array<LoopObservation>
|
|
259
|
+
render(): Array<Message>
|
|
260
|
+
}
|
|
261
|
+
export declare class SignalRouter {
|
|
262
|
+
constructor(maxQueueSize: number)
|
|
263
|
+
/**
|
|
264
|
+
* Ingest a signal. Returns the disposition string:
|
|
265
|
+
* "ignore" | "observe" | "queue" | "run" | "interrupt" | "interrupt_now" | "dropped"
|
|
266
|
+
*/
|
|
267
|
+
ingest(signal: RuntimeSignal, isRunning: boolean): string
|
|
268
|
+
/** Pull the next queued signal (highest priority first). */
|
|
269
|
+
next(): RuntimeSignal | null
|
|
270
|
+
depth(): number
|
|
271
|
+
clearDedup(): void
|
|
272
|
+
}
|
|
273
|
+
export declare class Governance {
|
|
274
|
+
/**
|
|
275
|
+
* Create a governance pipeline.
|
|
276
|
+
* `defaultAction` controls the fallback when no rule matches: `"allow"` (default) or `"deny"`.
|
|
277
|
+
*/
|
|
278
|
+
constructor(defaultAction?: string | undefined | null)
|
|
279
|
+
/** Set the agent identity used in governance audit logs. */
|
|
280
|
+
setIdentity(agentId: string, sessionId: string): void
|
|
281
|
+
/**
|
|
282
|
+
* Add a permission rule. `pattern` supports globs: `"db.*"`, `"*.delete"`, `"*"`, or exact names.
|
|
283
|
+
* `action`: `"allow"` | `"deny"` | `"ask_user"`.
|
|
284
|
+
* Rules are evaluated in insertion order; first match wins.
|
|
285
|
+
*/
|
|
286
|
+
addPermissionRule(pattern: string, action: string): void
|
|
287
|
+
/** Hard-block a tool name (veto stage — cannot be overridden by permission rules). */
|
|
288
|
+
blockTool(name: string): void
|
|
289
|
+
/** Advance the internal clock used by rate limiting and audit. */
|
|
290
|
+
setTime(nowMs: bigint): void
|
|
291
|
+
/**
|
|
292
|
+
* Evaluate a tool call through the full pipeline (Permission → Veto → RateLimit → Constraint → Audit).
|
|
293
|
+
* `argsJson`: JSON-encoded tool arguments string.
|
|
294
|
+
*/
|
|
295
|
+
evaluate(toolName: string, argsJson: string): GovernanceVerdictObj
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Kernel state machine for the evaluation cycle.
|
|
299
|
+
*
|
|
300
|
+
* Drive it like this:
|
|
301
|
+
* 1. `feedOutcome(goal, criteria, result, attempt)` → `"evaluate"` action
|
|
302
|
+
* 2. Call evaluator LLM with `action.messages`, collect the text response
|
|
303
|
+
* 3. `feedEvalResult(text)` → `"done"` action
|
|
304
|
+
* 4. Read `action.passed` / `action.feedback` / `action.skillCandidate`
|
|
305
|
+
* 5. Call `reset()` before the next attempt
|
|
306
|
+
*/
|
|
307
|
+
export declare class EvalPipeline {
|
|
308
|
+
constructor(options?: EvalPipelineOptions | undefined | null)
|
|
309
|
+
/**
|
|
310
|
+
* Phase 1 — provide the goal, criteria, agent output, and attempt number.
|
|
311
|
+
* Returns an `"evaluate"` action with messages to send to the evaluator LLM.
|
|
312
|
+
*/
|
|
313
|
+
feedOutcome(goal: string, criteria: Array<Criterion>, result: string, attempt: number): EvalPipelineAction
|
|
314
|
+
/** Phase 2 — feed back the evaluator LLM's text response. */
|
|
315
|
+
feedEvalResult(content: string): EvalPipelineAction
|
|
316
|
+
reset(): void
|
|
317
|
+
isIdle(): boolean
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Kernel state machine for the idle dreaming cycle.
|
|
321
|
+
*
|
|
322
|
+
* Drive it like this:
|
|
323
|
+
* 1. `feedTrigger(sessions, existingMemories, nowMs)` → `"synthesize_insights"` action
|
|
324
|
+
* 2. Call LLM with `action.messages`, collect the text response
|
|
325
|
+
* 3. `feedSynthesisResult(text)` → `"commit_memories"` action
|
|
326
|
+
* 4. Apply `action.curationResult` via `DreamStore.commit`, then call `reset()`
|
|
327
|
+
*/
|
|
328
|
+
export declare class IdlePipeline {
|
|
329
|
+
constructor(agentId: string)
|
|
330
|
+
/** Phase 1 — provide sessions + current memory snapshot; kernel builds the LLM prompt. */
|
|
331
|
+
feedTrigger(sessions: Array<SessionData>, existingMemories: Array<MemoryEntry>, nowMs: number): IdlePipelineAction
|
|
332
|
+
/** Phase 2 — feed back the LLM's synthesis text; kernel parses and curates. */
|
|
333
|
+
feedSynthesisResult(content: string): IdlePipelineAction
|
|
334
|
+
isIdle(): boolean
|
|
335
|
+
/** Reset to `Idle` after handling `CommitMemories` to allow the next cycle. */
|
|
336
|
+
reset(): void
|
|
337
|
+
}
|
package/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
/*
|
|
2
|
-
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/* prettier-ignore */
|
|
4
|
+
|
|
5
|
+
/* auto-generated by NAPI-RS */
|
|
3
6
|
|
|
4
7
|
const { existsSync, readFileSync } = require('fs')
|
|
5
8
|
const { join } = require('path')
|
|
@@ -11,55 +14,286 @@ let localFileExisted = false
|
|
|
11
14
|
let loadError = null
|
|
12
15
|
|
|
13
16
|
function isMusl() {
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
// For Node 10
|
|
18
|
+
if (!process.report || typeof process.report.getReport !== 'function') {
|
|
19
|
+
try {
|
|
20
|
+
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
|
21
|
+
return readFileSync(lddPath, 'utf8').includes('musl')
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return true
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
const { glibcVersionRuntime } = process.report.getReport().header
|
|
27
|
+
return !glibcVersionRuntime
|
|
28
|
+
}
|
|
16
29
|
}
|
|
17
30
|
|
|
18
31
|
switch (platform) {
|
|
19
32
|
case 'android':
|
|
20
33
|
switch (arch) {
|
|
21
|
-
case 'arm64':
|
|
22
|
-
|
|
23
|
-
|
|
34
|
+
case 'arm64':
|
|
35
|
+
localFileExisted = existsSync(join(__dirname, 'index.android-arm64.node'))
|
|
36
|
+
try {
|
|
37
|
+
if (localFileExisted) {
|
|
38
|
+
nativeBinding = require('./index.android-arm64.node')
|
|
39
|
+
} else {
|
|
40
|
+
nativeBinding = require('@deepstrike/core-android-arm64')
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
loadError = e
|
|
44
|
+
}
|
|
45
|
+
break
|
|
46
|
+
case 'arm':
|
|
47
|
+
localFileExisted = existsSync(join(__dirname, 'index.android-arm-eabi.node'))
|
|
48
|
+
try {
|
|
49
|
+
if (localFileExisted) {
|
|
50
|
+
nativeBinding = require('./index.android-arm-eabi.node')
|
|
51
|
+
} else {
|
|
52
|
+
nativeBinding = require('@deepstrike/core-android-arm-eabi')
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {
|
|
55
|
+
loadError = e
|
|
56
|
+
}
|
|
57
|
+
break
|
|
58
|
+
default:
|
|
59
|
+
throw new Error(`Unsupported architecture on Android ${arch}`)
|
|
24
60
|
}
|
|
25
61
|
break
|
|
26
62
|
case 'win32':
|
|
27
63
|
switch (arch) {
|
|
28
|
-
case 'x64':
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
64
|
+
case 'x64':
|
|
65
|
+
localFileExisted = existsSync(
|
|
66
|
+
join(__dirname, 'index.win32-x64-msvc.node')
|
|
67
|
+
)
|
|
68
|
+
try {
|
|
69
|
+
if (localFileExisted) {
|
|
70
|
+
nativeBinding = require('./index.win32-x64-msvc.node')
|
|
71
|
+
} else {
|
|
72
|
+
nativeBinding = require('@deepstrike/core-win32-x64-msvc')
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
loadError = e
|
|
76
|
+
}
|
|
77
|
+
break
|
|
78
|
+
case 'ia32':
|
|
79
|
+
localFileExisted = existsSync(
|
|
80
|
+
join(__dirname, 'index.win32-ia32-msvc.node')
|
|
81
|
+
)
|
|
82
|
+
try {
|
|
83
|
+
if (localFileExisted) {
|
|
84
|
+
nativeBinding = require('./index.win32-ia32-msvc.node')
|
|
85
|
+
} else {
|
|
86
|
+
nativeBinding = require('@deepstrike/core-win32-ia32-msvc')
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
loadError = e
|
|
90
|
+
}
|
|
91
|
+
break
|
|
92
|
+
case 'arm64':
|
|
93
|
+
localFileExisted = existsSync(
|
|
94
|
+
join(__dirname, 'index.win32-arm64-msvc.node')
|
|
95
|
+
)
|
|
96
|
+
try {
|
|
97
|
+
if (localFileExisted) {
|
|
98
|
+
nativeBinding = require('./index.win32-arm64-msvc.node')
|
|
99
|
+
} else {
|
|
100
|
+
nativeBinding = require('@deepstrike/core-win32-arm64-msvc')
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
loadError = e
|
|
104
|
+
}
|
|
105
|
+
break
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unsupported architecture on Windows: ${arch}`)
|
|
32
108
|
}
|
|
33
109
|
break
|
|
34
110
|
case 'darwin':
|
|
35
|
-
localFileExisted = existsSync(join(__dirname, '
|
|
111
|
+
localFileExisted = existsSync(join(__dirname, 'index.darwin-universal.node'))
|
|
36
112
|
try {
|
|
37
|
-
if (localFileExisted) {
|
|
113
|
+
if (localFileExisted) {
|
|
114
|
+
nativeBinding = require('./index.darwin-universal.node')
|
|
115
|
+
} else {
|
|
116
|
+
nativeBinding = require('@deepstrike/core-darwin-universal')
|
|
117
|
+
}
|
|
118
|
+
break
|
|
38
119
|
} catch {}
|
|
39
120
|
switch (arch) {
|
|
40
|
-
case 'x64':
|
|
41
|
-
|
|
42
|
-
|
|
121
|
+
case 'x64':
|
|
122
|
+
localFileExisted = existsSync(join(__dirname, 'index.darwin-x64.node'))
|
|
123
|
+
try {
|
|
124
|
+
if (localFileExisted) {
|
|
125
|
+
nativeBinding = require('./index.darwin-x64.node')
|
|
126
|
+
} else {
|
|
127
|
+
nativeBinding = require('@deepstrike/core-darwin-x64')
|
|
128
|
+
}
|
|
129
|
+
} catch (e) {
|
|
130
|
+
loadError = e
|
|
131
|
+
}
|
|
132
|
+
break
|
|
133
|
+
case 'arm64':
|
|
134
|
+
localFileExisted = existsSync(
|
|
135
|
+
join(__dirname, 'index.darwin-arm64.node')
|
|
136
|
+
)
|
|
137
|
+
try {
|
|
138
|
+
if (localFileExisted) {
|
|
139
|
+
nativeBinding = require('./index.darwin-arm64.node')
|
|
140
|
+
} else {
|
|
141
|
+
nativeBinding = require('@deepstrike/core-darwin-arm64')
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
144
|
+
loadError = e
|
|
145
|
+
}
|
|
146
|
+
break
|
|
147
|
+
default:
|
|
148
|
+
throw new Error(`Unsupported architecture on macOS: ${arch}`)
|
|
43
149
|
}
|
|
44
150
|
break
|
|
45
151
|
case 'freebsd':
|
|
46
|
-
if (arch !== 'x64')
|
|
47
|
-
|
|
152
|
+
if (arch !== 'x64') {
|
|
153
|
+
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
|
|
154
|
+
}
|
|
155
|
+
localFileExisted = existsSync(join(__dirname, 'index.freebsd-x64.node'))
|
|
156
|
+
try {
|
|
157
|
+
if (localFileExisted) {
|
|
158
|
+
nativeBinding = require('./index.freebsd-x64.node')
|
|
159
|
+
} else {
|
|
160
|
+
nativeBinding = require('@deepstrike/core-freebsd-x64')
|
|
161
|
+
}
|
|
162
|
+
} catch (e) {
|
|
163
|
+
loadError = e
|
|
164
|
+
}
|
|
48
165
|
break
|
|
49
166
|
case 'linux':
|
|
50
167
|
switch (arch) {
|
|
51
168
|
case 'x64':
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
169
|
+
if (isMusl()) {
|
|
170
|
+
localFileExisted = existsSync(
|
|
171
|
+
join(__dirname, 'index.linux-x64-musl.node')
|
|
172
|
+
)
|
|
173
|
+
try {
|
|
174
|
+
if (localFileExisted) {
|
|
175
|
+
nativeBinding = require('./index.linux-x64-musl.node')
|
|
176
|
+
} else {
|
|
177
|
+
nativeBinding = require('@deepstrike/core-linux-x64-musl')
|
|
178
|
+
}
|
|
179
|
+
} catch (e) {
|
|
180
|
+
loadError = e
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
localFileExisted = existsSync(
|
|
184
|
+
join(__dirname, 'index.linux-x64-gnu.node')
|
|
185
|
+
)
|
|
186
|
+
try {
|
|
187
|
+
if (localFileExisted) {
|
|
188
|
+
nativeBinding = require('./index.linux-x64-gnu.node')
|
|
189
|
+
} else {
|
|
190
|
+
nativeBinding = require('@deepstrike/core-linux-x64-gnu')
|
|
191
|
+
}
|
|
192
|
+
} catch (e) {
|
|
193
|
+
loadError = e
|
|
194
|
+
}
|
|
195
|
+
}
|
|
55
196
|
break
|
|
56
197
|
case 'arm64':
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
198
|
+
if (isMusl()) {
|
|
199
|
+
localFileExisted = existsSync(
|
|
200
|
+
join(__dirname, 'index.linux-arm64-musl.node')
|
|
201
|
+
)
|
|
202
|
+
try {
|
|
203
|
+
if (localFileExisted) {
|
|
204
|
+
nativeBinding = require('./index.linux-arm64-musl.node')
|
|
205
|
+
} else {
|
|
206
|
+
nativeBinding = require('@deepstrike/core-linux-arm64-musl')
|
|
207
|
+
}
|
|
208
|
+
} catch (e) {
|
|
209
|
+
loadError = e
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
localFileExisted = existsSync(
|
|
213
|
+
join(__dirname, 'index.linux-arm64-gnu.node')
|
|
214
|
+
)
|
|
215
|
+
try {
|
|
216
|
+
if (localFileExisted) {
|
|
217
|
+
nativeBinding = require('./index.linux-arm64-gnu.node')
|
|
218
|
+
} else {
|
|
219
|
+
nativeBinding = require('@deepstrike/core-linux-arm64-gnu')
|
|
220
|
+
}
|
|
221
|
+
} catch (e) {
|
|
222
|
+
loadError = e
|
|
223
|
+
}
|
|
224
|
+
}
|
|
60
225
|
break
|
|
61
226
|
case 'arm':
|
|
62
|
-
|
|
227
|
+
if (isMusl()) {
|
|
228
|
+
localFileExisted = existsSync(
|
|
229
|
+
join(__dirname, 'index.linux-arm-musleabihf.node')
|
|
230
|
+
)
|
|
231
|
+
try {
|
|
232
|
+
if (localFileExisted) {
|
|
233
|
+
nativeBinding = require('./index.linux-arm-musleabihf.node')
|
|
234
|
+
} else {
|
|
235
|
+
nativeBinding = require('@deepstrike/core-linux-arm-musleabihf')
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
loadError = e
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
localFileExisted = existsSync(
|
|
242
|
+
join(__dirname, 'index.linux-arm-gnueabihf.node')
|
|
243
|
+
)
|
|
244
|
+
try {
|
|
245
|
+
if (localFileExisted) {
|
|
246
|
+
nativeBinding = require('./index.linux-arm-gnueabihf.node')
|
|
247
|
+
} else {
|
|
248
|
+
nativeBinding = require('@deepstrike/core-linux-arm-gnueabihf')
|
|
249
|
+
}
|
|
250
|
+
} catch (e) {
|
|
251
|
+
loadError = e
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
break
|
|
255
|
+
case 'riscv64':
|
|
256
|
+
if (isMusl()) {
|
|
257
|
+
localFileExisted = existsSync(
|
|
258
|
+
join(__dirname, 'index.linux-riscv64-musl.node')
|
|
259
|
+
)
|
|
260
|
+
try {
|
|
261
|
+
if (localFileExisted) {
|
|
262
|
+
nativeBinding = require('./index.linux-riscv64-musl.node')
|
|
263
|
+
} else {
|
|
264
|
+
nativeBinding = require('@deepstrike/core-linux-riscv64-musl')
|
|
265
|
+
}
|
|
266
|
+
} catch (e) {
|
|
267
|
+
loadError = e
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
localFileExisted = existsSync(
|
|
271
|
+
join(__dirname, 'index.linux-riscv64-gnu.node')
|
|
272
|
+
)
|
|
273
|
+
try {
|
|
274
|
+
if (localFileExisted) {
|
|
275
|
+
nativeBinding = require('./index.linux-riscv64-gnu.node')
|
|
276
|
+
} else {
|
|
277
|
+
nativeBinding = require('@deepstrike/core-linux-riscv64-gnu')
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
loadError = e
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
break
|
|
284
|
+
case 's390x':
|
|
285
|
+
localFileExisted = existsSync(
|
|
286
|
+
join(__dirname, 'index.linux-s390x-gnu.node')
|
|
287
|
+
)
|
|
288
|
+
try {
|
|
289
|
+
if (localFileExisted) {
|
|
290
|
+
nativeBinding = require('./index.linux-s390x-gnu.node')
|
|
291
|
+
} else {
|
|
292
|
+
nativeBinding = require('@deepstrike/core-linux-s390x-gnu')
|
|
293
|
+
}
|
|
294
|
+
} catch (e) {
|
|
295
|
+
loadError = e
|
|
296
|
+
}
|
|
63
297
|
break
|
|
64
298
|
default:
|
|
65
299
|
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
|
@@ -69,4 +303,18 @@ switch (platform) {
|
|
|
69
303
|
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
|
|
70
304
|
}
|
|
71
305
|
|
|
72
|
-
|
|
306
|
+
if (!nativeBinding) {
|
|
307
|
+
if (loadError) {
|
|
308
|
+
throw loadError
|
|
309
|
+
}
|
|
310
|
+
throw new Error(`Failed to load native binding`)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const { ContextEngine, LoopStateMachine, SignalRouter, Governance, EvalPipeline, IdlePipeline } = nativeBinding
|
|
314
|
+
|
|
315
|
+
module.exports.ContextEngine = ContextEngine
|
|
316
|
+
module.exports.LoopStateMachine = LoopStateMachine
|
|
317
|
+
module.exports.SignalRouter = SignalRouter
|
|
318
|
+
module.exports.Governance = Governance
|
|
319
|
+
module.exports.EvalPipeline = EvalPipeline
|
|
320
|
+
module.exports.IdlePipeline = IdlePipeline
|
|
@@ -1,3 +1,22 @@
|
|
|
1
1
|
# `@deepstrike/core-darwin-arm64`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Platform-specific native addon for [`@deepstrike/core`](https://www.npmjs.com/package/@deepstrike/core).
|
|
4
|
+
|
|
5
|
+
- **Platform:** macOS ARM64 (Apple Silicon)
|
|
6
|
+
- **Target triple:** `aarch64-apple-darwin`
|
|
7
|
+
|
|
8
|
+
## Do not install directly
|
|
9
|
+
|
|
10
|
+
This package is an internal binary dependency. Install [`@deepstrike/sdk`](https://www.npmjs.com/package/@deepstrike/sdk) instead — the correct platform package is selected and installed automatically via `optionalDependencies`.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @deepstrike/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
`@deepstrike/core` loads this package at runtime when running on macOS with Apple Silicon. The `.node` file is a compiled Rust extension built with [napi-rs](https://napi.rs) that exposes the DeepStrike kernel (loop control, context compression, governance, signal routing) to Node.js.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Apache-2.0 OR MIT
|
package/npm/darwin-x64/README.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
1
|
# `@deepstrike/core-darwin-x64`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Platform-specific native addon for [`@deepstrike/core`](https://www.npmjs.com/package/@deepstrike/core).
|
|
4
|
+
|
|
5
|
+
- **Platform:** macOS x64 (Intel)
|
|
6
|
+
- **Target triple:** `x86_64-apple-darwin`
|
|
7
|
+
|
|
8
|
+
## Do not install directly
|
|
9
|
+
|
|
10
|
+
This package is an internal binary dependency. Install [`@deepstrike/sdk`](https://www.npmjs.com/package/@deepstrike/sdk) instead — the correct platform package is selected and installed automatically via `optionalDependencies`.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @deepstrike/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
`@deepstrike/core` loads this package at runtime when running on macOS with an Intel processor. The `.node` file is a compiled Rust extension built with [napi-rs](https://napi.rs) that exposes the DeepStrike kernel (loop control, context compression, governance, signal routing) to Node.js.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Apache-2.0 OR MIT
|
|
@@ -1,3 +1,22 @@
|
|
|
1
1
|
# `@deepstrike/core-linux-arm64-gnu`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Platform-specific native addon for [`@deepstrike/core`](https://www.npmjs.com/package/@deepstrike/core).
|
|
4
|
+
|
|
5
|
+
- **Platform:** Linux ARM64 (glibc)
|
|
6
|
+
- **Target triple:** `aarch64-unknown-linux-gnu`
|
|
7
|
+
|
|
8
|
+
## Do not install directly
|
|
9
|
+
|
|
10
|
+
This package is an internal binary dependency. Install [`@deepstrike/sdk`](https://www.npmjs.com/package/@deepstrike/sdk) instead — the correct platform package is selected and installed automatically via `optionalDependencies`.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @deepstrike/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
`@deepstrike/core` loads this package at runtime when running on Linux ARM64 with glibc (e.g. AWS Graviton, Raspberry Pi OS 64-bit). The `.node` file is a compiled Rust extension built with [napi-rs](https://napi.rs) that exposes the DeepStrike kernel (loop control, context compression, governance, signal routing) to Node.js.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Apache-2.0 OR MIT
|
|
@@ -1,3 +1,22 @@
|
|
|
1
1
|
# `@deepstrike/core-linux-arm64-musl`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Platform-specific native addon for [`@deepstrike/core`](https://www.npmjs.com/package/@deepstrike/core).
|
|
4
|
+
|
|
5
|
+
- **Platform:** Linux ARM64 (musl / Alpine)
|
|
6
|
+
- **Target triple:** `aarch64-unknown-linux-musl`
|
|
7
|
+
|
|
8
|
+
## Do not install directly
|
|
9
|
+
|
|
10
|
+
This package is an internal binary dependency. Install [`@deepstrike/sdk`](https://www.npmjs.com/package/@deepstrike/sdk) instead — the correct platform package is selected and installed automatically via `optionalDependencies`.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @deepstrike/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
`@deepstrike/core` loads this package at runtime when running on Linux ARM64 with musl libc (e.g. Alpine Linux on ARM). The `.node` file is a compiled Rust extension built with [napi-rs](https://napi.rs) that exposes the DeepStrike kernel (loop control, context compression, governance, signal routing) to Node.js.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Apache-2.0 OR MIT
|
|
@@ -1,3 +1,22 @@
|
|
|
1
1
|
# `@deepstrike/core-linux-x64-gnu`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Platform-specific native addon for [`@deepstrike/core`](https://www.npmjs.com/package/@deepstrike/core).
|
|
4
|
+
|
|
5
|
+
- **Platform:** Linux x64 (glibc)
|
|
6
|
+
- **Target triple:** `x86_64-unknown-linux-gnu`
|
|
7
|
+
|
|
8
|
+
## Do not install directly
|
|
9
|
+
|
|
10
|
+
This package is an internal binary dependency. Install [`@deepstrike/sdk`](https://www.npmjs.com/package/@deepstrike/sdk) instead — the correct platform package is selected and installed automatically via `optionalDependencies`.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @deepstrike/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
`@deepstrike/core` loads this package at runtime when running on Linux x64 with glibc. The `.node` file is a compiled Rust extension built with [napi-rs](https://napi.rs) that exposes the DeepStrike kernel (loop control, context compression, governance, signal routing) to Node.js.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Apache-2.0 OR MIT
|
|
@@ -1,3 +1,22 @@
|
|
|
1
1
|
# `@deepstrike/core-linux-x64-musl`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Platform-specific native addon for [`@deepstrike/core`](https://www.npmjs.com/package/@deepstrike/core).
|
|
4
|
+
|
|
5
|
+
- **Platform:** Linux x64 (musl / Alpine)
|
|
6
|
+
- **Target triple:** `x86_64-unknown-linux-musl`
|
|
7
|
+
|
|
8
|
+
## Do not install directly
|
|
9
|
+
|
|
10
|
+
This package is an internal binary dependency. Install [`@deepstrike/sdk`](https://www.npmjs.com/package/@deepstrike/sdk) instead — the correct platform package is selected and installed automatically via `optionalDependencies`.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @deepstrike/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
`@deepstrike/core` loads this package at runtime when running on Linux x64 with musl libc (e.g. Alpine Linux, Docker scratch images). The `.node` file is a compiled Rust extension built with [napi-rs](https://napi.rs) that exposes the DeepStrike kernel (loop control, context compression, governance, signal routing) to Node.js.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Apache-2.0 OR MIT
|
|
@@ -1,3 +1,22 @@
|
|
|
1
1
|
# `@deepstrike/core-win32-x64-msvc`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Platform-specific native addon for [`@deepstrike/core`](https://www.npmjs.com/package/@deepstrike/core).
|
|
4
|
+
|
|
5
|
+
- **Platform:** Windows x64 (MSVC)
|
|
6
|
+
- **Target triple:** `x86_64-pc-windows-msvc`
|
|
7
|
+
|
|
8
|
+
## Do not install directly
|
|
9
|
+
|
|
10
|
+
This package is an internal binary dependency. Install [`@deepstrike/sdk`](https://www.npmjs.com/package/@deepstrike/sdk) instead — the correct platform package is selected and installed automatically via `optionalDependencies`.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @deepstrike/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
`@deepstrike/core` loads this package at runtime when running on Windows x64. The `.node` file is a compiled Rust extension built with [napi-rs](https://napi.rs) that exposes the DeepStrike kernel (loop control, context compression, governance, signal routing) to Node.js.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Apache-2.0 OR MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepstrike/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "DeepStrike kernel — pre-built native addon",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
]
|
|
17
17
|
},
|
|
18
18
|
"optionalDependencies": {
|
|
19
|
-
"@deepstrike/core-linux-x64-gnu": "0.1.
|
|
20
|
-
"@deepstrike/core-linux-arm64-gnu": "0.1.
|
|
21
|
-
"@deepstrike/core-darwin-x64": "0.1.
|
|
22
|
-
"@deepstrike/core-darwin-arm64": "0.1.
|
|
23
|
-
"@deepstrike/core-win32-x64-msvc": "0.1.
|
|
19
|
+
"@deepstrike/core-linux-x64-gnu": "0.1.4",
|
|
20
|
+
"@deepstrike/core-linux-arm64-gnu": "0.1.4",
|
|
21
|
+
"@deepstrike/core-darwin-x64": "0.1.4",
|
|
22
|
+
"@deepstrike/core-darwin-arm64": "0.1.4",
|
|
23
|
+
"@deepstrike/core-win32-x64-msvc": "0.1.4"
|
|
24
24
|
}
|
|
25
25
|
}
|
package/src/lib.rs
CHANGED
|
@@ -43,10 +43,13 @@ use compact_str::CompactString;
|
|
|
43
43
|
|
|
44
44
|
use deepstrike_core::context::manager::ContextManager;
|
|
45
45
|
use deepstrike_core::context::pressure::PressureAction;
|
|
46
|
+
use deepstrike_core::governance::permission::{PermissionAction, PermissionRule};
|
|
46
47
|
use deepstrike_core::governance::pipeline::GovernancePipeline as RustGovernancePipeline;
|
|
48
|
+
use deepstrike_core::types::agent::AgentIdentity;
|
|
49
|
+
use deepstrike_core::types::policy::GovernanceVerdict as RustGovernanceVerdict;
|
|
47
50
|
use deepstrike_core::harness::eval_pipeline::{
|
|
48
|
-
|
|
49
|
-
EvalPipeline as RustEvalPipeline,
|
|
51
|
+
Criterion as RustCriterion, EvalAction as RustEvalAction, EvalEvent as RustEvalEvent,
|
|
52
|
+
EvalPolicy as RustEvalPolicy, EvalPipeline as RustEvalPipeline,
|
|
50
53
|
};
|
|
51
54
|
use deepstrike_core::memory::curator::CurationResult as RustCurationResult;
|
|
52
55
|
use deepstrike_core::memory::durable::SessionData as RustSessionData;
|
|
@@ -76,11 +79,30 @@ use deepstrike_core::types::task::RuntimeTask as RustRuntimeTask;
|
|
|
76
79
|
|
|
77
80
|
// ────────────────────────────────────── POD types (plain JS objects) ──────────────────────────────────────
|
|
78
81
|
|
|
82
|
+
#[napi(object)]
|
|
83
|
+
#[derive(Clone)]
|
|
84
|
+
pub struct ContentPartObj {
|
|
85
|
+
/// `"text"` | `"image"` | `"audio"` | `"tool_result"`
|
|
86
|
+
pub r#type: String,
|
|
87
|
+
pub text: Option<String>,
|
|
88
|
+
pub url: Option<String>,
|
|
89
|
+
pub data: Option<String>,
|
|
90
|
+
pub media_type: Option<String>,
|
|
91
|
+
pub detail: Option<String>,
|
|
92
|
+
pub call_id: Option<String>,
|
|
93
|
+
pub output: Option<String>,
|
|
94
|
+
pub is_error: Option<bool>,
|
|
95
|
+
}
|
|
96
|
+
|
|
79
97
|
#[napi(object)]
|
|
80
98
|
#[derive(Clone)]
|
|
81
99
|
pub struct Message {
|
|
82
100
|
pub role: String,
|
|
101
|
+
/// Plain-text content. When `content_parts` is present, this holds only the
|
|
102
|
+
/// concatenated text segments for backward compatibility.
|
|
83
103
|
pub content: String,
|
|
104
|
+
/// Structured multimodal content parts. When present, takes precedence over `content`.
|
|
105
|
+
pub content_parts: Option<Vec<ContentPartObj>>,
|
|
84
106
|
pub token_count: Option<u32>,
|
|
85
107
|
pub tool_calls: Vec<ToolCall>,
|
|
86
108
|
}
|
|
@@ -288,6 +310,51 @@ fn role_to_str(role: Role) -> &'static str {
|
|
|
288
310
|
}
|
|
289
311
|
}
|
|
290
312
|
|
|
313
|
+
fn content_part_to_rust(p: ContentPartObj) -> ContentPart {
|
|
314
|
+
match p.r#type.as_str() {
|
|
315
|
+
"image" => ContentPart::Image {
|
|
316
|
+
url: p.url,
|
|
317
|
+
data: p.data,
|
|
318
|
+
media_type: p.media_type,
|
|
319
|
+
detail: p.detail,
|
|
320
|
+
},
|
|
321
|
+
"audio" => ContentPart::Audio {
|
|
322
|
+
data: p.data.unwrap_or_default(),
|
|
323
|
+
media_type: p.media_type.unwrap_or_else(|| "audio/wav".into()),
|
|
324
|
+
},
|
|
325
|
+
"tool_result" => ContentPart::ToolResult {
|
|
326
|
+
call_id: CompactString::new(&p.call_id.unwrap_or_default()),
|
|
327
|
+
output: p.output.unwrap_or_default(),
|
|
328
|
+
is_error: p.is_error.unwrap_or(false),
|
|
329
|
+
},
|
|
330
|
+
_ => ContentPart::Text { text: p.text.unwrap_or_default() },
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
fn content_part_from_rust(p: &ContentPart) -> ContentPartObj {
|
|
335
|
+
match p {
|
|
336
|
+
ContentPart::Text { text } => ContentPartObj {
|
|
337
|
+
r#type: "text".into(), text: Some(text.clone()),
|
|
338
|
+
url: None, data: None, media_type: None, detail: None,
|
|
339
|
+
call_id: None, output: None, is_error: None,
|
|
340
|
+
},
|
|
341
|
+
ContentPart::Image { url, data, media_type, detail } => ContentPartObj {
|
|
342
|
+
r#type: "image".into(), text: None,
|
|
343
|
+
url: url.clone(), data: data.clone(), media_type: media_type.clone(), detail: detail.clone(),
|
|
344
|
+
call_id: None, output: None, is_error: None,
|
|
345
|
+
},
|
|
346
|
+
ContentPart::Audio { data, media_type } => ContentPartObj {
|
|
347
|
+
r#type: "audio".into(), text: None, url: None,
|
|
348
|
+
data: Some(data.clone()), media_type: Some(media_type.clone()), detail: None,
|
|
349
|
+
call_id: None, output: None, is_error: None,
|
|
350
|
+
},
|
|
351
|
+
ContentPart::ToolResult { call_id, output, is_error } => ContentPartObj {
|
|
352
|
+
r#type: "tool_result".into(), text: None, url: None, data: None, media_type: None, detail: None,
|
|
353
|
+
call_id: Some(call_id.to_string()), output: Some(output.clone()), is_error: Some(*is_error),
|
|
354
|
+
},
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
291
358
|
fn message_to_rust(m: Message) -> Result<RustMessage> {
|
|
292
359
|
let role = role_str_to_rust(&m.role)?;
|
|
293
360
|
let tool_calls: Vec<RustToolCall> = m
|
|
@@ -295,32 +362,29 @@ fn message_to_rust(m: Message) -> Result<RustMessage> {
|
|
|
295
362
|
.into_iter()
|
|
296
363
|
.map(tool_call_to_rust)
|
|
297
364
|
.collect::<Result<_>>()?;
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
})
|
|
365
|
+
let content = match m.content_parts {
|
|
366
|
+
Some(parts) if !parts.is_empty() => Content::Parts(parts.into_iter().map(content_part_to_rust).collect()),
|
|
367
|
+
_ => Content::Text(m.content),
|
|
368
|
+
};
|
|
369
|
+
Ok(RustMessage { role, content, tool_calls, token_count: m.token_count })
|
|
304
370
|
}
|
|
305
371
|
|
|
306
372
|
fn message_from_rust(m: &RustMessage) -> Message {
|
|
307
|
-
let content = match &m.content {
|
|
308
|
-
Content::Text(s) => s.clone(),
|
|
309
|
-
Content::Parts(parts) =>
|
|
310
|
-
.iter()
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
})
|
|
318
|
-
.collect::<Vec<_>>()
|
|
319
|
-
.join("\n"),
|
|
373
|
+
let (content, content_parts) = match &m.content {
|
|
374
|
+
Content::Text(s) => (s.clone(), None),
|
|
375
|
+
Content::Parts(parts) => {
|
|
376
|
+
let text_only: String = parts.iter().filter_map(|p| match p {
|
|
377
|
+
ContentPart::Text { text } => Some(text.as_str()),
|
|
378
|
+
_ => None,
|
|
379
|
+
}).collect::<Vec<_>>().join("\n");
|
|
380
|
+
let objs: Vec<ContentPartObj> = parts.iter().map(content_part_from_rust).collect();
|
|
381
|
+
(text_only, Some(objs))
|
|
382
|
+
}
|
|
320
383
|
};
|
|
321
384
|
Message {
|
|
322
385
|
role: role_to_str(m.role).to_string(),
|
|
323
386
|
content,
|
|
387
|
+
content_parts,
|
|
324
388
|
token_count: m.token_count,
|
|
325
389
|
tool_calls: m.tool_calls.iter().map(tool_call_from_rust).collect(),
|
|
326
390
|
}
|
|
@@ -577,6 +641,30 @@ impl LoopStateMachine {
|
|
|
577
641
|
self.inner.ctx.set_knowledge_enabled(enabled);
|
|
578
642
|
}
|
|
579
643
|
|
|
644
|
+
/// Prepend a system-level instruction to the context. Must be called before `start`.
|
|
645
|
+
/// `tokens` is a caller-supplied estimate (use `content.length / 4` if unsure).
|
|
646
|
+
/// The renderer skips messages with `tokens == 0`, so always pass at least 1.
|
|
647
|
+
#[napi]
|
|
648
|
+
pub fn add_system_message(&mut self, content: String, tokens: u32) {
|
|
649
|
+
self.inner
|
|
650
|
+
.ctx
|
|
651
|
+
.partitions
|
|
652
|
+
.system
|
|
653
|
+
.push(RustMessage::system(content), tokens.max(1));
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/// Pre-populate the memory partition with a long-term memory snippet.
|
|
657
|
+
/// Must be called before `start`. Use for seeding known context from past sessions.
|
|
658
|
+
/// `tokens` is a caller-supplied estimate; pass at least 1.
|
|
659
|
+
#[napi]
|
|
660
|
+
pub fn add_memory_message(&mut self, content: String, tokens: u32) {
|
|
661
|
+
self.inner
|
|
662
|
+
.ctx
|
|
663
|
+
.partitions
|
|
664
|
+
.memory
|
|
665
|
+
.push(RustMessage::user(content), tokens.max(1));
|
|
666
|
+
}
|
|
667
|
+
|
|
580
668
|
#[napi]
|
|
581
669
|
pub fn set_tools(&mut self, tools: Vec<ToolSchema>) -> Result<()> {
|
|
582
670
|
let rust_tools: Vec<RustToolSchema> = tools
|
|
@@ -683,27 +771,100 @@ impl SignalRouter {
|
|
|
683
771
|
|
|
684
772
|
// ─────────────────────────────────────────── Governance ───────────────────────────────────────────
|
|
685
773
|
|
|
774
|
+
/// JS-friendly governance verdict returned by `Governance.evaluate`.
|
|
775
|
+
#[napi(object)]
|
|
776
|
+
#[derive(Clone)]
|
|
777
|
+
pub struct GovernanceVerdictObj {
|
|
778
|
+
/// `"allow"` | `"deny"` | `"rate_limited"` | `"ask_user"`
|
|
779
|
+
pub kind: String,
|
|
780
|
+
pub reason: Option<String>,
|
|
781
|
+
/// Milliseconds until the tool may be retried. Only set when `kind === "rate_limited"`.
|
|
782
|
+
pub retry_after_ms: Option<f64>,
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
fn verdict_to_js(v: RustGovernanceVerdict) -> GovernanceVerdictObj {
|
|
786
|
+
match v {
|
|
787
|
+
RustGovernanceVerdict::Allow => GovernanceVerdictObj { kind: "allow".into(), reason: None, retry_after_ms: None },
|
|
788
|
+
RustGovernanceVerdict::Deny { reason, .. } => GovernanceVerdictObj { kind: "deny".into(), reason: Some(reason), retry_after_ms: None },
|
|
789
|
+
RustGovernanceVerdict::RateLimited { retry_after_ms } => GovernanceVerdictObj { kind: "rate_limited".into(), reason: None, retry_after_ms: Some(retry_after_ms as f64) },
|
|
790
|
+
RustGovernanceVerdict::AskUser { reason } => GovernanceVerdictObj { kind: "ask_user".into(), reason: Some(reason), retry_after_ms: None },
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
686
794
|
#[napi]
|
|
687
795
|
pub struct Governance {
|
|
688
796
|
inner: RustGovernancePipeline,
|
|
797
|
+
agent_id: String,
|
|
798
|
+
session_id: String,
|
|
689
799
|
}
|
|
690
800
|
|
|
691
801
|
#[napi]
|
|
692
802
|
impl Governance {
|
|
803
|
+
/// Create a governance pipeline.
|
|
804
|
+
/// `defaultAction` controls the fallback when no rule matches: `"allow"` (default) or `"deny"`.
|
|
693
805
|
#[napi(constructor)]
|
|
694
|
-
pub fn new() -> Self {
|
|
695
|
-
|
|
806
|
+
pub fn new(default_action: Option<String>) -> Self {
|
|
807
|
+
let action = match default_action.as_deref() {
|
|
808
|
+
Some("deny") => PermissionAction::Deny,
|
|
809
|
+
Some("ask_user") => PermissionAction::AskUser,
|
|
810
|
+
_ => PermissionAction::Allow,
|
|
811
|
+
};
|
|
812
|
+
Self {
|
|
813
|
+
inner: RustGovernancePipeline::new(action),
|
|
814
|
+
agent_id: "anonymous".into(),
|
|
815
|
+
session_id: "".into(),
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/// Set the agent identity used in governance audit logs.
|
|
820
|
+
#[napi]
|
|
821
|
+
pub fn set_identity(&mut self, agent_id: String, session_id: String) {
|
|
822
|
+
self.agent_id = agent_id;
|
|
823
|
+
self.session_id = session_id;
|
|
696
824
|
}
|
|
697
825
|
|
|
826
|
+
/// Add a permission rule. `pattern` supports globs: `"db.*"`, `"*.delete"`, `"*"`, or exact names.
|
|
827
|
+
/// `action`: `"allow"` | `"deny"` | `"ask_user"`.
|
|
828
|
+
/// Rules are evaluated in insertion order; first match wins.
|
|
829
|
+
#[napi]
|
|
830
|
+
pub fn add_permission_rule(&mut self, pattern: String, action: String) {
|
|
831
|
+
let perm_action = match action.as_str() {
|
|
832
|
+
"deny" => PermissionAction::Deny,
|
|
833
|
+
"ask_user" => PermissionAction::AskUser,
|
|
834
|
+
_ => PermissionAction::Allow,
|
|
835
|
+
};
|
|
836
|
+
self.inner.permission.add_rule(PermissionRule {
|
|
837
|
+
tool_pattern: pattern.into(),
|
|
838
|
+
action: perm_action,
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/// Hard-block a tool name (veto stage — cannot be overridden by permission rules).
|
|
698
843
|
#[napi]
|
|
699
844
|
pub fn block_tool(&mut self, name: String) {
|
|
700
845
|
self.inner.veto.block_tool(name);
|
|
701
846
|
}
|
|
702
847
|
|
|
848
|
+
/// Advance the internal clock used by rate limiting and audit.
|
|
703
849
|
#[napi]
|
|
704
850
|
pub fn set_time(&mut self, now_ms: BigInt) {
|
|
705
851
|
self.inner.set_time(now_ms.get_u64().1);
|
|
706
852
|
}
|
|
853
|
+
|
|
854
|
+
/// Evaluate a tool call through the full pipeline (Permission → Veto → RateLimit → Constraint → Audit).
|
|
855
|
+
/// `argsJson`: JSON-encoded tool arguments string.
|
|
856
|
+
#[napi]
|
|
857
|
+
pub fn evaluate(&mut self, tool_name: String, args_json: String) -> Result<GovernanceVerdictObj> {
|
|
858
|
+
let args: serde_json::Value = serde_json::from_str(&args_json)
|
|
859
|
+
.unwrap_or(serde_json::Value::Null);
|
|
860
|
+
let call = RustToolCall {
|
|
861
|
+
id: compact_str::CompactString::new(""),
|
|
862
|
+
name: compact_str::CompactString::new(&tool_name),
|
|
863
|
+
arguments: args,
|
|
864
|
+
};
|
|
865
|
+
let caller = AgentIdentity::new(self.agent_id.as_str(), self.session_id.as_str());
|
|
866
|
+
Ok(verdict_to_js(self.inner.evaluate(&call, &caller)))
|
|
867
|
+
}
|
|
707
868
|
}
|
|
708
869
|
|
|
709
870
|
// ──────────────────────────────── Dream / idle-pipeline POD types ────────────────────────────────
|
|
@@ -856,6 +1017,23 @@ fn idle_pipeline_action_from_rust(a: RustIdleAction) -> IdlePipelineAction {
|
|
|
856
1017
|
|
|
857
1018
|
// ─────────────────────────────────────────── EvalPipeline ────────────────────────────────────────
|
|
858
1019
|
|
|
1020
|
+
#[napi(object)]
|
|
1021
|
+
#[derive(Clone)]
|
|
1022
|
+
pub struct Criterion {
|
|
1023
|
+
pub text: String,
|
|
1024
|
+
pub required: bool,
|
|
1025
|
+
pub weight: Option<f64>,
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
#[napi(object)]
|
|
1029
|
+
#[derive(Clone)]
|
|
1030
|
+
pub struct CriterionResult {
|
|
1031
|
+
pub criterion: String,
|
|
1032
|
+
pub passed: bool,
|
|
1033
|
+
pub score: f64,
|
|
1034
|
+
pub feedback: String,
|
|
1035
|
+
}
|
|
1036
|
+
|
|
859
1037
|
#[napi(object)]
|
|
860
1038
|
#[derive(Clone)]
|
|
861
1039
|
pub struct EvalPipelineOptions {
|
|
@@ -873,14 +1051,16 @@ pub struct SkillCandidate {
|
|
|
873
1051
|
|
|
874
1052
|
/// Discriminated union returned by `EvalPipeline` methods. Inspect `kind`:
|
|
875
1053
|
/// - `"evaluate"` → `messages` (SDK must call evaluator LLM, then `feedEvalResult`)
|
|
876
|
-
/// - `"done"` → `
|
|
1054
|
+
/// - `"done"` → `passed`, `overallScore`, `feedback`, `details`, optional `skillCandidate`
|
|
877
1055
|
#[napi(object)]
|
|
878
1056
|
#[derive(Clone)]
|
|
879
1057
|
pub struct EvalPipelineAction {
|
|
880
1058
|
pub kind: String,
|
|
881
1059
|
pub messages: Option<Vec<Message>>,
|
|
882
1060
|
pub passed: Option<bool>,
|
|
1061
|
+
pub overall_score: Option<f64>,
|
|
883
1062
|
pub feedback: Option<String>,
|
|
1063
|
+
pub details: Option<Vec<CriterionResult>>,
|
|
884
1064
|
pub skill_candidate: Option<SkillCandidate>,
|
|
885
1065
|
}
|
|
886
1066
|
|
|
@@ -915,16 +1095,23 @@ impl EvalPipeline {
|
|
|
915
1095
|
pub fn feed_outcome(
|
|
916
1096
|
&mut self,
|
|
917
1097
|
goal: String,
|
|
918
|
-
criteria: Vec<
|
|
1098
|
+
criteria: Vec<Criterion>,
|
|
919
1099
|
result: String,
|
|
920
1100
|
attempt: u32,
|
|
921
1101
|
) -> EvalPipelineAction {
|
|
922
|
-
|
|
1102
|
+
let rust_criteria = criteria.into_iter().map(|c| RustCriterion {
|
|
1103
|
+
text: c.text,
|
|
1104
|
+
required: c.required,
|
|
1105
|
+
weight: c.weight.map(|w| w as f32).unwrap_or(1.0),
|
|
1106
|
+
}).collect();
|
|
1107
|
+
match self.inner.feed(RustEvalEvent::Outcome { goal, criteria: rust_criteria, result, attempt }) {
|
|
923
1108
|
RustEvalAction::Evaluate { messages } => EvalPipelineAction {
|
|
924
1109
|
kind: "evaluate".into(),
|
|
925
1110
|
messages: Some(messages.iter().map(message_from_rust).collect()),
|
|
926
1111
|
passed: None,
|
|
1112
|
+
overall_score: None,
|
|
927
1113
|
feedback: None,
|
|
1114
|
+
details: None,
|
|
928
1115
|
skill_candidate: None,
|
|
929
1116
|
},
|
|
930
1117
|
RustEvalAction::Done { result } => eval_done_action(result),
|
|
@@ -940,7 +1127,9 @@ impl EvalPipeline {
|
|
|
940
1127
|
kind: "evaluate".into(),
|
|
941
1128
|
messages: Some(messages.iter().map(message_from_rust).collect()),
|
|
942
1129
|
passed: None,
|
|
1130
|
+
overall_score: None,
|
|
943
1131
|
feedback: None,
|
|
1132
|
+
details: None,
|
|
944
1133
|
skill_candidate: None,
|
|
945
1134
|
},
|
|
946
1135
|
}
|
|
@@ -962,7 +1151,14 @@ fn eval_done_action(result: deepstrike_core::harness::eval_pipeline::EvalResult)
|
|
|
962
1151
|
kind: "done".into(),
|
|
963
1152
|
messages: None,
|
|
964
1153
|
passed: Some(result.passed),
|
|
1154
|
+
overall_score: Some(result.overall_score as f64),
|
|
965
1155
|
feedback: Some(result.feedback),
|
|
1156
|
+
details: Some(result.details.into_iter().map(|d| CriterionResult {
|
|
1157
|
+
criterion: d.criterion,
|
|
1158
|
+
passed: d.passed,
|
|
1159
|
+
score: d.score as f64,
|
|
1160
|
+
feedback: d.feedback,
|
|
1161
|
+
}).collect()),
|
|
966
1162
|
skill_candidate: result.skill_candidate.map(|s| SkillCandidate {
|
|
967
1163
|
name: s.name,
|
|
968
1164
|
description: s.description,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|