@deepstrike/wasm 0.2.73 → 0.2.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +117 -36
- package/dist/agent.js +204 -33
- package/dist/governance.d.ts +33 -9
- package/dist/governance.js +25 -28
- package/dist/index.d.ts +5 -4
- package/dist/index.js +2 -1
- package/dist/memory/authority.d.ts +30 -0
- package/dist/memory/authority.js +34 -0
- package/dist/memory/durable.d.ts +1 -1
- package/dist/memory/durable.js +2 -2
- package/dist/providers/anthropic.js +3 -2
- package/dist/providers/openai.js +2 -1
- package/dist/runtime/canonical-kernel-step.d.ts +32 -0
- package/dist/runtime/canonical-kernel-step.js +391 -141
- package/dist/runtime/execution-plane.d.ts +2 -0
- package/dist/runtime/execution-plane.js +10 -3
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/kernel-step.js +14 -3
- package/dist/runtime/mcp-transport.d.ts +43 -0
- package/dist/runtime/mcp-transport.js +58 -0
- package/dist/runtime/replay-provider.js +4 -3
- package/dist/runtime/runner.d.ts +55 -3
- package/dist/runtime/runner.js +405 -228
- package/dist/runtime/tool-arguments.d.ts +24 -0
- package/dist/runtime/tool-arguments.js +61 -0
- package/dist/runtime/types/agent.d.ts +4 -0
- package/dist/runtime/types/agent.js +6 -55
- package/dist/types.d.ts +2 -1
- package/package.json +4 -4
- package/dist/agent-ir.d.ts +0 -81
- package/dist/agent-ir.js +0 -115
package/dist/agent.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type { AgentCapabilityFilter } from "./runtime/types/agent.js";
|
|
2
|
-
import type { Memory, WorkingMemory } from "./memory/index.js";
|
|
1
|
+
import type { AgentCapabilityFilter, WorkflowOutcome, WorkflowSpec } from "./runtime/types/agent.js";
|
|
2
|
+
import type { Memory, WorkingMemory, MemoryRecord, MemoryRecall, MemoryKind } from "./memory/index.js";
|
|
3
3
|
import type { RegisteredTool } from "./tools/index.js";
|
|
4
|
-
import type { LLMProvider, StreamEvent } from "./types.js";
|
|
5
|
-
import {
|
|
4
|
+
import type { LLMProvider, StreamEvent, ContentPart } from "./types.js";
|
|
5
|
+
import { RuntimeRunner } from "./runtime/runner.js";
|
|
6
|
+
import { type ExecutionPlane } from "./runtime/execution-plane.js";
|
|
7
|
+
import { type SessionEvent, type SessionLog } from "./runtime/session-log.js";
|
|
8
|
+
import type { SignalSource } from "./signals/index.js";
|
|
9
|
+
import type { McpExecutionPlane } from "./runtime/mcp-transport.js";
|
|
6
10
|
type JsonSchema = Record<string, unknown>;
|
|
7
11
|
export interface MemoryReference {
|
|
8
12
|
kind?: "durable";
|
|
@@ -31,10 +35,7 @@ export type McpTransport = {
|
|
|
31
35
|
command: string;
|
|
32
36
|
args?: string[];
|
|
33
37
|
} | {
|
|
34
|
-
kind: "http";
|
|
35
|
-
url: string;
|
|
36
|
-
} | {
|
|
37
|
-
kind: "sse";
|
|
38
|
+
kind: "http" | "sse";
|
|
38
39
|
url: string;
|
|
39
40
|
} | {
|
|
40
41
|
kind: "custom";
|
|
@@ -63,22 +64,7 @@ export interface Skill {
|
|
|
63
64
|
providerOptions?: Record<string, unknown>;
|
|
64
65
|
}
|
|
65
66
|
export type KnowledgeSourceRef = {
|
|
66
|
-
kind: "file";
|
|
67
|
-
path: string;
|
|
68
|
-
} | {
|
|
69
|
-
kind: "directory";
|
|
70
|
-
path: string;
|
|
71
|
-
} | {
|
|
72
|
-
kind: "text";
|
|
73
|
-
content: string;
|
|
74
|
-
} | {
|
|
75
|
-
kind: "url";
|
|
76
|
-
url: string;
|
|
77
|
-
} | {
|
|
78
|
-
kind: "vector";
|
|
79
|
-
retriever: unknown;
|
|
80
|
-
} | {
|
|
81
|
-
kind: "custom";
|
|
67
|
+
kind: "file" | "directory" | "text" | "url" | "vector" | "custom";
|
|
82
68
|
[key: string]: unknown;
|
|
83
69
|
};
|
|
84
70
|
export interface Knowledge {
|
|
@@ -104,6 +90,16 @@ export interface Guardrail {
|
|
|
104
90
|
description?: string;
|
|
105
91
|
metadata?: Record<string, unknown>;
|
|
106
92
|
}
|
|
93
|
+
export interface AgentRuntimeBinding {
|
|
94
|
+
provider?: LLMProvider;
|
|
95
|
+
providerFor?: (model: string) => LLMProvider | undefined;
|
|
96
|
+
runtimeOptions?: Partial<import("./runtime/runner.js").RuntimeOptions>;
|
|
97
|
+
sessionLog?: SessionLog;
|
|
98
|
+
executionPlane?: ExecutionPlane;
|
|
99
|
+
mcpPlane?: McpExecutionPlane;
|
|
100
|
+
resolveAgent?: (name: string) => Agent | undefined | Promise<Agent | undefined>;
|
|
101
|
+
signalSource?: SignalSource;
|
|
102
|
+
}
|
|
107
103
|
export interface AgentOptions {
|
|
108
104
|
name: string;
|
|
109
105
|
description?: string;
|
|
@@ -120,16 +116,86 @@ export interface AgentOptions {
|
|
|
120
116
|
outputSchema?: JsonSchema;
|
|
121
117
|
metadata?: Record<string, unknown>;
|
|
122
118
|
guardrails?: Guardrail[];
|
|
123
|
-
runtimeBinding?:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
119
|
+
runtimeBinding?: AgentRuntimeBinding;
|
|
120
|
+
}
|
|
121
|
+
export interface AgentRunOptions {
|
|
122
|
+
sessionId?: string;
|
|
123
|
+
maxTurns?: number;
|
|
124
|
+
maxTotalTokens?: number;
|
|
125
|
+
timeoutMs?: number;
|
|
126
|
+
metadata?: Record<string, unknown>;
|
|
127
|
+
providerOptions?: Record<string, unknown>;
|
|
128
|
+
attachments?: ContentPart[];
|
|
129
|
+
cancelSignal?: AbortSignal;
|
|
128
130
|
}
|
|
129
131
|
export interface AgentRunResult {
|
|
130
132
|
output: string;
|
|
133
|
+
runId?: string;
|
|
131
134
|
sessionId: string;
|
|
132
135
|
status: "completed" | "partial" | "failed" | "cancelled";
|
|
136
|
+
usage?: {
|
|
137
|
+
inputTokens: number;
|
|
138
|
+
outputTokens: number;
|
|
139
|
+
totalTokens: number;
|
|
140
|
+
};
|
|
141
|
+
outputValidation?: {
|
|
142
|
+
ok: boolean;
|
|
143
|
+
errors: string[];
|
|
144
|
+
};
|
|
145
|
+
evidence?: {
|
|
146
|
+
route?: unknown;
|
|
147
|
+
measurement?: unknown;
|
|
148
|
+
contextBinding?: unknown;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export interface MemoryInput {
|
|
152
|
+
name: string;
|
|
153
|
+
content: string;
|
|
154
|
+
description?: string;
|
|
155
|
+
kind?: MemoryKind;
|
|
156
|
+
confidence?: number;
|
|
157
|
+
pinned?: boolean;
|
|
158
|
+
ttlDays?: number;
|
|
159
|
+
}
|
|
160
|
+
export interface RecallOptions {
|
|
161
|
+
topK?: number;
|
|
162
|
+
kinds?: MemoryKind[];
|
|
163
|
+
minScore?: number;
|
|
164
|
+
}
|
|
165
|
+
export interface DelegationResult {
|
|
166
|
+
output: string;
|
|
167
|
+
status: "completed" | "partial" | "failed";
|
|
168
|
+
}
|
|
169
|
+
export declare class AgentSession {
|
|
170
|
+
private readonly owner;
|
|
171
|
+
readonly id: string;
|
|
172
|
+
private activeRunner?;
|
|
173
|
+
constructor(owner: Agent, id: string);
|
|
174
|
+
history(fromSeq?: number): Promise<{
|
|
175
|
+
seq: number;
|
|
176
|
+
event: SessionEvent;
|
|
177
|
+
}[]>;
|
|
178
|
+
latestSeq(): Promise<number>;
|
|
179
|
+
workflowTrace(): Promise<{
|
|
180
|
+
seq: number;
|
|
181
|
+
event: SessionEvent;
|
|
182
|
+
}[]>;
|
|
183
|
+
workflowReplay(): Promise<{
|
|
184
|
+
events: {
|
|
185
|
+
seq: number;
|
|
186
|
+
event: SessionEvent;
|
|
187
|
+
}[];
|
|
188
|
+
nodeOutcomes: Record<string, unknown>[];
|
|
189
|
+
completed: boolean;
|
|
190
|
+
}>;
|
|
191
|
+
private runner;
|
|
192
|
+
stream(goal: string, options?: Omit<AgentRunOptions, "sessionId">): AsyncIterable<StreamEvent>;
|
|
193
|
+
run(goal: string, options?: Omit<AgentRunOptions, "sessionId">): Promise<AgentRunResult>;
|
|
194
|
+
resume(options?: Omit<AgentRunOptions, "sessionId">): AsyncIterable<StreamEvent>;
|
|
195
|
+
interrupt(reason?: "user" | "deadline" | "lease_lost" | "host_shutdown"): void;
|
|
196
|
+
remember(input: MemoryInput): Promise<MemoryRecord>;
|
|
197
|
+
recall(query: string, options?: RecallOptions): Promise<MemoryRecall[]>;
|
|
198
|
+
workflow(spec: WorkflowSpec): Promise<WorkflowOutcome>;
|
|
133
199
|
}
|
|
134
200
|
export declare class Agent {
|
|
135
201
|
readonly name: string;
|
|
@@ -147,14 +213,29 @@ export declare class Agent {
|
|
|
147
213
|
readonly outputSchema?: JsonSchema;
|
|
148
214
|
readonly metadata?: Record<string, unknown>;
|
|
149
215
|
readonly guardrails?: Guardrail[];
|
|
150
|
-
readonly runtimeBinding?:
|
|
216
|
+
readonly runtimeBinding?: AgentRuntimeBinding;
|
|
217
|
+
readonly sessionLog: SessionLog;
|
|
218
|
+
private readonly sessions;
|
|
151
219
|
constructor(options: AgentOptions);
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
220
|
+
session(id?: string): AgentSession;
|
|
221
|
+
createRunner(_goal: string, _sessionId: string, options?: AgentRunOptions): Promise<RuntimeRunner>;
|
|
222
|
+
run(goal: string, options?: AgentRunOptions): Promise<AgentRunResult>;
|
|
223
|
+
stream(goal: string, options?: AgentRunOptions): AsyncIterable<StreamEvent>;
|
|
224
|
+
resume(sessionId: string, options?: Omit<AgentRunOptions, "sessionId">): AsyncIterable<StreamEvent>;
|
|
225
|
+
interrupt(reason?: "user" | "deadline" | "lease_lost" | "host_shutdown", sessionId?: string): void;
|
|
226
|
+
workflow(spec: WorkflowSpec, options?: {
|
|
157
227
|
sessionId?: string;
|
|
158
|
-
}):
|
|
228
|
+
}): Promise<WorkflowOutcome>;
|
|
229
|
+
remember(input: MemoryInput, sessionId?: string): Promise<MemoryRecord>;
|
|
230
|
+
recall(query: string, options?: RecallOptions, _sessionId?: string): Promise<MemoryRecall[]>;
|
|
231
|
+
delegate(request: {
|
|
232
|
+
target: AgentRef;
|
|
233
|
+
goal: string;
|
|
234
|
+
metadata?: Record<string, unknown>;
|
|
235
|
+
providerOptions?: Record<string, unknown>;
|
|
236
|
+
}): Promise<DelegationResult>;
|
|
237
|
+
listen(): Promise<AgentRunResult | null>;
|
|
238
|
+
close(): Promise<void>;
|
|
239
|
+
result(sessionId: string, events: StreamEvent[]): Promise<AgentRunResult>;
|
|
159
240
|
}
|
|
160
241
|
export {};
|
package/dist/agent.js
CHANGED
|
@@ -1,6 +1,99 @@
|
|
|
1
1
|
import { RuntimeRunner } from "./runtime/runner.js";
|
|
2
2
|
import { LocalExecutionPlane } from "./runtime/execution-plane.js";
|
|
3
3
|
import { InMemorySessionLog } from "./runtime/session-log.js";
|
|
4
|
+
import { extractJsonValue, validateAgainstSchema } from "./runtime/output-schema.js";
|
|
5
|
+
import { checkMemoryWrite } from "./memory/authority.js";
|
|
6
|
+
function statusOf(reason) {
|
|
7
|
+
if (["completed", "success", "done"].includes(reason))
|
|
8
|
+
return "completed";
|
|
9
|
+
if (["cancelled", "user", "user_abort", "deadline", "timeout"].includes(reason))
|
|
10
|
+
return "cancelled";
|
|
11
|
+
if (["failed", "error", "invalid_arg"].includes(reason))
|
|
12
|
+
return "failed";
|
|
13
|
+
return "partial";
|
|
14
|
+
}
|
|
15
|
+
export class AgentSession {
|
|
16
|
+
owner;
|
|
17
|
+
id;
|
|
18
|
+
activeRunner;
|
|
19
|
+
constructor(owner, id) {
|
|
20
|
+
this.owner = owner;
|
|
21
|
+
this.id = id;
|
|
22
|
+
}
|
|
23
|
+
history(fromSeq = 0) { return this.owner.sessionLog.read(this.id, fromSeq); }
|
|
24
|
+
latestSeq() { return this.owner.sessionLog.latestSeq(this.id); }
|
|
25
|
+
async workflowTrace() {
|
|
26
|
+
const kinds = new Set(["workflow_batch_spawned", "workflow_node_completed", "workflow_nodes_submitted", "workflow_completed"]);
|
|
27
|
+
return (await this.history()).filter(entry => kinds.has(entry.event.kind));
|
|
28
|
+
}
|
|
29
|
+
async workflowReplay() {
|
|
30
|
+
const events = await this.workflowTrace();
|
|
31
|
+
const outcomes = new Map();
|
|
32
|
+
let completed = false;
|
|
33
|
+
for (const entry of events) {
|
|
34
|
+
if (entry.event.kind === "workflow_node_completed") {
|
|
35
|
+
const id = entry.event.agent_id;
|
|
36
|
+
if (id)
|
|
37
|
+
outcomes.set(id, entry.event);
|
|
38
|
+
}
|
|
39
|
+
if (entry.event.kind === "workflow_completed") {
|
|
40
|
+
completed = true;
|
|
41
|
+
for (const outcome of entry.event.node_outcomes) {
|
|
42
|
+
const id = outcome.node_id;
|
|
43
|
+
if (id)
|
|
44
|
+
outcomes.set(id, outcome);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return { events, nodeOutcomes: [...outcomes.values()], completed };
|
|
49
|
+
}
|
|
50
|
+
runner(goal, options = {}) { return this.owner.createRunner(goal, this.id, options); }
|
|
51
|
+
async *stream(goal, options = {}) {
|
|
52
|
+
const runner = await this.runner(goal, { ...options, sessionId: this.id });
|
|
53
|
+
this.activeRunner = runner;
|
|
54
|
+
const abort = () => runner.interrupt("user");
|
|
55
|
+
if (options.cancelSignal?.aborted)
|
|
56
|
+
abort();
|
|
57
|
+
else
|
|
58
|
+
options.cancelSignal?.addEventListener("abort", abort, { once: true });
|
|
59
|
+
try {
|
|
60
|
+
yield* runner.run({ sessionId: this.id, goal, attachments: options.attachments, extensions: options.providerOptions });
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
options.cancelSignal?.removeEventListener("abort", abort);
|
|
64
|
+
this.activeRunner = undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async run(goal, options = {}) {
|
|
68
|
+
const events = [];
|
|
69
|
+
for await (const event of this.stream(goal, options))
|
|
70
|
+
events.push(event);
|
|
71
|
+
return this.owner.result(this.id, events);
|
|
72
|
+
}
|
|
73
|
+
async *resume(options = {}) {
|
|
74
|
+
const runner = await this.runner("resume", { ...options, sessionId: this.id });
|
|
75
|
+
this.activeRunner = runner;
|
|
76
|
+
try {
|
|
77
|
+
yield* runner.wake(this.id, options.providerOptions);
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
this.activeRunner = undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
interrupt(reason = "user") { this.activeRunner?.interrupt(reason); }
|
|
84
|
+
remember(input) { return this.owner.remember(input, this.id); }
|
|
85
|
+
recall(query, options = {}) { return this.owner.recall(query, options, this.id); }
|
|
86
|
+
async workflow(spec) {
|
|
87
|
+
const runner = await this.runner("workflow", { sessionId: this.id });
|
|
88
|
+
this.activeRunner = runner;
|
|
89
|
+
try {
|
|
90
|
+
return await runner.runWorkflow(spec, { sessionId: this.id });
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
this.activeRunner = undefined;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
4
97
|
export class Agent {
|
|
5
98
|
name;
|
|
6
99
|
description;
|
|
@@ -18,6 +111,8 @@ export class Agent {
|
|
|
18
111
|
metadata;
|
|
19
112
|
guardrails;
|
|
20
113
|
runtimeBinding;
|
|
114
|
+
sessionLog;
|
|
115
|
+
sessions = new Map();
|
|
21
116
|
constructor(options) {
|
|
22
117
|
this.name = options.name;
|
|
23
118
|
this.description = options.description;
|
|
@@ -35,44 +130,120 @@ export class Agent {
|
|
|
35
130
|
this.metadata = options.metadata;
|
|
36
131
|
this.guardrails = options.guardrails;
|
|
37
132
|
this.runtimeBinding = options.runtimeBinding;
|
|
133
|
+
this.sessionLog = options.runtimeBinding?.sessionLog ?? options.runtimeBinding?.runtimeOptions?.sessionLog ?? new InMemorySessionLog();
|
|
38
134
|
}
|
|
39
|
-
|
|
135
|
+
session(id = `session-${crypto.randomUUID()}`) { if (!this.sessions.has(id))
|
|
136
|
+
this.sessions.set(id, new AgentSession(this, id)); return this.sessions.get(id); }
|
|
137
|
+
async createRunner(_goal, _sessionId, options = {}) {
|
|
40
138
|
const binding = this.runtimeBinding;
|
|
41
139
|
const provider = binding?.provider ?? (typeof this.model === "string" ? binding?.providerFor?.(this.model) : undefined);
|
|
42
140
|
if (!provider)
|
|
43
141
|
throw new Error(`agent "${this.name}" has no runtime provider binding`);
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
...(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
events.push(event);
|
|
58
|
-
const output = events.filter(event => event.type === "text_delta").map(event => ("delta" in event ? String(event.delta) : "")).join("");
|
|
59
|
-
const failed = events.some(event => event.type === "error");
|
|
60
|
-
return { output, sessionId, status: failed ? "failed" : "completed" };
|
|
142
|
+
const base = { ...(binding?.runtimeOptions ?? {}) };
|
|
143
|
+
if (options.maxTurns !== undefined)
|
|
144
|
+
base.maxTurns = options.maxTurns;
|
|
145
|
+
if (options.maxTotalTokens !== undefined)
|
|
146
|
+
base.maxTotalTokens = options.maxTotalTokens;
|
|
147
|
+
if (options.timeoutMs !== undefined)
|
|
148
|
+
base.timeoutMs = options.timeoutMs;
|
|
149
|
+
if (options.providerOptions)
|
|
150
|
+
base.extensions = { ...(base.extensions ?? {}), ...options.providerOptions };
|
|
151
|
+
const mcpPlane = binding?.mcpPlane;
|
|
152
|
+
if (mcpPlane)
|
|
153
|
+
await mcpPlane.connect();
|
|
154
|
+
return new RuntimeRunner({ provider, executionPlane: binding?.executionPlane ?? mcpPlane ?? new LocalExecutionPlane(), sessionLog: this.sessionLog, maxTokens: 32_000, agentId: this.name, ...(this.instructions ? { systemPrompt: this.instructions } : {}), ...base });
|
|
61
155
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
156
|
+
async run(goal, options = {}) { return this.session(options.sessionId).run(goal, options); }
|
|
157
|
+
stream(goal, options = {}) { return this.session(options.sessionId).stream(goal, options); }
|
|
158
|
+
resume(sessionId, options = {}) { return this.session(sessionId).resume(options); }
|
|
159
|
+
interrupt(reason = "user", sessionId) { sessionId ? this.session(sessionId).interrupt(reason) : [...this.sessions.values()].forEach(s => s.interrupt(reason)); }
|
|
160
|
+
workflow(spec, options = {}) { return this.session(options.sessionId).workflow(spec); }
|
|
161
|
+
async remember(input, sessionId) {
|
|
162
|
+
if (!this.memory || typeof this.memory.put !== "function")
|
|
163
|
+
throw new Error(`agent "${this.name}" memory is not runtime-bound`);
|
|
164
|
+
const now = Date.now();
|
|
165
|
+
const record = {
|
|
166
|
+
record_id: crypto.randomUUID(), scope: this.memory.scope
|
|
167
|
+
?? { tenant_id: "default", namespace: this.memory.namespace ?? this.name },
|
|
168
|
+
name: input.name, kind: input.kind ?? "reference", content: input.content,
|
|
169
|
+
description: input.description ?? input.name,
|
|
170
|
+
provenance: { author: "host", trust: "user_asserted", evidence_refs: [], session_id: sessionId ?? `memory-${crypto.randomUUID()}` },
|
|
171
|
+
created_at: now, updated_at: now, recall_count: 0, confidence: input.confidence ?? 1,
|
|
172
|
+
links: [], pinned: input.pinned ?? false, ...(input.ttlDays === undefined ? {} : { ttl_days: input.ttlDays }),
|
|
173
|
+
};
|
|
174
|
+
// §22.13 · the kernel's write rule, not a copy of it, decides whether this record may be stored.
|
|
175
|
+
const refusal = await checkMemoryWrite(undefined, record.name, record.content);
|
|
176
|
+
if (refusal)
|
|
177
|
+
throw new Error(`agent "${this.name}" memory write denied: ${refusal}`);
|
|
178
|
+
await this.memory.put(record);
|
|
179
|
+
return record;
|
|
180
|
+
}
|
|
181
|
+
async recall(query, options = {}, _sessionId) {
|
|
182
|
+
if (!this.memory || typeof this.memory.search !== "function")
|
|
183
|
+
throw new Error(`agent "${this.name}" memory is not runtime-bound`);
|
|
184
|
+
const records = await this.memory.search(query, { topK: options.topK ?? 8, kinds: options.kinds, minScore: options.minScore });
|
|
185
|
+
return records.map(record => ({ record, score: 1, why: "memory facade search" }));
|
|
186
|
+
}
|
|
187
|
+
async delegate(request) {
|
|
188
|
+
const targetName = typeof request.target === "string" ? request.target : request.target.name;
|
|
189
|
+
const declared = (this.handoffs ?? []).some(h => (typeof h.agent === "string" ? h.agent : h.agent.name) === targetName);
|
|
190
|
+
if (!declared)
|
|
191
|
+
throw new Error(`agent "${this.name}" cannot hand off to "${targetName}"`);
|
|
192
|
+
const resolver = this.runtimeBinding?.resolveAgent;
|
|
193
|
+
if (!resolver)
|
|
194
|
+
throw new Error(`agent "${this.name}" requires a host target resolver`);
|
|
195
|
+
const target = await resolver(targetName);
|
|
196
|
+
if (!target)
|
|
197
|
+
throw new Error(`target agent "${targetName}" is not registered`);
|
|
198
|
+
const result = await target.run(request.goal, { metadata: request.metadata, providerOptions: request.providerOptions });
|
|
199
|
+
return { output: result.output, status: result.status === "cancelled" ? "partial" : result.status };
|
|
200
|
+
}
|
|
201
|
+
async listen() {
|
|
202
|
+
const source = this.runtimeBinding?.signalSource;
|
|
203
|
+
if (!source)
|
|
204
|
+
throw new Error("agent signals require runtimeBinding.signalSource");
|
|
205
|
+
const claim = await source.claimSignal();
|
|
206
|
+
if (!claim)
|
|
207
|
+
return null;
|
|
208
|
+
const goal = String(claim.signal.payload.goal ?? claim.signal.payload.summary ?? JSON.stringify(claim.signal.payload));
|
|
209
|
+
try {
|
|
210
|
+
const result = await this.run(goal);
|
|
211
|
+
await source.ackSignal(claim);
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
await source.nackSignal(claim);
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async close() { await this.runtimeBinding?.mcpPlane?.disconnect(); }
|
|
220
|
+
async result(sessionId, events) {
|
|
221
|
+
const entries = await this.sessionLog.read(sessionId);
|
|
222
|
+
const started = [...entries].reverse().find(e => e.event.kind === "run_started")?.event;
|
|
223
|
+
const terminal = [...entries].reverse().find(e => e.event.kind === "run_terminal")?.event;
|
|
224
|
+
const output = events.filter((e) => e.type === "text_delta" && "delta" in e).map(e => String(e.delta)).join("");
|
|
225
|
+
const usage = [...events].reverse().find((e) => e.type === "usage");
|
|
226
|
+
const result = { output, runId: started?.kind === "run_started" ? started.run_id : undefined, sessionId, status: statusOf(terminal?.kind === "run_terminal" ? terminal.reason : events.some(e => e.type === "error") ? "error" : "completed") };
|
|
227
|
+
const attempt = [...entries].reverse().find(e => e.event.kind === "provider_attempt")?.event;
|
|
228
|
+
if (usage)
|
|
229
|
+
result.usage = { inputTokens: usage.inputTokens ?? 0, outputTokens: usage.outputTokens ?? 0, totalTokens: usage.totalTokens };
|
|
230
|
+
else if (attempt?.kind === "provider_attempt" && attempt.usage) {
|
|
231
|
+
result.usage = { inputTokens: attempt.usage.inputTokens, outputTokens: attempt.usage.outputTokens, totalTokens: attempt.usage.inputTokens + attempt.usage.outputTokens };
|
|
232
|
+
}
|
|
233
|
+
const measured = [...entries].reverse().find(e => e.event.kind === "prompt_measured")?.event;
|
|
234
|
+
const prepared = [...entries].reverse().find(e => e.event.kind === "context_prepared")?.event;
|
|
235
|
+
if ((started?.kind === "run_started" && started.route) || (attempt?.kind === "provider_attempt" && attempt.route) || measured || prepared) {
|
|
236
|
+
result.evidence = {
|
|
237
|
+
...((attempt?.kind === "provider_attempt" ? attempt.route : started?.kind === "run_started" ? started.route : undefined) ? { route: attempt?.kind === "provider_attempt" ? attempt.route : started.route } : {}),
|
|
238
|
+
...(measured?.kind === "prompt_measured" ? { measurement: measured.measurement } : {}),
|
|
239
|
+
...(prepared?.kind === "context_prepared" ? { contextBinding: prepared.preparation.binding } : {}),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (this.outputSchema) {
|
|
243
|
+
result.outputValidation = validateAgainstSchema(extractJsonValue(output), this.outputSchema);
|
|
244
|
+
if (!result.outputValidation.ok && result.status === "completed")
|
|
245
|
+
result.status = "failed";
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
77
248
|
}
|
|
78
249
|
}
|
package/dist/governance.d.ts
CHANGED
|
@@ -12,16 +12,11 @@ export interface GovernancePolicy {
|
|
|
12
12
|
windowMs: number;
|
|
13
13
|
}[];
|
|
14
14
|
constraints?: GovernanceConstraint[];
|
|
15
|
-
/** I5: when true (default), the
|
|
15
|
+
/** I5: when true (default), the kernel withholds statically denied tools (vetoes and `deny`
|
|
16
|
+
* rules, evaluated exactly as the call gate evaluates them) from the provider surface and names
|
|
17
|
+
* them once in the knowledge slot. Mirrors Node. */
|
|
16
18
|
surfaceDeniedInSystem?: boolean;
|
|
17
19
|
}
|
|
18
|
-
/** I5: bucket tools into allowed/denied per the policy. Pure. Mirrors Node. */
|
|
19
|
-
export declare function governanceFilterSchema<T extends {
|
|
20
|
-
name: string;
|
|
21
|
-
}>(tools: T[], policy: GovernancePolicy | undefined): {
|
|
22
|
-
allowed: T[];
|
|
23
|
-
denied: string[];
|
|
24
|
-
};
|
|
25
20
|
export type GovernanceConstraint = {
|
|
26
21
|
kind: "required";
|
|
27
22
|
tool: string;
|
|
@@ -38,5 +33,34 @@ export type GovernanceConstraint = {
|
|
|
38
33
|
min?: number;
|
|
39
34
|
max?: number;
|
|
40
35
|
};
|
|
41
|
-
export declare function governancePolicyToKernelEvent(policy: GovernancePolicy): Record<string, unknown
|
|
36
|
+
export declare function governancePolicyToKernelEvent(policy: GovernancePolicy): Record<string, unknown> & {
|
|
37
|
+
rate_limits: Array<{
|
|
38
|
+
tool: string;
|
|
39
|
+
max_calls: number;
|
|
40
|
+
window_ms: number;
|
|
41
|
+
}>;
|
|
42
|
+
};
|
|
43
|
+
/** A §13.2 live-policy patch replacing the governance posture, for `RuntimeRunner.applyPolicyPatch`. */
|
|
44
|
+
export declare function governancePolicyPatch(policy: GovernancePolicy): {
|
|
45
|
+
kind: "replace_governance_policy";
|
|
46
|
+
policy: Record<string, unknown>;
|
|
47
|
+
};
|
|
48
|
+
/** A §13.2 live policy patch in kernel vocabulary — the closed set of policies that may change
|
|
49
|
+
* while an operation runs. Use `governancePolicyPatch` to build the governance variant. */
|
|
50
|
+
export type LivePolicyPatch = {
|
|
51
|
+
kind: "replace_signal_policy";
|
|
52
|
+
policy: Record<string, unknown>;
|
|
53
|
+
} | {
|
|
54
|
+
kind: "replace_governance_policy";
|
|
55
|
+
policy: Record<string, unknown>;
|
|
56
|
+
} | {
|
|
57
|
+
kind: "replace_recovery_policy";
|
|
58
|
+
policy: Record<string, unknown>;
|
|
59
|
+
} | {
|
|
60
|
+
kind: "tighten_resource_quota";
|
|
61
|
+
max_concurrent_subagents?: number;
|
|
62
|
+
max_total_subagents?: number;
|
|
63
|
+
max_spawn_depth?: number;
|
|
64
|
+
max_workflow_nodes?: number;
|
|
65
|
+
};
|
|
42
66
|
export {};
|
package/dist/governance.js
CHANGED
|
@@ -1,29 +1,4 @@
|
|
|
1
1
|
// ─── Declarative policy (in-kernel gate) ──────────────────────────────────────
|
|
2
|
-
/** I5: bucket tools into allowed/denied per the policy. Pure. Mirrors Node. */
|
|
3
|
-
export function governanceFilterSchema(tools, policy) {
|
|
4
|
-
if (!policy)
|
|
5
|
-
return { allowed: tools, denied: [] };
|
|
6
|
-
const vetoes = new Set(policy.vetoes ?? []);
|
|
7
|
-
const allowed = [];
|
|
8
|
-
const denied = [];
|
|
9
|
-
const matches = (pat, name) => pat === name || (pat.endsWith("*") && name.startsWith(pat.slice(0, -1)));
|
|
10
|
-
for (const tool of tools) {
|
|
11
|
-
if (vetoes.has(tool.name)) {
|
|
12
|
-
denied.push(tool.name);
|
|
13
|
-
continue;
|
|
14
|
-
}
|
|
15
|
-
let action = policy.defaultAction ?? "allow";
|
|
16
|
-
for (const r of policy.rules ?? []) {
|
|
17
|
-
if (matches(r.pattern, tool.name))
|
|
18
|
-
action = r.action;
|
|
19
|
-
}
|
|
20
|
-
if (action === "deny")
|
|
21
|
-
denied.push(tool.name);
|
|
22
|
-
else
|
|
23
|
-
allowed.push(tool);
|
|
24
|
-
}
|
|
25
|
-
return { allowed, denied };
|
|
26
|
-
}
|
|
27
2
|
export function governancePolicyToKernelEvent(policy) {
|
|
28
3
|
return {
|
|
29
4
|
kind: "load_governance_policy",
|
|
@@ -36,9 +11,31 @@ export function governancePolicyToKernelEvent(policy) {
|
|
|
36
11
|
window_ms: rl.windowMs,
|
|
37
12
|
})),
|
|
38
13
|
constraints: (policy.constraints ?? []).map(c => c.kind === "enum"
|
|
39
|
-
? { kind: "enum", tool: c.tool,
|
|
14
|
+
? { kind: "enum", tool: c.tool, param_path: c.path, values: c.values }
|
|
40
15
|
: c.kind === "range"
|
|
41
|
-
? {
|
|
42
|
-
|
|
16
|
+
? {
|
|
17
|
+
kind: "range", tool: c.tool, param_path: c.path,
|
|
18
|
+
// The wire carries fixed-point micro-units so a bound replays byte-identically.
|
|
19
|
+
...(c.min !== undefined ? { min_micros: toMicros(c.min) } : {}),
|
|
20
|
+
...(c.max !== undefined ? { max_micros: toMicros(c.max) } : {}),
|
|
21
|
+
}
|
|
22
|
+
: { kind: "required", tool: c.tool, param_path: c.path }),
|
|
23
|
+
hide_denied_tools: policy.surfaceDeniedInSystem !== false,
|
|
43
24
|
};
|
|
44
25
|
}
|
|
26
|
+
/** A §13.2 live-policy patch replacing the governance posture, for `RuntimeRunner.applyPolicyPatch`. */
|
|
27
|
+
export function governancePolicyPatch(policy) {
|
|
28
|
+
const { kind: _kind, ...wire } = governancePolicyToKernelEvent(policy);
|
|
29
|
+
return {
|
|
30
|
+
kind: "replace_governance_policy",
|
|
31
|
+
policy: {
|
|
32
|
+
...wire,
|
|
33
|
+
rate_limits: wire.rate_limits.map(limit => ({ ...limit, window_ms: String(limit.window_ms) })),
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function toMicros(value) {
|
|
38
|
+
if (!Number.isFinite(value))
|
|
39
|
+
throw new RangeError(`governance range bound must be finite, got ${value}`);
|
|
40
|
+
return Math.round(value * 1_000_000);
|
|
41
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,15 +14,16 @@ export type { AgentCapabilityFilter, AgentIdentity, AgentIsolation, AgentRunSpec
|
|
|
14
14
|
export { workflowSpecToKernel, workflowNodeSpecToKernel, submitWorkflowNodesTool, startWorkflowTool, fanoutSynthesize, generateAndFilter, genEval, verifyRules } from "./runtime/types/agent.js";
|
|
15
15
|
export { loopInstruction, classifyInstruction, judgeGoal, extractClassifyBranch, extractJudgeWinner, } from "./runtime/workflow-control-flow.js";
|
|
16
16
|
export { Agent } from "./agent.js";
|
|
17
|
-
export
|
|
18
|
-
export {
|
|
19
|
-
export type {
|
|
17
|
+
export { McpExecutionPlane } from "./runtime/mcp-transport.js";
|
|
18
|
+
export type { McpConnection, McpConnectionFactory, McpCredentialVault, McpServerConfig } from "./runtime/mcp-transport.js";
|
|
19
|
+
export type { AgentMemory, AgentOptions, AgentRunResult, AgentRunOptions, AgentToolDefinition, AgentRef, Guardrail, Handoff, Knowledge, KnowledgeSourceRef, MCPServer, McpTransport, MemoryReference, ModelRef, ModelRequirement, Skill, MemoryInput, RecallOptions, DelegationResult, AgentRuntimeBinding, AgentSession, } from "./agent.js";
|
|
20
20
|
export { AnthropicProvider } from "./providers/anthropic.js";
|
|
21
21
|
export { OpenAIProvider, qwen, deepseek, minimax, kimi } from "./providers/openai.js";
|
|
22
22
|
export type { OpenAIProviderOptions, BackendProviderOptions } from "./providers/openai.js";
|
|
23
23
|
export { ProviderError, classifyProviderError } from "./providers/provider-error.js";
|
|
24
24
|
export type { ProviderErrorKind, ProviderErrorOptions } from "./providers/provider-error.js";
|
|
25
|
-
export type { GovernancePolicy, GovernanceConstraint } from "./governance.js";
|
|
25
|
+
export type { GovernancePolicy, GovernanceConstraint, LivePolicyPatch } from "./governance.js";
|
|
26
|
+
export { governancePolicyPatch } from "./governance.js";
|
|
26
27
|
export { tool, executeTools } from "./tools/index.js";
|
|
27
28
|
export type { RegisteredTool, ToolExecContext } from "./tools/index.js";
|
|
28
29
|
export { safeTool, ok, fail, ToolError, formatToolError } from "./tools/errors.js";
|
package/dist/index.js
CHANGED
|
@@ -10,10 +10,11 @@ export { SubAgentOrchestrator, defaultSubAgentOrchestrator, spawnStandalone } fr
|
|
|
10
10
|
export { workflowSpecToKernel, workflowNodeSpecToKernel, submitWorkflowNodesTool, startWorkflowTool, fanoutSynthesize, generateAndFilter, genEval, verifyRules } from "./runtime/types/agent.js";
|
|
11
11
|
export { loopInstruction, classifyInstruction, judgeGoal, extractClassifyBranch, extractJudgeWinner, } from "./runtime/workflow-control-flow.js";
|
|
12
12
|
export { Agent } from "./agent.js";
|
|
13
|
-
export {
|
|
13
|
+
export { McpExecutionPlane } from "./runtime/mcp-transport.js";
|
|
14
14
|
export { AnthropicProvider } from "./providers/anthropic.js";
|
|
15
15
|
export { OpenAIProvider, qwen, deepseek, minimax, kimi } from "./providers/openai.js";
|
|
16
16
|
export { ProviderError, classifyProviderError } from "./providers/provider-error.js";
|
|
17
|
+
export { governancePolicyPatch } from "./governance.js";
|
|
17
18
|
export { tool, executeTools } from "./tools/index.js";
|
|
18
19
|
export { safeTool, ok, fail, ToolError, formatToolError } from "./tools/errors.js";
|
|
19
20
|
export { WorkingMemory } from "./memory/index.js";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { MemoryRecall, MemoryRecallLifecycle } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* §22.13 · the kernel's memory authority for a host with no live operation.
|
|
4
|
+
*
|
|
5
|
+
* Inside a run, every memory decision is a kernel transition (`admit_memory_write`, and the
|
|
6
|
+
* `memory_recalled` / `promotion_suggested` facts a query resolution journals). With no run — an
|
|
7
|
+
* explicit `remember`, a session extract after the run ended — the host asks the same kernel
|
|
8
|
+
* functions statelessly. The SDK keeps no copy of the validation rule and never computes a recall
|
|
9
|
+
* count itself.
|
|
10
|
+
*/
|
|
11
|
+
/** The canonical wire `MemoryPolicy` (the `u64` threshold travels as a decimal string). */
|
|
12
|
+
export interface KernelMemoryPolicyWire {
|
|
13
|
+
stale_warning_days?: number;
|
|
14
|
+
retrieval_top_k?: number;
|
|
15
|
+
validation_enabled?: boolean;
|
|
16
|
+
max_content_bytes?: number;
|
|
17
|
+
max_name_length?: number;
|
|
18
|
+
promotion_recall_threshold?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface MemoryPromotion {
|
|
21
|
+
record_id: string;
|
|
22
|
+
recall_count: number;
|
|
23
|
+
}
|
|
24
|
+
/** Would the kernel admit this write? Resolves to the refusal reason, or `undefined` when admitted. */
|
|
25
|
+
export declare function checkMemoryWrite(policy: KernelMemoryPolicyWire | undefined, name: string, content: string): Promise<string | undefined>;
|
|
26
|
+
/** Derive one recall's lifecycle from the counts the store reported it held. */
|
|
27
|
+
export declare function deriveMemoryRecall(policy: KernelMemoryPolicyWire | undefined, recalledAt: number, hits: MemoryRecall[]): Promise<{
|
|
28
|
+
recalls: MemoryRecallLifecycle[];
|
|
29
|
+
promotions: MemoryPromotion[];
|
|
30
|
+
}>;
|