@deepstrike/sdk 0.2.71 → 0.2.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -5
- package/dist/advanced/public.d.ts +4 -0
- package/dist/advanced/public.js +2 -0
- package/dist/agent-facade.d.ts +33 -8
- package/dist/agent-facade.js +135 -24
- package/dist/agent-ir.d.ts +11 -5
- package/dist/agent-ir.js +42 -26
- package/dist/canonical-prefix-allowlist.d.ts +6 -0
- package/dist/canonical-prefix-allowlist.js +30 -0
- package/dist/conformance.d.ts +5 -0
- package/dist/conformance.js +7 -0
- package/dist/evals/public.d.ts +57 -0
- package/dist/evals/public.js +24 -0
- package/dist/guardrail.d.ts +4 -1
- package/dist/handoff-target.d.ts +2 -0
- package/dist/handoff-target.js +7 -1
- package/dist/index.d.ts +12 -46
- package/dist/index.js +5 -26
- package/dist/kernel.d.ts +2 -2
- package/dist/knowledge/public.d.ts +2 -0
- package/dist/knowledge/public.js +1 -1
- package/dist/knowledge/source.d.ts +7 -0
- package/dist/knowledge/source.js +20 -1
- package/dist/memory/protocols.d.ts +2 -2
- package/dist/projection-pairs.d.ts +43 -0
- package/dist/projection-pairs.js +9 -0
- package/dist/providers/anthropic-adapter.d.ts +2 -2
- package/dist/providers/anthropic.d.ts +4 -4
- package/dist/providers/base.d.ts +5 -5
- package/dist/providers/content-normalization.d.ts +4 -4
- package/dist/providers/gemini-adapter.d.ts +2 -2
- package/dist/providers/gemini.d.ts +3 -3
- package/dist/providers/ollama-adapter.d.ts +2 -2
- package/dist/providers/ollama.d.ts +2 -2
- package/dist/providers/openai-chat.d.ts +4 -4
- package/dist/providers/openai-responses-adapter.d.ts +2 -2
- package/dist/providers/openai-responses.d.ts +2 -2
- package/dist/providers/openai.d.ts +4 -4
- package/dist/providers/protocol-adapter.d.ts +2 -2
- package/dist/providers/protocol-capabilities.d.ts +1 -0
- package/dist/providers/protocol-capabilities.js +3 -0
- package/dist/providers/public.d.ts +4 -2
- package/dist/providers/public.js +2 -1
- package/dist/providers/replay-validator.d.ts +3 -3
- package/dist/reactions.d.ts +2 -0
- package/dist/reactions.js +3 -0
- package/dist/runtime/archive.d.ts +7 -7
- package/dist/runtime/canonical-kernel-step.d.ts +2 -2
- package/dist/runtime/context-manager.d.ts +56 -0
- package/dist/runtime/context-manager.js +112 -0
- package/dist/runtime/eval.d.ts +2 -2
- package/dist/runtime/kernel-step.d.ts +5 -5
- package/dist/runtime/provider-replay.d.ts +2 -2
- package/dist/runtime/public.d.ts +22 -0
- package/dist/runtime/public.js +11 -0
- package/dist/runtime/replay-fixture.d.ts +3 -3
- package/dist/runtime/replay-fixture.js +1 -1
- package/dist/runtime/replay-provider.d.ts +4 -4
- package/dist/runtime/replay-provider.js +1 -1
- package/dist/runtime/runner.d.ts +17 -5
- package/dist/runtime/runner.js +110 -37
- package/dist/runtime/session-log.d.ts +1 -1
- package/dist/runtime/session-repair.d.ts +2 -2
- package/dist/runtime/workflow-control-flow.d.ts +1 -1
- package/dist/runtime/workflow-control-flow.js +16 -2
- package/dist/runtime-classification.d.ts +161 -0
- package/dist/runtime-classification.js +66 -0
- package/dist/runtime-language.d.ts +32 -0
- package/dist/runtime-language.js +51 -0
- package/dist/session-events.d.ts +3 -0
- package/dist/session-events.js +1 -0
- package/dist/skill.d.ts +31 -5
- package/dist/types/agent.d.ts +17 -4
- package/dist/types.d.ts +25 -15
- package/dist/workflow/definition.d.ts +19 -0
- package/dist/workflow/definition.js +29 -0
- package/dist/workflow/public.d.ts +3 -1
- package/dist/workflow/public.js +1 -0
- package/package.json +16 -2
- package/dist/compat/anthropic/mcp.d.ts +0 -15
- package/dist/compat/anthropic/mcp.js +0 -10
- package/dist/compat/openai/agent.d.ts +0 -34
- package/dist/compat/openai/agent.js +0 -24
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
# DeepStrike Node.js SDK
|
|
7
|
+
# DeepStrike Node.js SDK (0.2.73)
|
|
8
8
|
|
|
9
9
|
Build Node.js Agents with providers, typed tools, memory, Skills, delegation, workflows, and durable sessions. The SDK keeps the Agent's long-running work explicit through stream events, SessionLog evidence, tool policies, and host-provided integrations.
|
|
10
10
|
|
|
@@ -55,7 +55,8 @@ const add = tool("add", "Add two numbers.", {
|
|
|
55
55
|
|
|
56
56
|
const agent = createAgent({
|
|
57
57
|
name: "math",
|
|
58
|
-
|
|
58
|
+
model: "openai/gpt-5-mini",
|
|
59
|
+
runtimeBinding: { provider },
|
|
59
60
|
tools: [add],
|
|
60
61
|
})
|
|
61
62
|
|
|
@@ -87,9 +88,11 @@ The root export is the **Agent intent layer** — what you reach for to define a
|
|
|
87
88
|
| `@deepstrike/sdk/memory` | `MemoryStore`, `WorkingMemory`, `InMemoryMemoryStore`, `rankMemories`, `extractSessionMemories`, `KnowledgeSource` |
|
|
88
89
|
| `@deepstrike/sdk/harness` | `AttemptLoop`, body/judge/carry policies, `judge` |
|
|
89
90
|
| `@deepstrike/sdk/os` | profiles, `KernelPrimitivesDashboard`, `primitiveForKind` / `KernelPrimitive`, signals, `PermissionManager`, replay-testing utilities |
|
|
90
|
-
| `@deepstrike/sdk/
|
|
91
|
+
| `@deepstrike/sdk/runtime` | RuntimeRunner, SessionLog, runtime projections, and host execution helpers |
|
|
92
|
+
| `@deepstrike/sdk/evals` | Public evaluation language: `judge`, criteria, verdicts, and schemas |
|
|
93
|
+
| `@deepstrike/sdk/advanced` | Kernel diagnostics and low-level orchestration escape hatches |
|
|
91
94
|
|
|
92
|
-
> **Migration from 0.2.
|
|
95
|
+
> **Migration from 0.2.71:** see [`MIGRATION-v0.2.71-to-v0.2.73.md`](../MIGRATION-v0.2.71-to-v0.2.73.md) for the AgentDefinition, message, runtime binding, workflow and package changes.
|
|
93
96
|
|
|
94
97
|
The recipes below the Agent section that mention `RuntimeRunner` are advanced implementation examples. Import it from `@deepstrike/sdk/advanced`; application code should use the Agent and Session methods shown above.
|
|
95
98
|
|
|
@@ -100,7 +103,7 @@ Most apps start with one executable Agent. Streaming, sessions, memory, delegati
|
|
|
100
103
|
```typescript
|
|
101
104
|
import { createAgent } from "@deepstrike/sdk"
|
|
102
105
|
|
|
103
|
-
const agent = createAgent({ name: "researcher", provider, tools: [add] })
|
|
106
|
+
const agent = createAgent({ name: "researcher", model: "openai/gpt-5-mini", runtimeBinding: { provider }, tools: [add] })
|
|
104
107
|
const answer = await agent.run("What is 17 + 28?")
|
|
105
108
|
console.log(answer.output)
|
|
106
109
|
|
|
@@ -114,6 +117,28 @@ console.log(delegated.output)
|
|
|
114
117
|
|
|
115
118
|
For parallel work and dependency graphs, use `agent.workflow(...)`. Kernel scheduling and run isolation remain internal to the Agent facade.
|
|
116
119
|
|
|
120
|
+
### Multimodal input
|
|
121
|
+
|
|
122
|
+
Pass image or audio parts through `AgentRunOptions.attachments`. The runner persists them with the
|
|
123
|
+
session and avoids injecting the same attachment twice when a session continues or resumes:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const session = agent.session("conversation-1")
|
|
127
|
+
|
|
128
|
+
await session.run("先看看这张图", {
|
|
129
|
+
attachments: [{
|
|
130
|
+
type: "image",
|
|
131
|
+
source: { kind: "url", url: "https://storage.example.com/signed/image.png" },
|
|
132
|
+
mediaType: "image/png",
|
|
133
|
+
}],
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
await session.run("继续解释其中的内容")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The current public `ContentPart` contract supports text, image, audio, and tool-result parts.
|
|
140
|
+
Video and file attachments require an explicit content-type extension and provider conversion.
|
|
141
|
+
|
|
117
142
|
### Deploying to serverless / bundlers
|
|
118
143
|
|
|
119
144
|
`@deepstrike/core` is a native N-API addon; its platform binary ships via `optionalDependencies`. Bundlers (Next.js/Vercel, webpack, esbuild) don't trace `.node` files by default, so the function fails at runtime with `Cannot find module '@deepstrike/core'`. Tell your bundler to treat the package as external and trace its files:
|
|
@@ -18,3 +18,7 @@ export * from "../runtime/reliability.js";
|
|
|
18
18
|
export * from "../runtime/turn-policy.js";
|
|
19
19
|
export * from "../runtime/reactive-session.js";
|
|
20
20
|
export * from "../runtime/reaction-checkpoint.js";
|
|
21
|
+
export { projectAgentRun, projectAgentContext, projectAgentCapabilities, projectAgentGovernance, projectAgentDelegation } from "../agent-ir.js";
|
|
22
|
+
export type { AgentDescriptor } from "../agent-ir.js";
|
|
23
|
+
export { FileKernelJournal, InMemoryKernelJournal, JournalCasConflictError, JournalIntegrityError, JournalIoError, diagnoseKernelJournal, } from "../runtime/public.js";
|
|
24
|
+
export type { CheckpointCandidate, InstalledCheckpoint, JournalAppendReceipt, JournalEntry, JournalHead, JournalPruneReceipt, JournalRecordInput, KernelJournal, KernelJournalDiagnosis, ContextPrepared, ContextPrepareJson, ContextVerifyJson, ContextProviderPreparationRequest, EvolutionRuntime, EvolutionStore, InvocationOutcome, ModelInvocation, ProviderAttempt, ProviderAttemptRecord, ProviderAttemptStatus, UsageAccountingPolicy, ModelUsageSettlement, } from "../runtime/public.js";
|
package/dist/advanced/public.js
CHANGED
|
@@ -14,3 +14,5 @@ export * from "../runtime/reliability.js";
|
|
|
14
14
|
export * from "../runtime/turn-policy.js";
|
|
15
15
|
export * from "../runtime/reactive-session.js";
|
|
16
16
|
export * from "../runtime/reaction-checkpoint.js";
|
|
17
|
+
export { projectAgentRun, projectAgentContext, projectAgentCapabilities, projectAgentGovernance, projectAgentDelegation } from "../agent-ir.js";
|
|
18
|
+
export { FileKernelJournal, InMemoryKernelJournal, JournalCasConflictError, JournalIntegrityError, JournalIoError, diagnoseKernelJournal, } from "../runtime/public.js";
|
package/dist/agent-facade.d.ts
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
import { type AgentOptions } from "./agent.js";
|
|
1
|
+
import { type AgentOptions, type ModelRef } from "./agent.js";
|
|
2
2
|
import { type SessionLog } from "./runtime/session-log.js";
|
|
3
3
|
import { type ExecutionPlane } from "./runtime/execution-plane.js";
|
|
4
4
|
import { type RuntimeOptions } from "./runtime/runner.js";
|
|
5
|
-
import type { LLMProvider, StreamEvent, TokenUsage } from "./types.js";
|
|
5
|
+
import type { LLMProvider, StreamEvent, TokenUsage, ContentPart } from "./types.js";
|
|
6
6
|
import type { RegisteredTool } from "./tools/index.js";
|
|
7
7
|
import type { MemoryRecord, MemoryRecall, MemoryScope, MemoryStore, MemoryKind } from "./memory/protocols.js";
|
|
8
8
|
import type { WorkflowSpec, WorkflowOutcome, KernelAgentRole } from "./types/agent.js";
|
|
9
9
|
export interface AgentDefinition extends Omit<AgentOptions, "model" | "name"> {
|
|
10
10
|
name?: string;
|
|
11
|
-
provider
|
|
11
|
+
/** Public model identity. Runtime resolves this through a provider binding. */
|
|
12
|
+
model?: ModelRef;
|
|
12
13
|
tools?: RegisteredTool[];
|
|
13
|
-
executionPlane?: ExecutionPlane;
|
|
14
|
-
sessionLog?: SessionLog;
|
|
15
14
|
maxTokens?: number;
|
|
16
15
|
memoryStore?: MemoryStore;
|
|
17
16
|
memoryScope?: MemoryScope;
|
|
18
|
-
|
|
17
|
+
runtimeBinding?: RuntimeBinding;
|
|
18
|
+
}
|
|
19
|
+
export interface RuntimeBinding {
|
|
20
|
+
provider?: LLMProvider;
|
|
21
|
+
providerFor?: RuntimeOptions["providerFor"];
|
|
22
|
+
executionPlane?: ExecutionPlane;
|
|
23
|
+
sessionLog?: SessionLog;
|
|
24
|
+
runtimeOptions?: Pick<RuntimeOptions, "memoryPolicy" | "governancePolicy" | "signalSource" | "signalPolicy" | "resourceQuota" | "onPermissionRequest" | "payloadStore" | "runGroup" | "subAgentOrchestrator" | "reducers" | "initialMemory" | "skillCatalog" | "knowledgeSource" | "contextManager" | "artifactSetDigest">;
|
|
19
25
|
}
|
|
20
26
|
export interface AgentRunOptions {
|
|
21
27
|
session?: SessionRef;
|
|
@@ -23,6 +29,8 @@ export interface AgentRunOptions {
|
|
|
23
29
|
signal?: AbortSignal;
|
|
24
30
|
metadata?: Record<string, unknown>;
|
|
25
31
|
onPermissionRequest?: RuntimeOptions["onPermissionRequest"];
|
|
32
|
+
/** Multimodal user input attached to this run and persisted in the session log. */
|
|
33
|
+
attachments?: ContentPart[];
|
|
26
34
|
}
|
|
27
35
|
export interface SessionRef {
|
|
28
36
|
id: string;
|
|
@@ -33,6 +41,17 @@ export interface RunResult<T = string> {
|
|
|
33
41
|
sessionId: string;
|
|
34
42
|
status: "completed" | "partial" | "failed" | "cancelled";
|
|
35
43
|
usage?: TokenUsage;
|
|
44
|
+
outputValidation?: {
|
|
45
|
+
ok: boolean;
|
|
46
|
+
errors: string[];
|
|
47
|
+
};
|
|
48
|
+
/** Host-owned execution evidence captured for evaluation and replay. */
|
|
49
|
+
evidence?: {
|
|
50
|
+
contextBinding?: unknown;
|
|
51
|
+
route?: unknown;
|
|
52
|
+
measurement?: unknown;
|
|
53
|
+
artifactSet?: unknown;
|
|
54
|
+
};
|
|
36
55
|
}
|
|
37
56
|
export interface AgentSession extends SessionRef {
|
|
38
57
|
run(goal: string, options?: Omit<AgentRunOptions, "session">): Promise<RunResult>;
|
|
@@ -57,13 +76,16 @@ export interface RecallOptions {
|
|
|
57
76
|
export interface DelegationRequest {
|
|
58
77
|
goal: string;
|
|
59
78
|
role?: KernelAgentRole;
|
|
79
|
+
/** Optional declared handoff target. When handoffs are declared, this is required and allowlisted. */
|
|
80
|
+
target?: import("./handoff-target.js").AgentRef;
|
|
60
81
|
}
|
|
61
82
|
export interface DelegationResult {
|
|
62
83
|
output: string;
|
|
63
84
|
status: "completed" | "partial" | "failed";
|
|
64
85
|
nodeId?: string;
|
|
65
86
|
}
|
|
66
|
-
|
|
87
|
+
/** The executable public Agent handle created from an AgentDefinition. */
|
|
88
|
+
export interface Agent {
|
|
67
89
|
readonly name: string;
|
|
68
90
|
readonly definition: Readonly<AgentDefinition>;
|
|
69
91
|
run(goal: string, options?: AgentRunOptions): Promise<RunResult>;
|
|
@@ -79,5 +101,8 @@ export interface ExecutableAgent {
|
|
|
79
101
|
session?: SessionRef;
|
|
80
102
|
leaseMs?: number;
|
|
81
103
|
}): Promise<RunResult | null>;
|
|
104
|
+
close(): Promise<void>;
|
|
82
105
|
}
|
|
83
|
-
|
|
106
|
+
/** @internal Compatibility alias; public code should use `Agent`. */
|
|
107
|
+
export type AgentRuntime = Agent;
|
|
108
|
+
export declare function createAgent(definition: AgentDefinition): Agent;
|
package/dist/agent-facade.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { normalizeAgent } from "./agent-ir.js";
|
|
1
2
|
import { InMemorySessionLog } from "./runtime/session-log.js";
|
|
2
3
|
import { LocalExecutionPlane } from "./runtime/execution-plane.js";
|
|
3
4
|
import { RuntimeRunner } from "./runtime/runner.js";
|
|
5
|
+
import { extractJsonValue, schemaInstruction, validateAgainstSchema } from "./runtime/output-schema.js";
|
|
6
|
+
import { McpProxyPlane } from "./runtime/mcp-proxy-plane.js";
|
|
7
|
+
import { EnvCredentialVault } from "./runtime/credential-vault.js";
|
|
8
|
+
import { agentRefName } from "./handoff-target.js";
|
|
9
|
+
import { createTextKnowledgeSource } from "./knowledge/public.js";
|
|
4
10
|
function sessionId(ref) {
|
|
5
11
|
return ref?.id ?? `session-${crypto.randomUUID()}`;
|
|
6
12
|
}
|
|
@@ -13,6 +19,19 @@ function statusFromDone(status) {
|
|
|
13
19
|
return "failed";
|
|
14
20
|
return "partial";
|
|
15
21
|
}
|
|
22
|
+
function mergeGuardrailPolicies(base, guardrails) {
|
|
23
|
+
const policies = [base, ...(guardrails ?? []).map(guardrail => guardrail.policy)].filter((policy) => policy !== undefined);
|
|
24
|
+
if (!policies.length)
|
|
25
|
+
return undefined;
|
|
26
|
+
return {
|
|
27
|
+
...(policies.some(policy => policy.defaultAction === "deny") ? { defaultAction: "deny" } : {}),
|
|
28
|
+
rules: policies.flatMap(policy => policy.rules ?? []),
|
|
29
|
+
vetoes: [...new Set(policies.flatMap(policy => policy.vetoes ?? []))],
|
|
30
|
+
rateLimits: policies.flatMap(policy => policy.rateLimits ?? []),
|
|
31
|
+
constraints: policies.flatMap(policy => policy.constraints ?? []),
|
|
32
|
+
...(policies.some(policy => policy.surfaceDeniedInSystem === false) ? { surfaceDeniedInSystem: false } : {}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
16
35
|
class AgentSessionImpl {
|
|
17
36
|
owner;
|
|
18
37
|
id;
|
|
@@ -33,17 +52,17 @@ class AgentSessionImpl {
|
|
|
33
52
|
this.owner.interrupt(reason);
|
|
34
53
|
}
|
|
35
54
|
}
|
|
36
|
-
class
|
|
55
|
+
class AgentRuntimeImpl {
|
|
37
56
|
name;
|
|
38
57
|
definition;
|
|
39
58
|
sessionLog;
|
|
40
59
|
activeRunner = null;
|
|
60
|
+
mcpPlane;
|
|
61
|
+
mcpConnection;
|
|
41
62
|
constructor(definition) {
|
|
42
|
-
if (!definition.provider)
|
|
43
|
-
throw new TypeError("createAgent requires a provider");
|
|
44
63
|
this.definition = Object.freeze({ ...definition });
|
|
45
|
-
this.name = definition.name
|
|
46
|
-
this.sessionLog = definition.sessionLog ?? new InMemorySessionLog();
|
|
64
|
+
this.name = normalizeAgent(definition).name;
|
|
65
|
+
this.sessionLog = definition.runtimeBinding?.sessionLog ?? new InMemorySessionLog();
|
|
47
66
|
}
|
|
48
67
|
session(id = `session-${crypto.randomUUID()}`) {
|
|
49
68
|
return new AgentSessionImpl(this, id);
|
|
@@ -88,6 +107,17 @@ class ExecutableAgentImpl {
|
|
|
88
107
|
return store.search(this.name, request);
|
|
89
108
|
}
|
|
90
109
|
async delegate(request) {
|
|
110
|
+
const handoffs = this.definition.handoffs ?? [];
|
|
111
|
+
if (handoffs.length) {
|
|
112
|
+
if (!request.target)
|
|
113
|
+
throw new Error(`agent "${this.name}" requires an explicit handoff target`);
|
|
114
|
+
const targetName = agentRefName(request.target);
|
|
115
|
+
const allowed = handoffs.some(handoff => {
|
|
116
|
+
return agentRefName(handoff.agent) === targetName;
|
|
117
|
+
});
|
|
118
|
+
if (!allowed)
|
|
119
|
+
throw new Error(`agent "${this.name}" cannot hand off to "${targetName}"`);
|
|
120
|
+
}
|
|
91
121
|
const spec = {
|
|
92
122
|
nodes: [{
|
|
93
123
|
task: { goal: request.goal },
|
|
@@ -107,6 +137,7 @@ class ExecutableAgentImpl {
|
|
|
107
137
|
}
|
|
108
138
|
async workflow(spec, options = {}) {
|
|
109
139
|
const runner = this.createRunner({});
|
|
140
|
+
await this.prepareMcp();
|
|
110
141
|
this.activeRunner = runner;
|
|
111
142
|
try {
|
|
112
143
|
return await runner.runWorkflow(spec, { sessionId: sessionId(options.session) });
|
|
@@ -116,7 +147,7 @@ class ExecutableAgentImpl {
|
|
|
116
147
|
}
|
|
117
148
|
}
|
|
118
149
|
async listen(options = {}) {
|
|
119
|
-
const source = this.definition.runtimeOptions?.signalSource;
|
|
150
|
+
const source = this.definition.runtimeBinding?.runtimeOptions?.signalSource;
|
|
120
151
|
if (!source)
|
|
121
152
|
throw new Error("agent signals require runtimeOptions.signalSource");
|
|
122
153
|
const claim = await source.claimSignal(this.name, options.leaseMs);
|
|
@@ -140,17 +171,21 @@ class ExecutableAgentImpl {
|
|
|
140
171
|
}
|
|
141
172
|
stream(goal, options = {}) {
|
|
142
173
|
const session = sessionId(options.session);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
options.signal.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
174
|
+
const owner = this;
|
|
175
|
+
return (async function* () {
|
|
176
|
+
const runner = owner.createRunner(options);
|
|
177
|
+
await owner.prepareMcp();
|
|
178
|
+
owner.activeRunner = runner;
|
|
179
|
+
const abort = () => runner.interrupt("user");
|
|
180
|
+
if (options.signal) {
|
|
181
|
+
if (options.signal.aborted)
|
|
182
|
+
runner.interrupt("user");
|
|
183
|
+
else
|
|
184
|
+
options.signal.addEventListener("abort", abort, { once: true });
|
|
185
|
+
}
|
|
186
|
+
const stream = runner.run({ sessionId: session, goal, ...(options.attachments?.length ? { attachments: options.attachments } : {}) });
|
|
187
|
+
yield* owner.clearRunnerAfter(stream, options.signal, abort);
|
|
188
|
+
})();
|
|
154
189
|
}
|
|
155
190
|
async run(goal, options = {}) {
|
|
156
191
|
const session = sessionId(options.session);
|
|
@@ -163,11 +198,26 @@ class ExecutableAgentImpl {
|
|
|
163
198
|
const started = [...persisted].reverse().find(entry => entry.event.kind === "run_started");
|
|
164
199
|
const usageEvent = [...events].reverse().find(event => event.type === "usage");
|
|
165
200
|
const output = events.filter(event => event.type === "text_delta").map(event => String(event.delta ?? "")).join("");
|
|
201
|
+
const prepared = [...persisted].reverse().find(entry => entry.event.kind === "context_prepared");
|
|
202
|
+
const measured = [...persisted].reverse().find(entry => entry.event.kind === "prompt_measured");
|
|
203
|
+
const attempt = [...persisted].reverse().find(entry => entry.event.kind === "provider_attempt");
|
|
204
|
+
const runStarted = [...persisted].reverse().find(entry => entry.event.kind === "run_started");
|
|
205
|
+
const binding = this.definition.runtimeBinding;
|
|
206
|
+
const evidence = {
|
|
207
|
+
...(prepared?.event.kind === "context_prepared" ? { contextBinding: prepared.event.preparation.binding } : {}),
|
|
208
|
+
...(attempt?.event.kind === "provider_attempt" ? { route: attempt.event.route } : runStarted?.event.kind === "run_started" && runStarted.event.route ? { route: runStarted.event.route } : {}),
|
|
209
|
+
...(measured?.event.kind === "prompt_measured" ? { measurement: measured.event.measurement } : {}),
|
|
210
|
+
...(binding?.runtimeOptions?.artifactSetDigest ? { artifactSet: { digest: binding.runtimeOptions.artifactSetDigest } } : {}),
|
|
211
|
+
};
|
|
212
|
+
const outputValidation = this.definition.outputSchema
|
|
213
|
+
? validateAgainstSchema(extractJsonValue(output), this.definition.outputSchema)
|
|
214
|
+
: undefined;
|
|
166
215
|
return {
|
|
167
216
|
output,
|
|
168
217
|
runId: started?.event.kind === "run_started" ? started.event.run_id : `run-${crypto.randomUUID()}`,
|
|
169
218
|
sessionId: session,
|
|
170
|
-
status: error ? "failed" : statusFromDone(done?.status ?? "partial"),
|
|
219
|
+
status: error || outputValidation && !outputValidation.ok ? "failed" : statusFromDone(done?.status ?? "partial"),
|
|
220
|
+
...(outputValidation ? { outputValidation } : {}),
|
|
171
221
|
...(usageEvent?.totalTokens !== undefined ? {
|
|
172
222
|
usage: {
|
|
173
223
|
inputTokens: usageEvent.inputTokens ?? 0,
|
|
@@ -175,30 +225,91 @@ class ExecutableAgentImpl {
|
|
|
175
225
|
totalTokens: usageEvent.totalTokens,
|
|
176
226
|
},
|
|
177
227
|
} : {}),
|
|
228
|
+
...(Object.keys(evidence).length ? { evidence } : {}),
|
|
178
229
|
};
|
|
179
230
|
}
|
|
180
231
|
async *resume(id, options = {}) {
|
|
181
232
|
const runner = this.createRunner(options);
|
|
233
|
+
await this.prepareMcp();
|
|
182
234
|
this.activeRunner = runner;
|
|
183
235
|
yield* this.clearRunnerAfter(runner.wake(id), options.signal, () => runner.interrupt("user"));
|
|
184
236
|
}
|
|
185
237
|
interrupt(reason = "user") {
|
|
186
238
|
this.activeRunner?.interrupt(reason);
|
|
187
239
|
}
|
|
240
|
+
async close() {
|
|
241
|
+
await this.mcpConnection;
|
|
242
|
+
await this.mcpPlane?.disconnect();
|
|
243
|
+
this.mcpPlane = undefined;
|
|
244
|
+
this.mcpConnection = undefined;
|
|
245
|
+
}
|
|
246
|
+
async prepareMcp() {
|
|
247
|
+
if (!this.mcpPlane || this.mcpConnection) {
|
|
248
|
+
await this.mcpConnection;
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
this.mcpConnection = this.mcpPlane.connect();
|
|
252
|
+
await this.mcpConnection;
|
|
253
|
+
}
|
|
188
254
|
createRunner(options) {
|
|
189
|
-
const
|
|
190
|
-
|
|
255
|
+
const model = this.definition.model;
|
|
256
|
+
const binding = this.definition.runtimeBinding;
|
|
257
|
+
const provider = binding?.provider
|
|
258
|
+
?? (typeof model === "string" ? binding?.providerFor?.(model) : undefined);
|
|
259
|
+
if (!provider) {
|
|
260
|
+
throw new Error(`agent "${this.name}" has no runtime provider binding for model ${typeof this.definition.model === "string" ? this.definition.model : "(unresolved)"}`);
|
|
261
|
+
}
|
|
262
|
+
if (binding?.executionPlane && this.definition.mcpServers?.length) {
|
|
263
|
+
throw new Error("agent mcpServers cannot be combined with a custom executionPlane");
|
|
264
|
+
}
|
|
265
|
+
const plane = binding?.executionPlane
|
|
266
|
+
?? (this.definition.mcpServers?.length
|
|
267
|
+
? (() => {
|
|
268
|
+
const servers = Object.fromEntries(this.definition.mcpServers.map(server => {
|
|
269
|
+
if (server.transport.kind !== "stdio") {
|
|
270
|
+
throw new Error(`agent MCP transport "${server.transport.kind}" is not supported by the local runtime`);
|
|
271
|
+
}
|
|
272
|
+
if (server.auth && Object.keys(server.auth).length > 0) {
|
|
273
|
+
throw new Error(`agent MCP server "${server.name ?? server.transport.command}" auth requires an explicit CredentialVault binding`);
|
|
274
|
+
}
|
|
275
|
+
return [server.name ?? server.transport.command, {
|
|
276
|
+
command: server.transport.command,
|
|
277
|
+
...(server.transport.args ? { args: server.transport.args } : {}),
|
|
278
|
+
}];
|
|
279
|
+
}));
|
|
280
|
+
this.mcpPlane ??= new McpProxyPlane({ servers, vault: new EnvCredentialVault() });
|
|
281
|
+
return this.mcpPlane;
|
|
282
|
+
})()
|
|
283
|
+
: (this.definition.tools ?? []).reduce((current, currentTool) => current.register(currentTool), new LocalExecutionPlane()));
|
|
284
|
+
if (this.definition.mcpServers?.length && this.definition.tools?.length) {
|
|
285
|
+
plane.register(...this.definition.tools);
|
|
286
|
+
}
|
|
191
287
|
const runtime = {
|
|
192
|
-
provider
|
|
288
|
+
provider,
|
|
289
|
+
...(mergeGuardrailPolicies(binding?.runtimeOptions?.governancePolicy, this.definition.guardrails)
|
|
290
|
+
? { governancePolicy: mergeGuardrailPolicies(binding?.runtimeOptions?.governancePolicy, this.definition.guardrails) }
|
|
291
|
+
: {}),
|
|
292
|
+
...(this.definition.capabilityFilter ? { capabilityFilter: this.definition.capabilityFilter } : {}),
|
|
193
293
|
executionPlane: plane,
|
|
194
294
|
sessionLog: this.sessionLog,
|
|
195
295
|
maxTokens: this.definition.maxTokens ?? 32_000,
|
|
196
|
-
...(this.definition.instructions
|
|
296
|
+
...(this.definition.instructions || this.definition.outputSchema ? {
|
|
297
|
+
systemPrompt: [
|
|
298
|
+
this.definition.instructions,
|
|
299
|
+
this.definition.outputSchema ? schemaInstruction(this.definition.outputSchema) : undefined,
|
|
300
|
+
].filter((part) => Boolean(part)).join("\n\n"),
|
|
301
|
+
} : {}),
|
|
197
302
|
...(options.maxTurns !== undefined ? { maxTurns: options.maxTurns } : {}),
|
|
198
303
|
...(this.definition.memoryStore ? { memoryStore: this.definition.memoryStore } : {}),
|
|
199
304
|
...(this.definition.memoryScope ? { memoryScope: this.definition.memoryScope } : {}),
|
|
305
|
+
...(this.definition.skills?.length ? { skillCatalog: this.definition.skills } : {}),
|
|
306
|
+
...(!binding?.runtimeOptions?.knowledgeSource && this.definition.knowledge?.some(item => item.source.kind === "text") ? {
|
|
307
|
+
knowledgeSource: createTextKnowledgeSource(this.definition.knowledge
|
|
308
|
+
.filter((item) => item.source.kind === "text")
|
|
309
|
+
.map(item => ({ id: item.id, name: item.name, content: item.source.content }))),
|
|
310
|
+
} : {}),
|
|
200
311
|
agentId: this.name,
|
|
201
|
-
...(
|
|
312
|
+
...(binding?.runtimeOptions ?? {}),
|
|
202
313
|
...(options.onPermissionRequest ? { onPermissionRequest: options.onPermissionRequest } : {}),
|
|
203
314
|
};
|
|
204
315
|
return new RuntimeRunner(runtime);
|
|
@@ -215,5 +326,5 @@ class ExecutableAgentImpl {
|
|
|
215
326
|
}
|
|
216
327
|
}
|
|
217
328
|
export function createAgent(definition) {
|
|
218
|
-
return new
|
|
329
|
+
return new AgentRuntimeImpl(definition);
|
|
219
330
|
}
|
package/dist/agent-ir.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AgentDefinition } from "./agent-facade.js";
|
|
1
2
|
import { Agent, type AgentOptions, type ModelRef } from "./agent.js";
|
|
2
3
|
import type { Guardrail } from "./guardrail.js";
|
|
3
4
|
import type { Handoff } from "./handoff-target.js";
|
|
@@ -15,7 +16,7 @@ export interface AgentToolDefinition {
|
|
|
15
16
|
}
|
|
16
17
|
/** A JSON-friendly Agent definition accepted by `normalizeAgent`. It is deliberately declarative:
|
|
17
18
|
* executable tools still enter the SDK through `AgentOptions.tools`. */
|
|
18
|
-
export interface
|
|
19
|
+
export interface AgentDescriptor extends Omit<AgentOptions, "tools"> {
|
|
19
20
|
tools?: Array<RegisteredTool | AgentToolDefinition>;
|
|
20
21
|
}
|
|
21
22
|
export interface AgentToolIR {
|
|
@@ -85,19 +86,24 @@ export interface AgentSpec {
|
|
|
85
86
|
guardrails?: Guardrail[];
|
|
86
87
|
metadata?: Record<string, unknown>;
|
|
87
88
|
/** Declared capabilities. This descriptive view grants nothing by itself. */
|
|
88
|
-
capabilities: AgentCapabilityIR[];
|
|
89
|
+
readonly capabilities: AgentCapabilityIR[];
|
|
89
90
|
/** Host ceiling copied from the public Agent, when supplied. Empty axes remain non-narrowing. */
|
|
90
91
|
capabilityFilter?: AgentCapabilityFilter;
|
|
91
92
|
/** The declarations that survive the supplied local ceiling. Host mounts may narrow further. */
|
|
92
|
-
effectiveCapabilities: AgentCapabilityIR[];
|
|
93
|
+
readonly effectiveCapabilities: AgentCapabilityIR[];
|
|
93
94
|
/** Namespace-isolated provider extensions. Unknown namespaces are preserved verbatim. */
|
|
94
95
|
extensions: Record<string, unknown>;
|
|
95
|
-
inputs: AgentLoweringInputs;
|
|
96
96
|
}
|
|
97
97
|
/** Normalizes native Agents and JSON-safe descriptor objects into the one public surface used by
|
|
98
98
|
* lowering. It does not interpret provider namespaces or create executable capabilities. */
|
|
99
|
-
export declare function normalizeAgent(agent: Agent | AgentDefinition): Agent;
|
|
99
|
+
export declare function normalizeAgent(agent: Agent | AgentDefinition | AgentDescriptor): Agent;
|
|
100
100
|
/** Pure: no provider branching, no scheduling, authorization, persistence, or Kernel wire calls.
|
|
101
101
|
* Providers consume only their own namespace from `extensions`; the host decides whether declared
|
|
102
102
|
* capabilities survive its existing attenuation filter. */
|
|
103
103
|
export declare function lowerAgent(agent: Agent): AgentSpec;
|
|
104
|
+
/** Detached projections; callers can adapt them without changing AgentSpec authority. */
|
|
105
|
+
export declare function projectAgentRun(spec: AgentSpec): AgentLoweringInputs["run"];
|
|
106
|
+
export declare function projectAgentContext(spec: AgentSpec): AgentLoweringInputs["context"];
|
|
107
|
+
export declare function projectAgentCapabilities(spec: AgentSpec): AgentLoweringInputs["capabilities"];
|
|
108
|
+
export declare function projectAgentGovernance(spec: AgentSpec): AgentLoweringInputs["governance"];
|
|
109
|
+
export declare function projectAgentDelegation(spec: AgentSpec): AgentLoweringInputs["delegation"];
|
package/dist/agent-ir.js
CHANGED
|
@@ -37,7 +37,7 @@ export function normalizeAgent(agent) {
|
|
|
37
37
|
return agent;
|
|
38
38
|
const tools = agent.tools?.map(tool => isRegisteredTool(tool) ? tool : toolDefinitionToRegisteredTool(tool));
|
|
39
39
|
const { tools: _rawTools, ...options } = agent;
|
|
40
|
-
return new Agent({ ...options, ...(tools ? { tools } : {}) });
|
|
40
|
+
return new Agent({ ...options, name: options.name ?? "agent", ...(tools ? { tools } : {}) });
|
|
41
41
|
}
|
|
42
42
|
function lowerTool(tool) {
|
|
43
43
|
let parameters;
|
|
@@ -88,17 +88,7 @@ export function lowerAgent(agent) {
|
|
|
88
88
|
const guardrails = clone(agent.guardrails ?? []);
|
|
89
89
|
const memory = lowerMemory(agent.memory);
|
|
90
90
|
const extensions = clone(agent.providerOptions ?? {});
|
|
91
|
-
const capabilities = [
|
|
92
|
-
...tools.map(tool => ({ kind: "tool", id: tool.name, description: tool.description })),
|
|
93
|
-
...mcpServers.map(server => ({
|
|
94
|
-
kind: "mcp_server",
|
|
95
|
-
id: server.name ?? server.transport.kind,
|
|
96
|
-
description: server.name ?? `${server.transport.kind} MCP server`,
|
|
97
|
-
})),
|
|
98
|
-
...skills.map(skill => ({ kind: "skill", id: skill.name, description: skill.description ?? "" })),
|
|
99
|
-
];
|
|
100
91
|
const capabilityFilter = agent.capabilityFilter ? clone(agent.capabilityFilter) : undefined;
|
|
101
|
-
const effectiveCapabilities = capabilities.filter(capability => capabilityAllowed(capability, capabilityFilter));
|
|
102
92
|
return {
|
|
103
93
|
name: agent.name,
|
|
104
94
|
...(agent.description ? { description: agent.description } : {}),
|
|
@@ -113,22 +103,48 @@ export function lowerAgent(agent) {
|
|
|
113
103
|
...(handoffs.length ? { handoffs } : {}),
|
|
114
104
|
...(guardrails.length ? { guardrails } : {}),
|
|
115
105
|
...(agent.metadata ? { metadata: clone(agent.metadata) } : {}),
|
|
116
|
-
capabilities,
|
|
106
|
+
get capabilities() { return declaredCapabilities(this); },
|
|
117
107
|
...(capabilityFilter ? { capabilityFilter } : {}),
|
|
118
|
-
effectiveCapabilities
|
|
119
|
-
|
|
120
|
-
inputs: {
|
|
121
|
-
run: { name: agent.name, ...(agent.model ? { model: clone(agent.model) } : {}) },
|
|
122
|
-
context: {
|
|
123
|
-
...(agent.description ? { description: agent.description } : {}),
|
|
124
|
-
...(agent.instructions ? { instructions: agent.instructions } : {}),
|
|
125
|
-
...(agent.outputSchema ? { outputSchema: clone(agent.outputSchema) } : {}),
|
|
126
|
-
knowledge,
|
|
127
|
-
},
|
|
128
|
-
capabilities: { tools, mcpServers, skills, effective: effectiveCapabilities },
|
|
129
|
-
...(memory ? { memory } : {}),
|
|
130
|
-
delegation: { handoffs },
|
|
131
|
-
governance: { guardrails },
|
|
108
|
+
get effectiveCapabilities() {
|
|
109
|
+
return declaredCapabilities(this).filter(capability => capabilityAllowed(capability, this.capabilityFilter));
|
|
132
110
|
},
|
|
111
|
+
extensions,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/** Detached projections; callers can adapt them without changing AgentSpec authority. */
|
|
115
|
+
export function projectAgentRun(spec) {
|
|
116
|
+
return { name: spec.name, ...(spec.model !== undefined ? { model: clone(spec.model) } : {}) };
|
|
117
|
+
}
|
|
118
|
+
export function projectAgentContext(spec) {
|
|
119
|
+
return {
|
|
120
|
+
...(spec.description !== undefined ? { description: spec.description } : {}),
|
|
121
|
+
...(spec.instructions !== undefined ? { instructions: spec.instructions } : {}),
|
|
122
|
+
...(spec.outputSchema !== undefined ? { outputSchema: clone(spec.outputSchema) } : {}),
|
|
123
|
+
knowledge: clone(spec.knowledge ?? []),
|
|
133
124
|
};
|
|
134
125
|
}
|
|
126
|
+
export function projectAgentCapabilities(spec) {
|
|
127
|
+
return {
|
|
128
|
+
tools: clone(spec.tools),
|
|
129
|
+
mcpServers: clone(spec.mcpServers ?? []),
|
|
130
|
+
skills: clone(spec.skills ?? []),
|
|
131
|
+
effective: clone(spec.effectiveCapabilities),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export function projectAgentGovernance(spec) {
|
|
135
|
+
return { guardrails: clone(spec.guardrails ?? []) };
|
|
136
|
+
}
|
|
137
|
+
export function projectAgentDelegation(spec) {
|
|
138
|
+
return { handoffs: clone(spec.handoffs ?? []) };
|
|
139
|
+
}
|
|
140
|
+
function declaredCapabilities(spec) {
|
|
141
|
+
return [
|
|
142
|
+
...spec.tools.map(tool => ({ kind: "tool", id: tool.name, description: tool.description })),
|
|
143
|
+
...(spec.mcpServers ?? []).map(server => ({
|
|
144
|
+
kind: "mcp_server",
|
|
145
|
+
id: server.name ?? server.transport.kind,
|
|
146
|
+
description: server.name ?? `${server.transport.kind} MCP server`,
|
|
147
|
+
})),
|
|
148
|
+
...(spec.skills ?? []).map(skill => ({ kind: "skill", id: skill.name, description: skill.description ?? "" })),
|
|
149
|
+
];
|
|
150
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPC-028-03: names that retain the Canonical prefix for ABI/runtime reasons.
|
|
3
|
+
* New provider-neutral types should use a domain and representation name instead.
|
|
4
|
+
*/
|
|
5
|
+
export declare const CANONICAL_PREFIX_ALLOWLIST: readonly ["CanonicalAdapterInput", "CanonicalCheckpoint", "CanonicalCommit", "CanonicalKernel", "CanonicalKernelHost", "CanonicalKernelInput", "CanonicalKernelInstance", "CanonicalKernelRebuildRequiredError", "CanonicalKernelRejectedError", "CanonicalMessage", "CanonicalMessageBlock", "CanonicalPlannedStep", "CanonicalPreparation", "CanonicalPrepared", "CanonicalRejected", "CanonicalRenderedContext", "CanonicalReplayed", "CanonicalRestoreCost", "CanonicalRunnerRuntime", "CanonicalRunnerRuntimeOptions", "CanonicalStopReason", "CanonicalToolResult", "CanonicalTransition", "CanonicalTransitionOptions"];
|
|
6
|
+
export type AllowedCanonicalPrefixName = typeof CANONICAL_PREFIX_ALLOWLIST[number];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPC-028-03: names that retain the Canonical prefix for ABI/runtime reasons.
|
|
3
|
+
* New provider-neutral types should use a domain and representation name instead.
|
|
4
|
+
*/
|
|
5
|
+
export const CANONICAL_PREFIX_ALLOWLIST = [
|
|
6
|
+
"CanonicalAdapterInput",
|
|
7
|
+
"CanonicalCheckpoint",
|
|
8
|
+
"CanonicalCommit",
|
|
9
|
+
"CanonicalKernel",
|
|
10
|
+
"CanonicalKernelHost",
|
|
11
|
+
"CanonicalKernelInput",
|
|
12
|
+
"CanonicalKernelInstance",
|
|
13
|
+
"CanonicalKernelRebuildRequiredError",
|
|
14
|
+
"CanonicalKernelRejectedError",
|
|
15
|
+
"CanonicalMessage",
|
|
16
|
+
"CanonicalMessageBlock",
|
|
17
|
+
"CanonicalPlannedStep",
|
|
18
|
+
"CanonicalPreparation",
|
|
19
|
+
"CanonicalPrepared",
|
|
20
|
+
"CanonicalRejected",
|
|
21
|
+
"CanonicalRenderedContext",
|
|
22
|
+
"CanonicalReplayed",
|
|
23
|
+
"CanonicalRestoreCost",
|
|
24
|
+
"CanonicalRunnerRuntime",
|
|
25
|
+
"CanonicalRunnerRuntimeOptions",
|
|
26
|
+
"CanonicalStopReason",
|
|
27
|
+
"CanonicalToolResult",
|
|
28
|
+
"CanonicalTransition",
|
|
29
|
+
"CanonicalTransitionOptions",
|
|
30
|
+
];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { decodeDurableContent, decodeDurableToolResult } from "./runtime/durable-content.js";
|
|
2
|
+
export { decodeCanonicalContentParts, encodeCanonicalContentParts } from "./runtime/kernel-step.js";
|
|
3
|
+
export { lowerAgent, normalizeAgent } from "./agent-ir.js";
|
|
4
|
+
export { SESSION_EVENT_KINDS } from "./runtime/session-log.js";
|
|
5
|
+
export { providerAttemptToRecord } from "./runtime/execution-evidence.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// SDK conformance harness surface. Kept separate from the public root so the
|
|
2
|
+
// executable SDK contract does not accidentally grow internal protocol exports.
|
|
3
|
+
export { decodeDurableContent, decodeDurableToolResult } from "./runtime/durable-content.js";
|
|
4
|
+
export { decodeCanonicalContentParts, encodeCanonicalContentParts } from "./runtime/kernel-step.js";
|
|
5
|
+
export { lowerAgent, normalizeAgent } from "./agent-ir.js";
|
|
6
|
+
export { SESSION_EVENT_KINDS } from "./runtime/session-log.js";
|
|
7
|
+
export { providerAttemptToRecord } from "./runtime/execution-evidence.js";
|