@deepstrike/wasm 0.2.73 → 0.2.74

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,98 @@
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
+ function statusOf(reason) {
6
+ if (["completed", "success", "done"].includes(reason))
7
+ return "completed";
8
+ if (["cancelled", "user", "user_abort", "deadline", "timeout"].includes(reason))
9
+ return "cancelled";
10
+ if (["failed", "error", "invalid_arg"].includes(reason))
11
+ return "failed";
12
+ return "partial";
13
+ }
14
+ export class AgentSession {
15
+ owner;
16
+ id;
17
+ activeRunner;
18
+ constructor(owner, id) {
19
+ this.owner = owner;
20
+ this.id = id;
21
+ }
22
+ history(fromSeq = 0) { return this.owner.sessionLog.read(this.id, fromSeq); }
23
+ latestSeq() { return this.owner.sessionLog.latestSeq(this.id); }
24
+ async workflowTrace() {
25
+ const kinds = new Set(["workflow_batch_spawned", "workflow_node_completed", "workflow_nodes_submitted", "workflow_completed"]);
26
+ return (await this.history()).filter(entry => kinds.has(entry.event.kind));
27
+ }
28
+ async workflowReplay() {
29
+ const events = await this.workflowTrace();
30
+ const outcomes = new Map();
31
+ let completed = false;
32
+ for (const entry of events) {
33
+ if (entry.event.kind === "workflow_node_completed") {
34
+ const id = entry.event.agent_id;
35
+ if (id)
36
+ outcomes.set(id, entry.event);
37
+ }
38
+ if (entry.event.kind === "workflow_completed") {
39
+ completed = true;
40
+ for (const outcome of entry.event.node_outcomes) {
41
+ const id = outcome.node_id;
42
+ if (id)
43
+ outcomes.set(id, outcome);
44
+ }
45
+ }
46
+ }
47
+ return { events, nodeOutcomes: [...outcomes.values()], completed };
48
+ }
49
+ runner(goal, options = {}) { return this.owner.createRunner(goal, this.id, options); }
50
+ async *stream(goal, options = {}) {
51
+ const runner = await this.runner(goal, { ...options, sessionId: this.id });
52
+ this.activeRunner = runner;
53
+ const abort = () => runner.interrupt("user");
54
+ if (options.cancelSignal?.aborted)
55
+ abort();
56
+ else
57
+ options.cancelSignal?.addEventListener("abort", abort, { once: true });
58
+ try {
59
+ yield* runner.run({ sessionId: this.id, goal, attachments: options.attachments, extensions: options.providerOptions });
60
+ }
61
+ finally {
62
+ options.cancelSignal?.removeEventListener("abort", abort);
63
+ this.activeRunner = undefined;
64
+ }
65
+ }
66
+ async run(goal, options = {}) {
67
+ const events = [];
68
+ for await (const event of this.stream(goal, options))
69
+ events.push(event);
70
+ return this.owner.result(this.id, events);
71
+ }
72
+ async *resume(options = {}) {
73
+ const runner = await this.runner("resume", { ...options, sessionId: this.id });
74
+ this.activeRunner = runner;
75
+ try {
76
+ yield* runner.wake(this.id, options.providerOptions);
77
+ }
78
+ finally {
79
+ this.activeRunner = undefined;
80
+ }
81
+ }
82
+ interrupt(reason = "user") { this.activeRunner?.interrupt(reason); }
83
+ remember(input) { return this.owner.remember(input, this.id); }
84
+ recall(query, options = {}) { return this.owner.recall(query, options, this.id); }
85
+ async workflow(spec) {
86
+ const runner = await this.runner("workflow", { sessionId: this.id });
87
+ this.activeRunner = runner;
88
+ try {
89
+ return await runner.runWorkflow(spec, { sessionId: this.id });
90
+ }
91
+ finally {
92
+ this.activeRunner = undefined;
93
+ }
94
+ }
95
+ }
4
96
  export class Agent {
5
97
  name;
6
98
  description;
@@ -18,6 +110,8 @@ export class Agent {
18
110
  metadata;
19
111
  guardrails;
20
112
  runtimeBinding;
113
+ sessionLog;
114
+ sessions = new Map();
21
115
  constructor(options) {
22
116
  this.name = options.name;
23
117
  this.description = options.description;
@@ -35,44 +129,116 @@ export class Agent {
35
129
  this.metadata = options.metadata;
36
130
  this.guardrails = options.guardrails;
37
131
  this.runtimeBinding = options.runtimeBinding;
132
+ this.sessionLog = options.runtimeBinding?.sessionLog ?? options.runtimeBinding?.runtimeOptions?.sessionLog ?? new InMemorySessionLog();
38
133
  }
39
- async run(goal, options = {}) {
134
+ session(id = `session-${crypto.randomUUID()}`) { if (!this.sessions.has(id))
135
+ this.sessions.set(id, new AgentSession(this, id)); return this.sessions.get(id); }
136
+ async createRunner(_goal, _sessionId, options = {}) {
40
137
  const binding = this.runtimeBinding;
41
138
  const provider = binding?.provider ?? (typeof this.model === "string" ? binding?.providerFor?.(this.model) : undefined);
42
139
  if (!provider)
43
140
  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" };
141
+ const base = { ...(binding?.runtimeOptions ?? {}) };
142
+ if (options.maxTurns !== undefined)
143
+ base.maxTurns = options.maxTurns;
144
+ if (options.maxTotalTokens !== undefined)
145
+ base.maxTotalTokens = options.maxTotalTokens;
146
+ if (options.timeoutMs !== undefined)
147
+ base.timeoutMs = options.timeoutMs;
148
+ if (options.providerOptions)
149
+ base.extensions = { ...(base.extensions ?? {}), ...options.providerOptions };
150
+ const mcpPlane = binding?.mcpPlane;
151
+ if (mcpPlane)
152
+ await mcpPlane.connect();
153
+ 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
154
  }
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 });
155
+ async run(goal, options = {}) { return this.session(options.sessionId).run(goal, options); }
156
+ stream(goal, options = {}) { return this.session(options.sessionId).stream(goal, options); }
157
+ resume(sessionId, options = {}) { return this.session(sessionId).resume(options); }
158
+ interrupt(reason = "user", sessionId) { sessionId ? this.session(sessionId).interrupt(reason) : [...this.sessions.values()].forEach(s => s.interrupt(reason)); }
159
+ workflow(spec, options = {}) { return this.session(options.sessionId).workflow(spec); }
160
+ async remember(input, sessionId) {
161
+ if (!this.memory || typeof this.memory.put !== "function")
162
+ throw new Error(`agent "${this.name}" memory is not runtime-bound`);
163
+ const now = Date.now();
164
+ const record = {
165
+ record_id: crypto.randomUUID(), scope: this.memory.scope
166
+ ?? { tenant_id: "default", namespace: this.memory.namespace ?? this.name },
167
+ name: input.name, kind: input.kind ?? "reference", content: input.content,
168
+ description: input.description ?? input.name,
169
+ provenance: { author: "host", trust: "user_asserted", evidence_refs: [], session_id: sessionId ?? `memory-${crypto.randomUUID()}` },
170
+ created_at: now, updated_at: now, recall_count: 0, confidence: input.confidence ?? 1,
171
+ links: [], pinned: input.pinned ?? false, ...(input.ttlDays === undefined ? {} : { ttl_days: input.ttlDays }),
172
+ };
173
+ await this.memory.put(record);
174
+ return record;
175
+ }
176
+ async recall(query, options = {}, _sessionId) {
177
+ if (!this.memory || typeof this.memory.search !== "function")
178
+ throw new Error(`agent "${this.name}" memory is not runtime-bound`);
179
+ const records = await this.memory.search(query, { topK: options.topK ?? 8, kinds: options.kinds, minScore: options.minScore });
180
+ return records.map(record => ({ record, score: 1, why: "memory facade search" }));
181
+ }
182
+ async delegate(request) {
183
+ const targetName = typeof request.target === "string" ? request.target : request.target.name;
184
+ const declared = (this.handoffs ?? []).some(h => (typeof h.agent === "string" ? h.agent : h.agent.name) === targetName);
185
+ if (!declared)
186
+ throw new Error(`agent "${this.name}" cannot hand off to "${targetName}"`);
187
+ const resolver = this.runtimeBinding?.resolveAgent;
188
+ if (!resolver)
189
+ throw new Error(`agent "${this.name}" requires a host target resolver`);
190
+ const target = await resolver(targetName);
191
+ if (!target)
192
+ throw new Error(`target agent "${targetName}" is not registered`);
193
+ const result = await target.run(request.goal, { metadata: request.metadata, providerOptions: request.providerOptions });
194
+ return { output: result.output, status: result.status === "cancelled" ? "partial" : result.status };
195
+ }
196
+ async listen() {
197
+ const source = this.runtimeBinding?.signalSource;
198
+ if (!source)
199
+ throw new Error("agent signals require runtimeBinding.signalSource");
200
+ const claim = await source.claimSignal();
201
+ if (!claim)
202
+ return null;
203
+ const goal = String(claim.signal.payload.goal ?? claim.signal.payload.summary ?? JSON.stringify(claim.signal.payload));
204
+ try {
205
+ const result = await this.run(goal);
206
+ await source.ackSignal(claim);
207
+ return result;
208
+ }
209
+ catch (error) {
210
+ await source.nackSignal(claim);
211
+ throw error;
212
+ }
213
+ }
214
+ async close() { await this.runtimeBinding?.mcpPlane?.disconnect(); }
215
+ async result(sessionId, events) {
216
+ const entries = await this.sessionLog.read(sessionId);
217
+ const started = [...entries].reverse().find(e => e.event.kind === "run_started")?.event;
218
+ const terminal = [...entries].reverse().find(e => e.event.kind === "run_terminal")?.event;
219
+ const output = events.filter((e) => e.type === "text_delta" && "delta" in e).map(e => String(e.delta)).join("");
220
+ const usage = [...events].reverse().find((e) => e.type === "usage");
221
+ 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") };
222
+ const attempt = [...entries].reverse().find(e => e.event.kind === "provider_attempt")?.event;
223
+ if (usage)
224
+ result.usage = { inputTokens: usage.inputTokens ?? 0, outputTokens: usage.outputTokens ?? 0, totalTokens: usage.totalTokens };
225
+ else if (attempt?.kind === "provider_attempt" && attempt.usage) {
226
+ result.usage = { inputTokens: attempt.usage.inputTokens, outputTokens: attempt.usage.outputTokens, totalTokens: attempt.usage.inputTokens + attempt.usage.outputTokens };
227
+ }
228
+ const measured = [...entries].reverse().find(e => e.event.kind === "prompt_measured")?.event;
229
+ const prepared = [...entries].reverse().find(e => e.event.kind === "context_prepared")?.event;
230
+ if ((started?.kind === "run_started" && started.route) || (attempt?.kind === "provider_attempt" && attempt.route) || measured || prepared) {
231
+ result.evidence = {
232
+ ...((attempt?.kind === "provider_attempt" ? attempt.route : started?.kind === "run_started" ? started.route : undefined) ? { route: attempt?.kind === "provider_attempt" ? attempt.route : started.route } : {}),
233
+ ...(measured?.kind === "prompt_measured" ? { measurement: measured.measurement } : {}),
234
+ ...(prepared?.kind === "context_prepared" ? { contextBinding: prepared.preparation.binding } : {}),
235
+ };
236
+ }
237
+ if (this.outputSchema) {
238
+ result.outputValidation = validateAgainstSchema(extractJsonValue(output), this.outputSchema);
239
+ if (!result.outputValidation.ok && result.status === "completed")
240
+ result.status = "failed";
241
+ }
242
+ return result;
77
243
  }
78
244
  }
package/dist/index.d.ts CHANGED
@@ -14,9 +14,9 @@ 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";
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ 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";
@@ -3,8 +3,8 @@ import type { Memory, MemoryRecord, MemoryScope, MemorySearchOptions, MemoryStor
3
3
  export declare class DurableMemory implements Memory {
4
4
  private readonly store;
5
5
  private readonly agentId;
6
- private readonly scope;
7
6
  readonly namespace: string;
7
+ readonly scope: MemoryScope;
8
8
  constructor(store: MemoryStore, agentId: string, scope: MemoryScope);
9
9
  search(query: string, options?: MemorySearchOptions): Promise<MemoryRecord[]>;
10
10
  get(recordId: string): Promise<MemoryRecord | null>;
@@ -2,13 +2,13 @@
2
2
  export class DurableMemory {
3
3
  store;
4
4
  agentId;
5
- scope;
6
5
  namespace;
6
+ scope;
7
7
  constructor(store, agentId, scope) {
8
8
  this.store = store;
9
9
  this.agentId = agentId;
10
- this.scope = scope;
11
10
  this.namespace = scope.namespace;
11
+ this.scope = scope;
12
12
  }
13
13
  async search(query, options = {}) {
14
14
  const request = {
@@ -14,6 +14,8 @@ export { CanonicalKernelHost, CanonicalKernelRejectedError, CanonicalKernelRebui
14
14
  export type { CanonicalKernelInput, CanonicalPlannedStep, CanonicalRunnerRuntimeOptions, CanonicalTransition, CanonicalTransitionOptions, } from "./canonical-kernel-step.js";
15
15
  export { runAgent, runFanout } from "./facade.js";
16
16
  export type { RunAgentOptions, RunFanoutOptions } from "./facade.js";
17
+ export { McpExecutionPlane } from "./mcp-transport.js";
18
+ export type { McpConnection, McpConnectionFactory, McpCredentialVault, McpServerConfig } from "./mcp-transport.js";
17
19
  export { builtinReducers, resolveReducer } from "./reducers.js";
18
20
  export type { Reducer, ReducerRegistry, ReducerInput } from "./reducers.js";
19
21
  export { getKernel } from "./kernel.js";
@@ -9,6 +9,7 @@ export { RuntimeRunner, collectText } from "./runner.js";
9
9
  export { MemoryPayloadDriver, PayloadStore } from "./payload-store.js";
10
10
  export { CanonicalKernelHost, CanonicalKernelRejectedError, CanonicalKernelRebuildRequiredError, CanonicalRunnerRuntime, sha256, } from "./canonical-kernel-step.js";
11
11
  export { runAgent, runFanout } from "./facade.js";
12
+ export { McpExecutionPlane } from "./mcp-transport.js";
12
13
  export { builtinReducers, resolveReducer } from "./reducers.js";
13
14
  export { getKernel } from "./kernel.js";
14
15
  export { ReplayProvider } from "./replay-provider.js";
@@ -0,0 +1,43 @@
1
+ import type { ToolCall, ToolSchema, StreamEvent } from "../types.js";
2
+ import { type ExecutionPlane, type RunContext } from "./execution-plane.js";
3
+ import type { RegisteredTool } from "../tools/index.js";
4
+ /** Browser-safe MCP connection boundary. Implement HTTP/SSE/custom transports in the host. */
5
+ export interface McpConnection {
6
+ start(): Promise<void>;
7
+ schemas(): ToolSchema[];
8
+ execute(call: ToolCall, context?: RunContext): Promise<{
9
+ content: string;
10
+ isError: boolean;
11
+ contentParts?: unknown[];
12
+ }>;
13
+ stop(): Promise<void>;
14
+ }
15
+ export interface McpCredentialVault {
16
+ get(key: string): Promise<string | undefined>;
17
+ }
18
+ export interface McpServerConfig {
19
+ name: string;
20
+ transport: {
21
+ kind: "http" | "sse" | "custom";
22
+ [key: string]: unknown;
23
+ };
24
+ credentialVault?: McpCredentialVault;
25
+ }
26
+ export type McpConnectionFactory = (config: McpServerConfig) => McpConnection | Promise<McpConnection>;
27
+ /** ExecutionPlane adapter that keeps MCP wire details outside the Kernel. */
28
+ export declare class McpExecutionPlane implements ExecutionPlane {
29
+ private readonly configs;
30
+ private readonly factory;
31
+ private readonly connections;
32
+ private readonly toolMap;
33
+ private connected;
34
+ private readonly local;
35
+ private readonly localNames;
36
+ constructor(configs: McpServerConfig[], factory: McpConnectionFactory);
37
+ connect(): Promise<void>;
38
+ register(...tools: RegisteredTool[]): this;
39
+ unregister(name: string): this;
40
+ schemas(): ToolSchema[];
41
+ executeAll(calls: ToolCall[], context: RunContext): AsyncIterable<StreamEvent>;
42
+ disconnect(): Promise<void>;
43
+ }
@@ -0,0 +1,58 @@
1
+ import { LocalExecutionPlane } from "./execution-plane.js";
2
+ /** ExecutionPlane adapter that keeps MCP wire details outside the Kernel. */
3
+ export class McpExecutionPlane {
4
+ configs;
5
+ factory;
6
+ connections = [];
7
+ toolMap = new Map();
8
+ connected = false;
9
+ local = new LocalExecutionPlane();
10
+ localNames = new Set();
11
+ constructor(configs, factory) {
12
+ this.configs = configs;
13
+ this.factory = factory;
14
+ }
15
+ async connect() {
16
+ if (this.connected)
17
+ return;
18
+ for (const config of this.configs) {
19
+ const connection = await this.factory(config);
20
+ await connection.start();
21
+ this.connections.push(connection);
22
+ for (const schema of connection.schemas())
23
+ this.toolMap.set(schema.name, connection);
24
+ }
25
+ this.connected = true;
26
+ }
27
+ register(...tools) { this.local.register(...tools); for (const tool of tools)
28
+ this.localNames.add(tool.schema.name); return this; }
29
+ unregister(name) { this.local.unregister(name); this.localNames.delete(name); this.toolMap.delete(name); return this; }
30
+ schemas() { return [...this.local.schemas(), ...this.connections.flatMap(connection => connection.schemas())]; }
31
+ async *executeAll(calls, context) {
32
+ const localCalls = calls.filter(call => this.localNames.has(call.name));
33
+ if (localCalls.length)
34
+ yield* this.local.executeAll(localCalls, context);
35
+ for (const call of calls) {
36
+ if (this.localNames.has(call.name))
37
+ continue;
38
+ const connection = this.toolMap.get(call.name);
39
+ if (!connection) {
40
+ yield { type: "tool_result", callId: call.id, name: call.name, content: `unknown MCP tool: ${call.name}`, isError: true };
41
+ continue;
42
+ }
43
+ try {
44
+ const result = await connection.execute(call, context);
45
+ yield { type: "tool_result", callId: call.id, name: call.name, content: result.content, isError: result.isError, contentParts: result.contentParts };
46
+ }
47
+ catch (error) {
48
+ yield { type: "tool_result", callId: call.id, name: call.name, content: String(error), isError: true };
49
+ }
50
+ }
51
+ }
52
+ async disconnect() {
53
+ await Promise.all(this.connections.map(connection => connection.stop()));
54
+ this.connections.length = 0;
55
+ this.toolMap.clear();
56
+ this.connected = false;
57
+ }
58
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstrike/wasm",
3
- "version": "0.2.73",
3
+ "version": "0.2.74",
4
4
  "description": "DeepStrike WASM SDK — browser, Cloudflare Workers, Deno Deploy",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -12,12 +12,12 @@
12
12
  ],
13
13
  "scripts": {
14
14
  "build:wasm": "wasm-pack build ../crates/deepstrike-wasm --target bundler --out-dir ../../wasm/pkg",
15
- "build": "tsc",
15
+ "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc",
16
16
  "test": "node --experimental-vm-modules node_modules/.bin/jest",
17
17
  "test:canonical-binding": "wasm-pack build ../crates/deepstrike-wasm --target nodejs --dev --out-dir ../../wasm/pkg-node && node tests/canonical-binding.node.cjs && node tests/golden-fixtures-sweep.node.cjs"
18
18
  },
19
19
  "dependencies": {
20
- "@deepstrike/wasm-kernel": "0.2.73"
20
+ "@deepstrike/wasm-kernel": "0.2.74"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/jest": "^30.0.0",
@@ -1,81 +0,0 @@
1
- import { Agent, type AgentOptions, type AgentToolDefinition, type Guardrail, type Handoff, type Knowledge, type MCPServer, type ModelRef, type Skill } from "./agent.js";
2
- import type { AgentCapabilityFilter } from "./runtime/types/agent.js";
3
- import type { RegisteredTool } from "./tools/index.js";
4
- type JsonSchema = Record<string, unknown>;
5
- export interface AgentDefinition extends Omit<AgentOptions, "tools"> {
6
- tools?: Array<RegisteredTool | AgentToolDefinition>;
7
- }
8
- export interface AgentToolIR {
9
- name: string;
10
- description: string;
11
- parameters: Record<string, unknown>;
12
- providerOptions?: Record<string, unknown>;
13
- }
14
- export interface AgentMemoryIR {
15
- kind: "durable" | "working";
16
- namespace?: string;
17
- }
18
- export type AgentCapabilityIR = {
19
- kind: "tool";
20
- id: string;
21
- description: string;
22
- } | {
23
- kind: "mcp_server";
24
- id: string;
25
- description: string;
26
- } | {
27
- kind: "skill";
28
- id: string;
29
- description: string;
30
- };
31
- export interface AgentLoweringInputs {
32
- run: {
33
- name: string;
34
- model?: ModelRef;
35
- };
36
- context: {
37
- description?: string;
38
- instructions?: string;
39
- outputSchema?: JsonSchema;
40
- knowledge: Knowledge[];
41
- };
42
- capabilities: {
43
- tools: AgentToolIR[];
44
- mcpServers: MCPServer[];
45
- skills: Skill[];
46
- effective: AgentCapabilityIR[];
47
- };
48
- memory?: AgentMemoryIR;
49
- delegation: {
50
- handoffs: Handoff[];
51
- };
52
- governance: {
53
- guardrails: Guardrail[];
54
- };
55
- }
56
- /** Provider-neutral host descriptor. This is neither an execution plan nor a Kernel wire DTO. */
57
- export interface AgentSpec {
58
- name: string;
59
- description?: string;
60
- instructions?: string;
61
- model?: ModelRef;
62
- tools: AgentToolIR[];
63
- outputSchema?: JsonSchema;
64
- mcpServers?: MCPServer[];
65
- skills?: Skill[];
66
- memory?: AgentMemoryIR;
67
- knowledge?: Knowledge[];
68
- handoffs?: Handoff[];
69
- guardrails?: Guardrail[];
70
- metadata?: Record<string, unknown>;
71
- capabilities: AgentCapabilityIR[];
72
- capabilityFilter?: AgentCapabilityFilter;
73
- effectiveCapabilities: AgentCapabilityIR[];
74
- extensions: Record<string, unknown>;
75
- inputs: AgentLoweringInputs;
76
- }
77
- /** Native Agents need no normalization; JSON-safe declarations remain schema-only capabilities. */
78
- export declare function normalizeAgent(agent: Agent | AgentDefinition): Agent;
79
- /** Pure lowering only: providers, Kernel scheduling, persistence, and grants remain outside it. */
80
- export declare function lowerAgent(agent: Agent): AgentSpec;
81
- export {};
package/dist/agent-ir.js DELETED
@@ -1,115 +0,0 @@
1
- import { Agent, } from "./agent.js";
2
- import { WorkingMemory } from "./memory/index.js";
3
- function clone(value) {
4
- if (value === undefined || value === null || typeof value !== "object")
5
- return value;
6
- if (Array.isArray(value))
7
- return value.map(clone);
8
- const copy = {};
9
- for (const [key, nested] of Object.entries(value))
10
- copy[key] = clone(nested);
11
- return copy;
12
- }
13
- function isRegisteredTool(tool) {
14
- return "schema" in tool && "execute" in tool;
15
- }
16
- /** Native Agents need no normalization; JSON-safe declarations remain schema-only capabilities. */
17
- export function normalizeAgent(agent) {
18
- if (agent instanceof Agent)
19
- return agent;
20
- return new Agent({ ...agent, ...(agent.tools ? { tools: clone(agent.tools) } : {}) });
21
- }
22
- function lowerTool(tool) {
23
- if (!isRegisteredTool(tool)) {
24
- const parameters = clone(tool.parameters ?? { type: "object", properties: {} });
25
- if (parameters.type !== "object") {
26
- throw new Error(`tool "${tool.name}": parameters must be a JSON Schema with root type "object"`);
27
- }
28
- return {
29
- name: tool.name,
30
- description: tool.description ?? "",
31
- parameters,
32
- ...(tool.providerOptions ? { providerOptions: clone(tool.providerOptions) } : {}),
33
- };
34
- }
35
- let parameters;
36
- try {
37
- parameters = JSON.parse(tool.schema.parameters);
38
- }
39
- catch {
40
- throw new Error(`tool "${tool.schema.name}" has invalid JSON Schema parameters`);
41
- }
42
- if (!parameters || typeof parameters !== "object" || Array.isArray(parameters) || parameters.type !== "object") {
43
- throw new Error(`tool "${tool.schema.name}" parameters must decode to an object`);
44
- }
45
- return { name: tool.schema.name, description: tool.schema.description, parameters: clone(parameters) };
46
- }
47
- function lowerMemory(memory) {
48
- if (!memory)
49
- return undefined;
50
- if (memory instanceof WorkingMemory)
51
- return { kind: "working" };
52
- const reference = memory;
53
- return { kind: "durable", ...(reference.namespace ? { namespace: reference.namespace } : {}) };
54
- }
55
- function capabilityAllowed(capability, filter) {
56
- if (!filter)
57
- return true;
58
- const kindAllowed = !filter.allowedKinds?.length || filter.allowedKinds.includes(capability.kind);
59
- const idAllowed = !filter.allowedIds?.length || filter.allowedIds.includes(capability.id);
60
- return kindAllowed && idAllowed;
61
- }
62
- /** Pure lowering only: providers, Kernel scheduling, persistence, and grants remain outside it. */
63
- export function lowerAgent(agent) {
64
- const tools = (agent.tools ?? []).map(lowerTool);
65
- const mcpServers = clone(agent.mcpServers ?? []);
66
- const skills = clone(agent.skills ?? []);
67
- const knowledge = clone(agent.knowledge ?? []);
68
- const handoffs = clone(agent.handoffs ?? []);
69
- const guardrails = clone(agent.guardrails ?? []);
70
- const memory = lowerMemory(agent.memory);
71
- const extensions = clone(agent.providerOptions ?? {});
72
- const capabilities = [
73
- ...tools.map(tool => ({ kind: "tool", id: tool.name, description: tool.description })),
74
- ...mcpServers.map(server => ({
75
- kind: "mcp_server",
76
- id: server.name ?? server.transport.kind,
77
- description: server.name ?? `${server.transport.kind} MCP server`,
78
- })),
79
- ...skills.map(skill => ({ kind: "skill", id: skill.name, description: skill.description ?? "" })),
80
- ];
81
- const capabilityFilter = agent.capabilityFilter ? clone(agent.capabilityFilter) : undefined;
82
- const effectiveCapabilities = capabilities.filter(capability => capabilityAllowed(capability, capabilityFilter));
83
- return {
84
- name: agent.name,
85
- ...(agent.description ? { description: agent.description } : {}),
86
- ...(agent.instructions ? { instructions: agent.instructions } : {}),
87
- ...(agent.model ? { model: clone(agent.model) } : {}),
88
- tools,
89
- ...(agent.outputSchema ? { outputSchema: clone(agent.outputSchema) } : {}),
90
- ...(mcpServers.length ? { mcpServers } : {}),
91
- ...(skills.length ? { skills } : {}),
92
- ...(memory ? { memory } : {}),
93
- ...(knowledge.length ? { knowledge } : {}),
94
- ...(handoffs.length ? { handoffs } : {}),
95
- ...(guardrails.length ? { guardrails } : {}),
96
- ...(agent.metadata ? { metadata: clone(agent.metadata) } : {}),
97
- capabilities,
98
- ...(capabilityFilter ? { capabilityFilter } : {}),
99
- effectiveCapabilities,
100
- extensions,
101
- inputs: {
102
- run: { name: agent.name, ...(agent.model ? { model: clone(agent.model) } : {}) },
103
- context: {
104
- ...(agent.description ? { description: agent.description } : {}),
105
- ...(agent.instructions ? { instructions: agent.instructions } : {}),
106
- ...(agent.outputSchema ? { outputSchema: clone(agent.outputSchema) } : {}),
107
- knowledge,
108
- },
109
- capabilities: { tools, mcpServers, skills, effective: effectiveCapabilities },
110
- ...(memory ? { memory } : {}),
111
- delegation: { handoffs },
112
- governance: { guardrails },
113
- },
114
- };
115
- }