@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 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 { type RuntimeOptions } from "./runtime/runner.js";
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
- provider?: LLMProvider;
125
- providerFor?: (model: string) => LLMProvider | undefined;
126
- runtimeOptions?: Partial<RuntimeOptions>;
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?: AgentOptions["runtimeBinding"];
216
+ readonly runtimeBinding?: AgentRuntimeBinding;
217
+ readonly sessionLog: SessionLog;
218
+ private readonly sessions;
151
219
  constructor(options: AgentOptions);
152
- run(goal: string, options?: {
153
- sessionId?: string;
154
- maxTurns?: number;
155
- }): Promise<AgentRunResult>;
156
- stream(goal: string, options?: {
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
- }): AsyncIterable<StreamEvent>;
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
- async run(goal, options = {}) {
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 runtime = new RuntimeRunner({
45
- provider,
46
- executionPlane: new LocalExecutionPlane(),
47
- sessionLog: new InMemorySessionLog(),
48
- maxTokens: 32_000,
49
- agentId: this.name,
50
- ...(this.instructions ? { systemPrompt: this.instructions } : {}),
51
- ...(options.maxTurns !== undefined ? { maxTurns: options.maxTurns } : {}),
52
- ...(binding?.runtimeOptions ?? {}),
53
- });
54
- const sessionId = options.sessionId ?? `session-${crypto.randomUUID()}`;
55
- const events = [];
56
- for await (const event of runtime.run({ sessionId, goal }))
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
- stream(goal, options = {}) {
63
- const binding = this.runtimeBinding;
64
- const provider = binding?.provider ?? (typeof this.model === "string" ? binding?.providerFor?.(this.model) : undefined);
65
- if (!provider)
66
- throw new Error(`agent "${this.name}" has no runtime provider binding`);
67
- const runtime = new RuntimeRunner({
68
- provider,
69
- executionPlane: new LocalExecutionPlane(),
70
- sessionLog: new InMemorySessionLog(),
71
- maxTokens: 32_000,
72
- agentId: this.name,
73
- ...(this.instructions ? { systemPrompt: this.instructions } : {}),
74
- ...(binding?.runtimeOptions ?? {}),
75
- });
76
- return runtime.run({ sessionId: options.sessionId ?? `session-${crypto.randomUUID()}`, goal });
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
  }
@@ -12,16 +12,11 @@ export interface GovernancePolicy {
12
12
  windowMs: number;
13
13
  }[];
14
14
  constraints?: GovernanceConstraint[];
15
- /** I5: when true (default), the runner pre-filters denied tools out of the schema. */
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 {};
@@ -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, path: c.path, values: c.values }
14
+ ? { kind: "enum", tool: c.tool, param_path: c.path, values: c.values }
40
15
  : c.kind === "range"
41
- ? { kind: "range", tool: c.tool, path: c.path, ...(c.min !== undefined ? { min: c.min } : {}), ...(c.max !== undefined ? { max: c.max } : {}) }
42
- : { kind: "required", tool: c.tool, path: c.path }),
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 type { AgentMemory, AgentOptions, AgentRunResult, AgentToolDefinition, AgentRef, Guardrail, Handoff, Knowledge, KnowledgeSourceRef, MCPServer, McpTransport, MemoryReference, ModelRef, ModelRequirement, Skill, } from "./agent.js";
18
- export { lowerAgent, normalizeAgent } from "./agent-ir.js";
19
- export type { AgentCapabilityIR, AgentDefinition, AgentLoweringInputs, AgentMemoryIR, AgentSpec, AgentToolIR, } from "./agent-ir.js";
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 { lowerAgent, normalizeAgent } from "./agent-ir.js";
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
+ }>;