@contractspec/lib.ai-agent 0.0.0-canary-20260113162409
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/LICENSE +21 -0
- package/README.md +49 -0
- package/dist/_virtual/rolldown_runtime.js +8 -0
- package/dist/agent/agent-factory.d.ts +104 -0
- package/dist/agent/agent-factory.d.ts.map +1 -0
- package/dist/agent/agent-factory.js +103 -0
- package/dist/agent/agent-factory.js.map +1 -0
- package/dist/agent/contract-spec-agent.d.ts +75 -0
- package/dist/agent/contract-spec-agent.d.ts.map +1 -0
- package/dist/agent/contract-spec-agent.js +148 -0
- package/dist/agent/contract-spec-agent.js.map +1 -0
- package/dist/agent/index.d.ts +3 -0
- package/dist/agent/index.js +4 -0
- package/dist/agent/unified-agent.d.ts +131 -0
- package/dist/agent/unified-agent.d.ts.map +1 -0
- package/dist/agent/unified-agent.js +267 -0
- package/dist/agent/unified-agent.js.map +1 -0
- package/dist/approval/index.d.ts +2 -0
- package/dist/approval/index.js +3 -0
- package/dist/approval/workflow.d.ts +156 -0
- package/dist/approval/workflow.d.ts.map +1 -0
- package/dist/approval/workflow.js +160 -0
- package/dist/approval/workflow.js.map +1 -0
- package/dist/exporters/claude-agent-exporter.d.ts +64 -0
- package/dist/exporters/claude-agent-exporter.d.ts.map +1 -0
- package/dist/exporters/claude-agent-exporter.js +210 -0
- package/dist/exporters/claude-agent-exporter.js.map +1 -0
- package/dist/exporters/index.d.ts +4 -0
- package/dist/exporters/index.js +4 -0
- package/dist/exporters/opencode-exporter.d.ts +64 -0
- package/dist/exporters/opencode-exporter.d.ts.map +1 -0
- package/dist/exporters/opencode-exporter.js +200 -0
- package/dist/exporters/opencode-exporter.js.map +1 -0
- package/dist/exporters/types.d.ts +239 -0
- package/dist/exporters/types.d.ts.map +1 -0
- package/dist/exporters/types.js +0 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +31 -0
- package/dist/interop/index.d.ts +4 -0
- package/dist/interop/index.js +4 -0
- package/dist/interop/spec-consumer.d.ts +81 -0
- package/dist/interop/spec-consumer.d.ts.map +1 -0
- package/dist/interop/spec-consumer.js +287 -0
- package/dist/interop/spec-consumer.js.map +1 -0
- package/dist/interop/tool-consumer.d.ts +68 -0
- package/dist/interop/tool-consumer.d.ts.map +1 -0
- package/dist/interop/tool-consumer.js +220 -0
- package/dist/interop/tool-consumer.js.map +1 -0
- package/dist/interop/types.d.ts +262 -0
- package/dist/interop/types.d.ts.map +1 -0
- package/dist/interop/types.js +0 -0
- package/dist/knowledge/index.d.ts +2 -0
- package/dist/knowledge/index.js +3 -0
- package/dist/knowledge/injector.d.ts +38 -0
- package/dist/knowledge/injector.d.ts.map +1 -0
- package/dist/knowledge/injector.js +58 -0
- package/dist/knowledge/injector.js.map +1 -0
- package/dist/memory/in-memory.d.ts +22 -0
- package/dist/memory/in-memory.d.ts.map +1 -0
- package/dist/memory/in-memory.js +48 -0
- package/dist/memory/in-memory.js.map +1 -0
- package/dist/memory/index.d.ts +3 -0
- package/dist/memory/index.js +4 -0
- package/dist/memory/manager.d.ts +42 -0
- package/dist/memory/manager.d.ts.map +1 -0
- package/dist/memory/manager.js +80 -0
- package/dist/memory/manager.js.map +1 -0
- package/dist/providers/claude-agent-sdk/adapter.d.ts +58 -0
- package/dist/providers/claude-agent-sdk/adapter.d.ts.map +1 -0
- package/dist/providers/claude-agent-sdk/adapter.js +306 -0
- package/dist/providers/claude-agent-sdk/adapter.js.map +1 -0
- package/dist/providers/claude-agent-sdk/index.d.ts +4 -0
- package/dist/providers/claude-agent-sdk/index.js +5 -0
- package/dist/providers/claude-agent-sdk/session-bridge.d.ts +101 -0
- package/dist/providers/claude-agent-sdk/session-bridge.d.ts.map +1 -0
- package/dist/providers/claude-agent-sdk/session-bridge.js +158 -0
- package/dist/providers/claude-agent-sdk/session-bridge.js.map +1 -0
- package/dist/providers/claude-agent-sdk/tool-bridge.d.ts +110 -0
- package/dist/providers/claude-agent-sdk/tool-bridge.d.ts.map +1 -0
- package/dist/providers/claude-agent-sdk/tool-bridge.js +122 -0
- package/dist/providers/claude-agent-sdk/tool-bridge.js.map +1 -0
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/opencode-sdk/adapter.d.ts +54 -0
- package/dist/providers/opencode-sdk/adapter.d.ts.map +1 -0
- package/dist/providers/opencode-sdk/adapter.js +276 -0
- package/dist/providers/opencode-sdk/adapter.js.map +1 -0
- package/dist/providers/opencode-sdk/agent-bridge.d.ts +94 -0
- package/dist/providers/opencode-sdk/agent-bridge.d.ts.map +1 -0
- package/dist/providers/opencode-sdk/agent-bridge.js +165 -0
- package/dist/providers/opencode-sdk/agent-bridge.js.map +1 -0
- package/dist/providers/opencode-sdk/index.d.ts +4 -0
- package/dist/providers/opencode-sdk/index.js +5 -0
- package/dist/providers/opencode-sdk/tool-bridge.d.ts +81 -0
- package/dist/providers/opencode-sdk/tool-bridge.d.ts.map +1 -0
- package/dist/providers/opencode-sdk/tool-bridge.js +127 -0
- package/dist/providers/opencode-sdk/tool-bridge.js.map +1 -0
- package/dist/providers/registry.d.ts +22 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +52 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/types.d.ts +243 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +44 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.js +4 -0
- package/dist/schema/json-schema-to-zod.d.ts +55 -0
- package/dist/schema/json-schema-to-zod.d.ts.map +1 -0
- package/dist/schema/json-schema-to-zod.js +124 -0
- package/dist/schema/json-schema-to-zod.js.map +1 -0
- package/dist/schema/schema-output.d.ts +77 -0
- package/dist/schema/schema-output.d.ts.map +1 -0
- package/dist/schema/schema-output.js +65 -0
- package/dist/schema/schema-output.js.map +1 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +3 -0
- package/dist/session/store.d.ts +74 -0
- package/dist/session/store.d.ts.map +1 -0
- package/dist/session/store.js +79 -0
- package/dist/session/store.js.map +1 -0
- package/dist/spec/index.d.ts +3 -0
- package/dist/spec/index.js +4 -0
- package/dist/spec/registry.d.ts +47 -0
- package/dist/spec/registry.d.ts.map +1 -0
- package/dist/spec/registry.js +65 -0
- package/dist/spec/registry.js.map +1 -0
- package/dist/spec/spec.d.ts +127 -0
- package/dist/spec/spec.d.ts.map +1 -0
- package/dist/spec/spec.js +30 -0
- package/dist/spec/spec.js.map +1 -0
- package/dist/telemetry/adapter.d.ts +73 -0
- package/dist/telemetry/adapter.d.ts.map +1 -0
- package/dist/telemetry/adapter.js +103 -0
- package/dist/telemetry/adapter.js.map +1 -0
- package/dist/telemetry/index.d.ts +2 -0
- package/dist/telemetry/index.js +3 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/knowledge-tool.d.ts +21 -0
- package/dist/tools/knowledge-tool.d.ts.map +1 -0
- package/dist/tools/knowledge-tool.js +54 -0
- package/dist/tools/knowledge-tool.js.map +1 -0
- package/dist/tools/mcp-client.d.ts +59 -0
- package/dist/tools/mcp-client.d.ts.map +1 -0
- package/dist/tools/mcp-client.js +58 -0
- package/dist/tools/mcp-client.js.map +1 -0
- package/dist/tools/mcp-server.d.ts +46 -0
- package/dist/tools/mcp-server.d.ts.map +1 -0
- package/dist/tools/mcp-server.js +69 -0
- package/dist/tools/mcp-server.js.map +1 -0
- package/dist/tools/tool-adapter.d.ts +50 -0
- package/dist/tools/tool-adapter.d.ts.map +1 -0
- package/dist/tools/tool-adapter.js +80 -0
- package/dist/tools/tool-adapter.js.map +1 -0
- package/dist/types.d.ts +146 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +0 -0
- package/package.json +155 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { AgentSpec } from "../spec/spec.js";
|
|
2
|
+
import { AgentCallOptions, AgentGenerateResult, ToolHandler } from "../types.js";
|
|
3
|
+
import { ClaudeAgentSDKConfig, OpenCodeSDKConfig } from "../providers/types.js";
|
|
4
|
+
|
|
5
|
+
//#region src/agent/unified-agent.d.ts
|
|
6
|
+
|
|
7
|
+
/** Supported backend types */
|
|
8
|
+
type UnifiedAgentBackend = 'ai-sdk' | 'claude-agent-sdk' | 'opencode-sdk';
|
|
9
|
+
/** Backend-specific configuration */
|
|
10
|
+
interface UnifiedAgentBackendConfig {
|
|
11
|
+
'ai-sdk'?: {
|
|
12
|
+
model?: string;
|
|
13
|
+
temperature?: number;
|
|
14
|
+
maxTokens?: number;
|
|
15
|
+
};
|
|
16
|
+
'claude-agent-sdk'?: ClaudeAgentSDKConfig;
|
|
17
|
+
'opencode-sdk'?: OpenCodeSDKConfig;
|
|
18
|
+
}
|
|
19
|
+
/** Unified agent configuration */
|
|
20
|
+
interface UnifiedAgentConfig {
|
|
21
|
+
/** Backend to use */
|
|
22
|
+
backend: UnifiedAgentBackend;
|
|
23
|
+
/** Backend-specific configuration */
|
|
24
|
+
config?: UnifiedAgentBackendConfig[UnifiedAgentBackend];
|
|
25
|
+
/** Tool handlers for the agent */
|
|
26
|
+
tools?: Map<string, ToolHandler>;
|
|
27
|
+
/** Fallback backend if primary fails */
|
|
28
|
+
fallbackBackend?: UnifiedAgentBackend;
|
|
29
|
+
/** Enable verbose logging */
|
|
30
|
+
verbose?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** Unified agent run options */
|
|
33
|
+
interface UnifiedAgentRunOptions extends AgentCallOptions {
|
|
34
|
+
/** Override backend for this call */
|
|
35
|
+
backend?: UnifiedAgentBackend;
|
|
36
|
+
}
|
|
37
|
+
/** Unified agent state */
|
|
38
|
+
interface UnifiedAgentState {
|
|
39
|
+
backend: UnifiedAgentBackend;
|
|
40
|
+
isReady: boolean;
|
|
41
|
+
sessionId?: string;
|
|
42
|
+
messageCount: number;
|
|
43
|
+
lastError?: Error;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Unified agent that works across multiple backends.
|
|
47
|
+
*/
|
|
48
|
+
declare class UnifiedAgent {
|
|
49
|
+
private readonly spec;
|
|
50
|
+
private readonly config;
|
|
51
|
+
private readonly tools;
|
|
52
|
+
private provider?;
|
|
53
|
+
private context?;
|
|
54
|
+
private state;
|
|
55
|
+
constructor(spec: AgentSpec, config: UnifiedAgentConfig);
|
|
56
|
+
/**
|
|
57
|
+
* Initialize the agent with its backend.
|
|
58
|
+
*/
|
|
59
|
+
initialize(): Promise<void>;
|
|
60
|
+
private initializeClaudeAgentSDK;
|
|
61
|
+
private initializeOpenCodeSDK;
|
|
62
|
+
/**
|
|
63
|
+
* Run the agent with a message.
|
|
64
|
+
*/
|
|
65
|
+
run(message: string, options?: UnifiedAgentRunOptions): Promise<AgentGenerateResult>;
|
|
66
|
+
private runWithAISDK;
|
|
67
|
+
private runWithExternalProvider;
|
|
68
|
+
private convertExternalResult;
|
|
69
|
+
/**
|
|
70
|
+
* Get agent state.
|
|
71
|
+
*/
|
|
72
|
+
getState(): UnifiedAgentState;
|
|
73
|
+
/**
|
|
74
|
+
* Get the agent spec.
|
|
75
|
+
*/
|
|
76
|
+
getSpec(): AgentSpec;
|
|
77
|
+
/**
|
|
78
|
+
* Get the current backend.
|
|
79
|
+
*/
|
|
80
|
+
getBackend(): UnifiedAgentBackend;
|
|
81
|
+
/**
|
|
82
|
+
* Check if a specific backend is available.
|
|
83
|
+
*/
|
|
84
|
+
isBackendAvailable(backend: UnifiedAgentBackend): Promise<boolean>;
|
|
85
|
+
/**
|
|
86
|
+
* Switch to a different backend.
|
|
87
|
+
*/
|
|
88
|
+
switchBackend(backend: UnifiedAgentBackend): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Reset the agent state.
|
|
91
|
+
*/
|
|
92
|
+
reset(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Add a tool handler.
|
|
95
|
+
*/
|
|
96
|
+
addTool(name: string, handler: ToolHandler): void;
|
|
97
|
+
/**
|
|
98
|
+
* Remove a tool handler.
|
|
99
|
+
*/
|
|
100
|
+
removeTool(name: string): boolean;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create a unified agent.
|
|
104
|
+
*/
|
|
105
|
+
declare function createUnifiedAgent(spec: AgentSpec, config: UnifiedAgentConfig): UnifiedAgent;
|
|
106
|
+
/**
|
|
107
|
+
* Create a unified agent with AI SDK backend (default).
|
|
108
|
+
*/
|
|
109
|
+
declare function createAISDKAgent(spec: AgentSpec, options?: {
|
|
110
|
+
tools?: Map<string, ToolHandler>;
|
|
111
|
+
model?: string;
|
|
112
|
+
}): UnifiedAgent;
|
|
113
|
+
/**
|
|
114
|
+
* Create a unified agent with Claude Agent SDK backend.
|
|
115
|
+
*/
|
|
116
|
+
declare function createClaudeAgentSDKAgent(spec: AgentSpec, config?: ClaudeAgentSDKConfig & {
|
|
117
|
+
tools?: Map<string, ToolHandler>;
|
|
118
|
+
}): UnifiedAgent;
|
|
119
|
+
/**
|
|
120
|
+
* Create a unified agent with OpenCode SDK backend.
|
|
121
|
+
*/
|
|
122
|
+
declare function createOpenCodeSDKAgent(spec: AgentSpec, config?: OpenCodeSDKConfig & {
|
|
123
|
+
tools?: Map<string, ToolHandler>;
|
|
124
|
+
}): UnifiedAgent;
|
|
125
|
+
/**
|
|
126
|
+
* Get available backends.
|
|
127
|
+
*/
|
|
128
|
+
declare function getAvailableBackends(): Promise<UnifiedAgentBackend[]>;
|
|
129
|
+
//#endregion
|
|
130
|
+
export { UnifiedAgent, UnifiedAgentBackend, UnifiedAgentBackendConfig, UnifiedAgentConfig, UnifiedAgentRunOptions, UnifiedAgentState, createAISDKAgent, createClaudeAgentSDKAgent, createOpenCodeSDKAgent, createUnifiedAgent, getAvailableBackends };
|
|
131
|
+
//# sourceMappingURL=unified-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unified-agent.d.ts","names":[],"sources":["../../src/agent/unified-agent.ts"],"sourcesContent":[],"mappings":";;;;;;;AAoZiC,KAtWrB,mBAAA,GAsWqB,QAAA,GAAA,kBAAA,GAAA,cAAA;;AAmBjB,UAnXC,yBAAA,CAmXiB;EAC1B,QAAA,CAAA,EAAA;IACE,KAAA,CAAA,EAAA,MAAA;IACP,WAAA,CAAA,EAAA,MAAA;IAAY,SAAA,CAAA,EAAA,MAAA;EAOC,CAAA;EACR,kBAAA,CAAA,EAxXe,oBAwXf;EAEgB,cAAA,CAAA,EAzXL,iBAyXK;;;AAGT,UAxXE,kBAAA,CAwXF;EAWC;EACR,OAAA,EAlYG,mBAkYH;EACG;EACa,MAAA,CAAA,EAlYb,yBAkYa,CAlYa,mBAkYb,CAAA;EAAZ;EAET,KAAA,CAAA,EAlYO,GAkYP,CAAA,MAAA,EAlYmB,WAkYnB,CAAA;EAAY;EAYC,eAAA,CAAA,EA5YI,mBA4YkB;EAC9B;EACG,OAAA,CAAA,EAAA,OAAA;;;AAGR,UA3Yc,sBAAA,SAA+B,gBA2Y7C,CAAA;EAAY;EAYO,OAAA,CAAA,EArZV,mBAqZ8B;;;UAjZzB,iBAAA;WACN;;;;cAIG;;;;;cAUD,YAAA;;;;;;;oBAQO,mBAAmB;;;;gBAcjB;;;;;;iCA+FR,yBACT,QAAQ;;;;;;;cA4GC;;;;aAOD;;;;gBAOG;;;;8BAOoB,sBAAsB;;;;yBAiC3B,sBAAsB;;;;;;;;iCA0BpB;;;;;;;;;iBAmBjB,kBAAA,OACR,mBACE,qBACP;;;;iBAOa,gBAAA,OACR;UAEI,YAAY;;IAGrB;;;;iBAWa,yBAAA,OACR,oBACG;UACC,YAAY;IAErB;;;;iBAYa,sBAAA,OACR,oBACG;UACC,YAAY;IAErB;;;;iBAYmB,oBAAA,CAAA,GAAwB,QAAQ"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
//#region src/agent/unified-agent.ts
|
|
2
|
+
/**
|
|
3
|
+
* Unified agent that works across multiple backends.
|
|
4
|
+
*/
|
|
5
|
+
var UnifiedAgent = class {
|
|
6
|
+
spec;
|
|
7
|
+
config;
|
|
8
|
+
tools;
|
|
9
|
+
provider;
|
|
10
|
+
context;
|
|
11
|
+
state;
|
|
12
|
+
constructor(spec, config) {
|
|
13
|
+
this.spec = spec;
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.tools = config.tools ?? /* @__PURE__ */ new Map();
|
|
16
|
+
this.state = {
|
|
17
|
+
backend: config.backend,
|
|
18
|
+
isReady: false,
|
|
19
|
+
messageCount: 0
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Initialize the agent with its backend.
|
|
24
|
+
*/
|
|
25
|
+
async initialize() {
|
|
26
|
+
const backend = this.config.backend;
|
|
27
|
+
try {
|
|
28
|
+
switch (backend) {
|
|
29
|
+
case "ai-sdk":
|
|
30
|
+
this.state.isReady = true;
|
|
31
|
+
break;
|
|
32
|
+
case "claude-agent-sdk":
|
|
33
|
+
await this.initializeClaudeAgentSDK();
|
|
34
|
+
break;
|
|
35
|
+
case "opencode-sdk":
|
|
36
|
+
await this.initializeOpenCodeSDK();
|
|
37
|
+
break;
|
|
38
|
+
default: throw new Error(`Unknown backend: ${backend}`);
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
this.state.lastError = error instanceof Error ? error : new Error(String(error));
|
|
42
|
+
if (this.config.fallbackBackend && this.config.fallbackBackend !== backend) {
|
|
43
|
+
console.warn(`[UnifiedAgent] ${backend} failed, falling back to ${this.config.fallbackBackend}`);
|
|
44
|
+
this.state.backend = this.config.fallbackBackend;
|
|
45
|
+
await this.initialize();
|
|
46
|
+
} else throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async initializeClaudeAgentSDK() {
|
|
50
|
+
try {
|
|
51
|
+
const { ClaudeAgentSDKProvider } = await import("../providers/claude-agent-sdk/index.js");
|
|
52
|
+
const config = this.config.config;
|
|
53
|
+
this.provider = new ClaudeAgentSDKProvider(config ?? {});
|
|
54
|
+
if (!this.provider.isAvailable()) throw new Error("Claude Agent SDK not available. Install @anthropic-ai/claude-agent-sdk");
|
|
55
|
+
this.context = await this.provider.createContext(this.spec);
|
|
56
|
+
this.state.isReady = true;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (error.code === "MODULE_NOT_FOUND") throw new Error("Claude Agent SDK not installed. Run: npm install @anthropic-ai/claude-agent-sdk");
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async initializeOpenCodeSDK() {
|
|
63
|
+
try {
|
|
64
|
+
const { OpenCodeSDKProvider } = await import("../providers/opencode-sdk/index.js");
|
|
65
|
+
const config = this.config.config;
|
|
66
|
+
this.provider = new OpenCodeSDKProvider(config ?? {});
|
|
67
|
+
if (!this.provider.isAvailable()) throw new Error("OpenCode SDK not available. Install @opencode-ai/sdk");
|
|
68
|
+
this.context = await this.provider.createContext(this.spec);
|
|
69
|
+
this.state.isReady = true;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error.code === "MODULE_NOT_FOUND") throw new Error("OpenCode SDK not installed. Run: npm install @opencode-ai/sdk");
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Run the agent with a message.
|
|
77
|
+
*/
|
|
78
|
+
async run(message, options) {
|
|
79
|
+
if (!this.state.isReady) await this.initialize();
|
|
80
|
+
const backend = options?.backend ?? this.state.backend;
|
|
81
|
+
this.state.messageCount++;
|
|
82
|
+
try {
|
|
83
|
+
switch (backend) {
|
|
84
|
+
case "ai-sdk": return await this.runWithAISDK(message, options);
|
|
85
|
+
case "claude-agent-sdk":
|
|
86
|
+
case "opencode-sdk": return await this.runWithExternalProvider(message, options);
|
|
87
|
+
default: throw new Error(`Unknown backend: ${backend}`);
|
|
88
|
+
}
|
|
89
|
+
} catch (error) {
|
|
90
|
+
this.state.lastError = error instanceof Error ? error : new Error(String(error));
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async runWithAISDK(message, options) {
|
|
95
|
+
const { ContractSpecAgent } = await import("./contract-spec-agent.js");
|
|
96
|
+
const { anthropic } = await import("@ai-sdk/anthropic");
|
|
97
|
+
const backendConfig = this.config.backend === "ai-sdk" ? this.config.config : {};
|
|
98
|
+
return await (await ContractSpecAgent.create({
|
|
99
|
+
spec: this.spec,
|
|
100
|
+
model: anthropic(backendConfig?.model ?? "claude-3-5-sonnet-20240620"),
|
|
101
|
+
toolHandlers: this.tools
|
|
102
|
+
})).generate({
|
|
103
|
+
prompt: message,
|
|
104
|
+
options
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
async runWithExternalProvider(message, options) {
|
|
108
|
+
if (!this.provider || !this.context) throw new Error("Provider not initialized");
|
|
109
|
+
const result = await this.provider.execute(this.context, {
|
|
110
|
+
prompt: message,
|
|
111
|
+
options
|
|
112
|
+
});
|
|
113
|
+
return this.convertExternalResult(result);
|
|
114
|
+
}
|
|
115
|
+
convertExternalResult(result) {
|
|
116
|
+
return {
|
|
117
|
+
text: result.text,
|
|
118
|
+
steps: [],
|
|
119
|
+
toolCalls: result.toolCalls.map((tc) => ({
|
|
120
|
+
type: "tool-call",
|
|
121
|
+
toolCallId: tc.toolCallId,
|
|
122
|
+
toolName: tc.toolName,
|
|
123
|
+
args: tc.args
|
|
124
|
+
})),
|
|
125
|
+
toolResults: result.toolResults.map((tr) => ({
|
|
126
|
+
type: "tool-result",
|
|
127
|
+
toolCallId: tr.toolCallId,
|
|
128
|
+
toolName: tr.toolName,
|
|
129
|
+
output: tr.output
|
|
130
|
+
})),
|
|
131
|
+
finishReason: result.finishReason,
|
|
132
|
+
usage: result.usage ? {
|
|
133
|
+
promptTokens: result.usage.inputTokens,
|
|
134
|
+
completionTokens: result.usage.outputTokens,
|
|
135
|
+
totalTokens: result.usage.totalTokens ?? result.usage.inputTokens + result.usage.outputTokens
|
|
136
|
+
} : void 0
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get agent state.
|
|
141
|
+
*/
|
|
142
|
+
getState() {
|
|
143
|
+
return { ...this.state };
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get the agent spec.
|
|
147
|
+
*/
|
|
148
|
+
getSpec() {
|
|
149
|
+
return this.spec;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get the current backend.
|
|
153
|
+
*/
|
|
154
|
+
getBackend() {
|
|
155
|
+
return this.state.backend;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if a specific backend is available.
|
|
159
|
+
*/
|
|
160
|
+
async isBackendAvailable(backend) {
|
|
161
|
+
switch (backend) {
|
|
162
|
+
case "ai-sdk": return true;
|
|
163
|
+
case "claude-agent-sdk": try {
|
|
164
|
+
const { ClaudeAgentSDKProvider } = await import("../providers/claude-agent-sdk/index.js");
|
|
165
|
+
return new ClaudeAgentSDKProvider({}).isAvailable();
|
|
166
|
+
} catch {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
case "opencode-sdk": try {
|
|
170
|
+
const { OpenCodeSDKProvider } = await import("../providers/opencode-sdk/index.js");
|
|
171
|
+
return new OpenCodeSDKProvider({}).isAvailable();
|
|
172
|
+
} catch {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
default: return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Switch to a different backend.
|
|
180
|
+
*/
|
|
181
|
+
async switchBackend(backend) {
|
|
182
|
+
if (backend === this.state.backend) return;
|
|
183
|
+
this.state.backend = backend;
|
|
184
|
+
this.state.isReady = false;
|
|
185
|
+
this.provider = void 0;
|
|
186
|
+
this.context = void 0;
|
|
187
|
+
await this.initialize();
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Reset the agent state.
|
|
191
|
+
*/
|
|
192
|
+
reset() {
|
|
193
|
+
this.state.messageCount = 0;
|
|
194
|
+
this.state.sessionId = void 0;
|
|
195
|
+
this.state.lastError = void 0;
|
|
196
|
+
this.context = void 0;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Add a tool handler.
|
|
200
|
+
*/
|
|
201
|
+
addTool(name, handler) {
|
|
202
|
+
this.tools.set(name, handler);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Remove a tool handler.
|
|
206
|
+
*/
|
|
207
|
+
removeTool(name) {
|
|
208
|
+
return this.tools.delete(name);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Create a unified agent.
|
|
213
|
+
*/
|
|
214
|
+
function createUnifiedAgent(spec, config) {
|
|
215
|
+
return new UnifiedAgent(spec, config);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Create a unified agent with AI SDK backend (default).
|
|
219
|
+
*/
|
|
220
|
+
function createAISDKAgent(spec, options) {
|
|
221
|
+
return new UnifiedAgent(spec, {
|
|
222
|
+
backend: "ai-sdk",
|
|
223
|
+
tools: options?.tools,
|
|
224
|
+
config: { model: options?.model }
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Create a unified agent with Claude Agent SDK backend.
|
|
229
|
+
*/
|
|
230
|
+
function createClaudeAgentSDKAgent(spec, config) {
|
|
231
|
+
const { tools, ...sdkConfig } = config ?? {};
|
|
232
|
+
return new UnifiedAgent(spec, {
|
|
233
|
+
backend: "claude-agent-sdk",
|
|
234
|
+
tools,
|
|
235
|
+
config: sdkConfig
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Create a unified agent with OpenCode SDK backend.
|
|
240
|
+
*/
|
|
241
|
+
function createOpenCodeSDKAgent(spec, config) {
|
|
242
|
+
const { tools, ...sdkConfig } = config ?? {};
|
|
243
|
+
return new UnifiedAgent(spec, {
|
|
244
|
+
backend: "opencode-sdk",
|
|
245
|
+
tools,
|
|
246
|
+
config: sdkConfig
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Get available backends.
|
|
251
|
+
*/
|
|
252
|
+
async function getAvailableBackends() {
|
|
253
|
+
const backends = ["ai-sdk"];
|
|
254
|
+
try {
|
|
255
|
+
const { ClaudeAgentSDKProvider } = await import("../providers/claude-agent-sdk/index.js");
|
|
256
|
+
if (new ClaudeAgentSDKProvider({}).isAvailable()) backends.push("claude-agent-sdk");
|
|
257
|
+
} catch {}
|
|
258
|
+
try {
|
|
259
|
+
const { OpenCodeSDKProvider } = await import("../providers/opencode-sdk/index.js");
|
|
260
|
+
if (new OpenCodeSDKProvider({}).isAvailable()) backends.push("opencode-sdk");
|
|
261
|
+
} catch {}
|
|
262
|
+
return backends;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
//#endregion
|
|
266
|
+
export { UnifiedAgent, createAISDKAgent, createClaudeAgentSDKAgent, createOpenCodeSDKAgent, createUnifiedAgent, getAvailableBackends };
|
|
267
|
+
//# sourceMappingURL=unified-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unified-agent.js","names":[],"sources":["../../src/agent/unified-agent.ts"],"sourcesContent":["/**\n * Unified Agent Wrapper\n *\n * Provides a single API surface for running agents regardless of backend:\n * - AI SDK v6 (existing ContractSpec implementation)\n * - Claude Agent SDK (@anthropic-ai/claude-agent-sdk)\n * - OpenCode SDK (@opencode-ai/sdk)\n *\n * @example\n * ```typescript\n * import { UnifiedAgent, createUnifiedAgent } from '@contractspec/lib.ai-agent';\n *\n * // Create agent with AI SDK backend (default)\n * const agent = createUnifiedAgent(mySpec, {\n * backend: 'ai-sdk',\n * });\n *\n * // Create agent with Claude Agent SDK backend\n * const claudeAgent = createUnifiedAgent(mySpec, {\n * backend: 'claude-agent-sdk',\n * config: { extendedThinking: true },\n * });\n *\n * // All agents use the same API\n * const response = await agent.run('Hello');\n * ```\n */\nimport type { AgentSpec } from '../spec/spec';\nimport type {\n AgentCallOptions,\n AgentGenerateResult,\n ToolHandler,\n LanguageModelUsage,\n} from '../types';\nimport type {\n ExternalAgentProvider,\n ClaudeAgentSDKConfig,\n OpenCodeSDKConfig,\n ExternalExecuteResult,\n} from '../providers/types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** Supported backend types */\nexport type UnifiedAgentBackend =\n | 'ai-sdk'\n | 'claude-agent-sdk'\n | 'opencode-sdk';\n\n/** Backend-specific configuration */\nexport interface UnifiedAgentBackendConfig {\n 'ai-sdk'?: {\n model?: string;\n temperature?: number;\n maxTokens?: number;\n };\n 'claude-agent-sdk'?: ClaudeAgentSDKConfig;\n 'opencode-sdk'?: OpenCodeSDKConfig;\n}\n\n/** Unified agent configuration */\nexport interface UnifiedAgentConfig {\n /** Backend to use */\n backend: UnifiedAgentBackend;\n /** Backend-specific configuration */\n config?: UnifiedAgentBackendConfig[UnifiedAgentBackend];\n /** Tool handlers for the agent */\n tools?: Map<string, ToolHandler>;\n /** Fallback backend if primary fails */\n fallbackBackend?: UnifiedAgentBackend;\n /** Enable verbose logging */\n verbose?: boolean;\n}\n\n/** Unified agent run options */\nexport interface UnifiedAgentRunOptions extends AgentCallOptions {\n /** Override backend for this call */\n backend?: UnifiedAgentBackend;\n}\n\n/** Unified agent state */\nexport interface UnifiedAgentState {\n backend: UnifiedAgentBackend;\n isReady: boolean;\n sessionId?: string;\n messageCount: number;\n lastError?: Error;\n}\n\n// =============================================================================\n// Unified Agent Implementation\n// =============================================================================\n\n/**\n * Unified agent that works across multiple backends.\n */\nexport class UnifiedAgent {\n private readonly spec: AgentSpec;\n private readonly config: UnifiedAgentConfig;\n private readonly tools: Map<string, ToolHandler>;\n private provider?: ExternalAgentProvider;\n private context?: unknown;\n private state: UnifiedAgentState;\n\n constructor(spec: AgentSpec, config: UnifiedAgentConfig) {\n this.spec = spec;\n this.config = config;\n this.tools = config.tools ?? new Map();\n this.state = {\n backend: config.backend,\n isReady: false,\n messageCount: 0,\n };\n }\n\n /**\n * Initialize the agent with its backend.\n */\n async initialize(): Promise<void> {\n const backend = this.config.backend;\n\n try {\n switch (backend) {\n case 'ai-sdk':\n // AI SDK is always available\n this.state.isReady = true;\n break;\n\n case 'claude-agent-sdk':\n await this.initializeClaudeAgentSDK();\n break;\n\n case 'opencode-sdk':\n await this.initializeOpenCodeSDK();\n break;\n\n default:\n throw new Error(`Unknown backend: ${backend}`);\n }\n } catch (error) {\n this.state.lastError =\n error instanceof Error ? error : new Error(String(error));\n\n // Try fallback if configured\n if (\n this.config.fallbackBackend &&\n this.config.fallbackBackend !== backend\n ) {\n console.warn(\n `[UnifiedAgent] ${backend} failed, falling back to ${this.config.fallbackBackend}`\n );\n this.state.backend = this.config.fallbackBackend;\n await this.initialize();\n } else {\n throw error;\n }\n }\n }\n\n private async initializeClaudeAgentSDK(): Promise<void> {\n // Dynamic import to avoid requiring the dependency\n try {\n const { ClaudeAgentSDKProvider } =\n await import('../providers/claude-agent-sdk');\n const config = this.config.config as ClaudeAgentSDKConfig | undefined;\n this.provider = new ClaudeAgentSDKProvider(config ?? {});\n\n if (!this.provider.isAvailable()) {\n throw new Error(\n 'Claude Agent SDK not available. Install @anthropic-ai/claude-agent-sdk'\n );\n }\n\n this.context = await this.provider.createContext(this.spec);\n this.state.isReady = true;\n } catch (error) {\n if ((error as { code?: string }).code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'Claude Agent SDK not installed. Run: npm install @anthropic-ai/claude-agent-sdk'\n );\n }\n throw error;\n }\n }\n\n private async initializeOpenCodeSDK(): Promise<void> {\n // Dynamic import to avoid requiring the dependency\n try {\n const { OpenCodeSDKProvider } = await import('../providers/opencode-sdk');\n const config = this.config.config as OpenCodeSDKConfig | undefined;\n this.provider = new OpenCodeSDKProvider(config ?? {});\n\n if (!this.provider.isAvailable()) {\n throw new Error('OpenCode SDK not available. Install @opencode-ai/sdk');\n }\n\n this.context = await this.provider.createContext(this.spec);\n this.state.isReady = true;\n } catch (error) {\n if ((error as { code?: string }).code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'OpenCode SDK not installed. Run: npm install @opencode-ai/sdk'\n );\n }\n throw error;\n }\n }\n\n /**\n * Run the agent with a message.\n */\n async run(\n message: string,\n options?: UnifiedAgentRunOptions\n ): Promise<AgentGenerateResult> {\n if (!this.state.isReady) {\n await this.initialize();\n }\n\n const backend = options?.backend ?? this.state.backend;\n this.state.messageCount++;\n\n try {\n switch (backend) {\n case 'ai-sdk':\n return await this.runWithAISDK(message, options);\n\n case 'claude-agent-sdk':\n case 'opencode-sdk':\n return await this.runWithExternalProvider(message, options);\n\n default:\n throw new Error(`Unknown backend: ${backend}`);\n }\n } catch (error) {\n this.state.lastError =\n error instanceof Error ? error : new Error(String(error));\n throw error;\n }\n }\n\n private async runWithAISDK(\n message: string,\n options?: UnifiedAgentRunOptions\n ): Promise<AgentGenerateResult> {\n // Import the existing ContractSpec agent factory\n const { ContractSpecAgent } = await import('./contract-spec-agent');\n const { anthropic } = await import('@ai-sdk/anthropic');\n\n // Use factory method create() instead of new\n const backendConfig =\n this.config.backend === 'ai-sdk'\n ? (this.config.config as Record<string, unknown>)\n : {};\n\n const agent = await ContractSpecAgent.create({\n spec: this.spec,\n model: anthropic(\n (backendConfig?.model as string) ?? 'claude-3-5-sonnet-20240620'\n ),\n toolHandlers: this.tools,\n });\n\n return await agent.generate({\n prompt: message,\n options,\n });\n }\n\n private async runWithExternalProvider(\n message: string,\n options?: UnifiedAgentRunOptions\n ): Promise<AgentGenerateResult> {\n if (!this.provider || !this.context) {\n throw new Error('Provider not initialized');\n }\n\n const result: ExternalExecuteResult = await this.provider.execute(\n this.context as Parameters<ExternalAgentProvider['execute']>[0],\n {\n prompt: message,\n options,\n }\n );\n\n return this.convertExternalResult(result);\n }\n\n private convertExternalResult(\n result: ExternalExecuteResult\n ): AgentGenerateResult {\n return {\n text: result.text,\n steps: [],\n toolCalls: result.toolCalls.map((tc) => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n args: tc.args,\n })),\n toolResults: result.toolResults.map((tr) => ({\n type: 'tool-result' as const,\n toolCallId: tr.toolCallId,\n toolName: tr.toolName,\n output: tr.output,\n })),\n finishReason: result.finishReason,\n usage: result.usage\n ? ({\n promptTokens: result.usage.inputTokens,\n completionTokens: result.usage.outputTokens,\n totalTokens:\n result.usage.totalTokens ??\n result.usage.inputTokens + result.usage.outputTokens,\n } as unknown as LanguageModelUsage)\n : undefined,\n };\n }\n\n /**\n * Get agent state.\n */\n getState(): UnifiedAgentState {\n return { ...this.state };\n }\n\n /**\n * Get the agent spec.\n */\n getSpec(): AgentSpec {\n return this.spec;\n }\n\n /**\n * Get the current backend.\n */\n getBackend(): UnifiedAgentBackend {\n return this.state.backend;\n }\n\n /**\n * Check if a specific backend is available.\n */\n async isBackendAvailable(backend: UnifiedAgentBackend): Promise<boolean> {\n switch (backend) {\n case 'ai-sdk':\n return true;\n\n case 'claude-agent-sdk':\n try {\n const { ClaudeAgentSDKProvider } =\n await import('../providers/claude-agent-sdk');\n const provider = new ClaudeAgentSDKProvider({});\n return provider.isAvailable();\n } catch {\n return false;\n }\n\n case 'opencode-sdk':\n try {\n const { OpenCodeSDKProvider } =\n await import('../providers/opencode-sdk');\n const provider = new OpenCodeSDKProvider({});\n return provider.isAvailable();\n } catch {\n return false;\n }\n\n default:\n return false;\n }\n }\n\n /**\n * Switch to a different backend.\n */\n async switchBackend(backend: UnifiedAgentBackend): Promise<void> {\n if (backend === this.state.backend) {\n return;\n }\n\n this.state.backend = backend;\n this.state.isReady = false;\n this.provider = undefined;\n this.context = undefined;\n\n await this.initialize();\n }\n\n /**\n * Reset the agent state.\n */\n reset(): void {\n this.state.messageCount = 0;\n this.state.sessionId = undefined;\n this.state.lastError = undefined;\n this.context = undefined;\n }\n\n /**\n * Add a tool handler.\n */\n addTool(name: string, handler: ToolHandler): void {\n this.tools.set(name, handler);\n }\n\n /**\n * Remove a tool handler.\n */\n removeTool(name: string): boolean {\n return this.tools.delete(name);\n }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Create a unified agent.\n */\nexport function createUnifiedAgent(\n spec: AgentSpec,\n config: UnifiedAgentConfig\n): UnifiedAgent {\n return new UnifiedAgent(spec, config);\n}\n\n/**\n * Create a unified agent with AI SDK backend (default).\n */\nexport function createAISDKAgent(\n spec: AgentSpec,\n options?: {\n tools?: Map<string, ToolHandler>;\n model?: string;\n }\n): UnifiedAgent {\n return new UnifiedAgent(spec, {\n backend: 'ai-sdk',\n tools: options?.tools,\n config: { model: options?.model },\n });\n}\n\n/**\n * Create a unified agent with Claude Agent SDK backend.\n */\nexport function createClaudeAgentSDKAgent(\n spec: AgentSpec,\n config?: ClaudeAgentSDKConfig & {\n tools?: Map<string, ToolHandler>;\n }\n): UnifiedAgent {\n const { tools, ...sdkConfig } = config ?? {};\n return new UnifiedAgent(spec, {\n backend: 'claude-agent-sdk',\n tools,\n config: sdkConfig,\n });\n}\n\n/**\n * Create a unified agent with OpenCode SDK backend.\n */\nexport function createOpenCodeSDKAgent(\n spec: AgentSpec,\n config?: OpenCodeSDKConfig & {\n tools?: Map<string, ToolHandler>;\n }\n): UnifiedAgent {\n const { tools, ...sdkConfig } = config ?? {};\n return new UnifiedAgent(spec, {\n backend: 'opencode-sdk',\n tools,\n config: sdkConfig,\n });\n}\n\n/**\n * Get available backends.\n */\nexport async function getAvailableBackends(): Promise<UnifiedAgentBackend[]> {\n const backends: UnifiedAgentBackend[] = ['ai-sdk'];\n\n try {\n const { ClaudeAgentSDKProvider } =\n await import('../providers/claude-agent-sdk');\n const provider = new ClaudeAgentSDKProvider({});\n if (provider.isAvailable()) {\n backends.push('claude-agent-sdk');\n }\n } catch {\n // Not available\n }\n\n try {\n const { OpenCodeSDKProvider } = await import('../providers/opencode-sdk');\n const provider = new OpenCodeSDKProvider({});\n if (provider.isAvailable()) {\n backends.push('opencode-sdk');\n }\n } catch {\n // Not available\n }\n\n return backends;\n}\n"],"mappings":";;;;AAkGA,IAAa,eAAb,MAA0B;CACxB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,MAAiB,QAA4B;AACvD,OAAK,OAAO;AACZ,OAAK,SAAS;AACd,OAAK,QAAQ,OAAO,yBAAS,IAAI,KAAK;AACtC,OAAK,QAAQ;GACX,SAAS,OAAO;GAChB,SAAS;GACT,cAAc;GACf;;;;;CAMH,MAAM,aAA4B;EAChC,MAAM,UAAU,KAAK,OAAO;AAE5B,MAAI;AACF,WAAQ,SAAR;IACE,KAAK;AAEH,UAAK,MAAM,UAAU;AACrB;IAEF,KAAK;AACH,WAAM,KAAK,0BAA0B;AACrC;IAEF,KAAK;AACH,WAAM,KAAK,uBAAuB;AAClC;IAEF,QACE,OAAM,IAAI,MAAM,oBAAoB,UAAU;;WAE3C,OAAO;AACd,QAAK,MAAM,YACT,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AAG3D,OACE,KAAK,OAAO,mBACZ,KAAK,OAAO,oBAAoB,SAChC;AACA,YAAQ,KACN,kBAAkB,QAAQ,2BAA2B,KAAK,OAAO,kBAClE;AACD,SAAK,MAAM,UAAU,KAAK,OAAO;AACjC,UAAM,KAAK,YAAY;SAEvB,OAAM;;;CAKZ,MAAc,2BAA0C;AAEtD,MAAI;GACF,MAAM,EAAE,2BACN,MAAM,OAAO;GACf,MAAM,SAAS,KAAK,OAAO;AAC3B,QAAK,WAAW,IAAI,uBAAuB,UAAU,EAAE,CAAC;AAExD,OAAI,CAAC,KAAK,SAAS,aAAa,CAC9B,OAAM,IAAI,MACR,yEACD;AAGH,QAAK,UAAU,MAAM,KAAK,SAAS,cAAc,KAAK,KAAK;AAC3D,QAAK,MAAM,UAAU;WACd,OAAO;AACd,OAAK,MAA4B,SAAS,mBACxC,OAAM,IAAI,MACR,kFACD;AAEH,SAAM;;;CAIV,MAAc,wBAAuC;AAEnD,MAAI;GACF,MAAM,EAAE,wBAAwB,MAAM,OAAO;GAC7C,MAAM,SAAS,KAAK,OAAO;AAC3B,QAAK,WAAW,IAAI,oBAAoB,UAAU,EAAE,CAAC;AAErD,OAAI,CAAC,KAAK,SAAS,aAAa,CAC9B,OAAM,IAAI,MAAM,uDAAuD;AAGzE,QAAK,UAAU,MAAM,KAAK,SAAS,cAAc,KAAK,KAAK;AAC3D,QAAK,MAAM,UAAU;WACd,OAAO;AACd,OAAK,MAA4B,SAAS,mBACxC,OAAM,IAAI,MACR,gEACD;AAEH,SAAM;;;;;;CAOV,MAAM,IACJ,SACA,SAC8B;AAC9B,MAAI,CAAC,KAAK,MAAM,QACd,OAAM,KAAK,YAAY;EAGzB,MAAM,UAAU,SAAS,WAAW,KAAK,MAAM;AAC/C,OAAK,MAAM;AAEX,MAAI;AACF,WAAQ,SAAR;IACE,KAAK,SACH,QAAO,MAAM,KAAK,aAAa,SAAS,QAAQ;IAElD,KAAK;IACL,KAAK,eACH,QAAO,MAAM,KAAK,wBAAwB,SAAS,QAAQ;IAE7D,QACE,OAAM,IAAI,MAAM,oBAAoB,UAAU;;WAE3C,OAAO;AACd,QAAK,MAAM,YACT,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AAC3D,SAAM;;;CAIV,MAAc,aACZ,SACA,SAC8B;EAE9B,MAAM,EAAE,sBAAsB,MAAM,OAAO;EAC3C,MAAM,EAAE,cAAc,MAAM,OAAO;EAGnC,MAAM,gBACJ,KAAK,OAAO,YAAY,WACnB,KAAK,OAAO,SACb,EAAE;AAUR,SAAO,OARO,MAAM,kBAAkB,OAAO;GAC3C,MAAM,KAAK;GACX,OAAO,UACJ,eAAe,SAAoB,6BACrC;GACD,cAAc,KAAK;GACpB,CAAC,EAEiB,SAAS;GAC1B,QAAQ;GACR;GACD,CAAC;;CAGJ,MAAc,wBACZ,SACA,SAC8B;AAC9B,MAAI,CAAC,KAAK,YAAY,CAAC,KAAK,QAC1B,OAAM,IAAI,MAAM,2BAA2B;EAG7C,MAAM,SAAgC,MAAM,KAAK,SAAS,QACxD,KAAK,SACL;GACE,QAAQ;GACR;GACD,CACF;AAED,SAAO,KAAK,sBAAsB,OAAO;;CAG3C,AAAQ,sBACN,QACqB;AACrB,SAAO;GACL,MAAM,OAAO;GACb,OAAO,EAAE;GACT,WAAW,OAAO,UAAU,KAAK,QAAQ;IACvC,MAAM;IACN,YAAY,GAAG;IACf,UAAU,GAAG;IACb,MAAM,GAAG;IACV,EAAE;GACH,aAAa,OAAO,YAAY,KAAK,QAAQ;IAC3C,MAAM;IACN,YAAY,GAAG;IACf,UAAU,GAAG;IACb,QAAQ,GAAG;IACZ,EAAE;GACH,cAAc,OAAO;GACrB,OAAO,OAAO,QACT;IACC,cAAc,OAAO,MAAM;IAC3B,kBAAkB,OAAO,MAAM;IAC/B,aACE,OAAO,MAAM,eACb,OAAO,MAAM,cAAc,OAAO,MAAM;IAC3C,GACD;GACL;;;;;CAMH,WAA8B;AAC5B,SAAO,EAAE,GAAG,KAAK,OAAO;;;;;CAM1B,UAAqB;AACnB,SAAO,KAAK;;;;;CAMd,aAAkC;AAChC,SAAO,KAAK,MAAM;;;;;CAMpB,MAAM,mBAAmB,SAAgD;AACvE,UAAQ,SAAR;GACE,KAAK,SACH,QAAO;GAET,KAAK,mBACH,KAAI;IACF,MAAM,EAAE,2BACN,MAAM,OAAO;AAEf,WADiB,IAAI,uBAAuB,EAAE,CAAC,CAC/B,aAAa;WACvB;AACN,WAAO;;GAGX,KAAK,eACH,KAAI;IACF,MAAM,EAAE,wBACN,MAAM,OAAO;AAEf,WADiB,IAAI,oBAAoB,EAAE,CAAC,CAC5B,aAAa;WACvB;AACN,WAAO;;GAGX,QACE,QAAO;;;;;;CAOb,MAAM,cAAc,SAA6C;AAC/D,MAAI,YAAY,KAAK,MAAM,QACzB;AAGF,OAAK,MAAM,UAAU;AACrB,OAAK,MAAM,UAAU;AACrB,OAAK,WAAW;AAChB,OAAK,UAAU;AAEf,QAAM,KAAK,YAAY;;;;;CAMzB,QAAc;AACZ,OAAK,MAAM,eAAe;AAC1B,OAAK,MAAM,YAAY;AACvB,OAAK,MAAM,YAAY;AACvB,OAAK,UAAU;;;;;CAMjB,QAAQ,MAAc,SAA4B;AAChD,OAAK,MAAM,IAAI,MAAM,QAAQ;;;;;CAM/B,WAAW,MAAuB;AAChC,SAAO,KAAK,MAAM,OAAO,KAAK;;;;;;AAWlC,SAAgB,mBACd,MACA,QACc;AACd,QAAO,IAAI,aAAa,MAAM,OAAO;;;;;AAMvC,SAAgB,iBACd,MACA,SAIc;AACd,QAAO,IAAI,aAAa,MAAM;EAC5B,SAAS;EACT,OAAO,SAAS;EAChB,QAAQ,EAAE,OAAO,SAAS,OAAO;EAClC,CAAC;;;;;AAMJ,SAAgB,0BACd,MACA,QAGc;CACd,MAAM,EAAE,OAAO,GAAG,cAAc,UAAU,EAAE;AAC5C,QAAO,IAAI,aAAa,MAAM;EAC5B,SAAS;EACT;EACA,QAAQ;EACT,CAAC;;;;;AAMJ,SAAgB,uBACd,MACA,QAGc;CACd,MAAM,EAAE,OAAO,GAAG,cAAc,UAAU,EAAE;AAC5C,QAAO,IAAI,aAAa,MAAM;EAC5B,SAAS;EACT;EACA,QAAQ;EACT,CAAC;;;;;AAMJ,eAAsB,uBAAuD;CAC3E,MAAM,WAAkC,CAAC,SAAS;AAElD,KAAI;EACF,MAAM,EAAE,2BACN,MAAM,OAAO;AAEf,MADiB,IAAI,uBAAuB,EAAE,CAAC,CAClC,aAAa,CACxB,UAAS,KAAK,mBAAmB;SAE7B;AAIR,KAAI;EACF,MAAM,EAAE,wBAAwB,MAAM,OAAO;AAE7C,MADiB,IAAI,oBAAoB,EAAE,CAAC,CAC/B,aAAa,CACxB,UAAS,KAAK,eAAe;SAEzB;AAIR,QAAO"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { ApprovalRequest, ApprovalStatus, ApprovalStore, ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow } from "./workflow.js";
|
|
2
|
+
export { type ApprovalRequest, type ApprovalStatus, type ApprovalStore, ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { ToolCallInfo } from "../types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/approval/workflow.d.ts
|
|
4
|
+
type ApprovalStatus = 'pending' | 'approved' | 'rejected';
|
|
5
|
+
/**
|
|
6
|
+
* Approval request for a tool execution.
|
|
7
|
+
*
|
|
8
|
+
* When a tool has `needsApproval: true` in AI SDK v6, the agent
|
|
9
|
+
* will pause and wait for approval before executing the tool.
|
|
10
|
+
*/
|
|
11
|
+
interface ApprovalRequest {
|
|
12
|
+
/** Unique request ID */
|
|
13
|
+
id: string;
|
|
14
|
+
/** Agent session ID */
|
|
15
|
+
sessionId: string;
|
|
16
|
+
/** Agent ID */
|
|
17
|
+
agentId: string;
|
|
18
|
+
/** Tenant ID for scoping */
|
|
19
|
+
tenantId?: string;
|
|
20
|
+
/** Tool name requiring approval */
|
|
21
|
+
toolName: string;
|
|
22
|
+
/** Tool call ID from AI SDK */
|
|
23
|
+
toolCallId: string;
|
|
24
|
+
/** Tool arguments */
|
|
25
|
+
toolArgs: unknown;
|
|
26
|
+
/** Human-readable reason for approval */
|
|
27
|
+
reason: string;
|
|
28
|
+
/** When the approval was requested */
|
|
29
|
+
requestedAt: Date;
|
|
30
|
+
/** Current status */
|
|
31
|
+
status: ApprovalStatus;
|
|
32
|
+
/** Additional context payload */
|
|
33
|
+
payload?: Record<string, unknown>;
|
|
34
|
+
/** Who resolved the approval */
|
|
35
|
+
reviewer?: string;
|
|
36
|
+
/** When the approval was resolved */
|
|
37
|
+
resolvedAt?: Date;
|
|
38
|
+
/** Reviewer notes */
|
|
39
|
+
notes?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Storage interface for approval requests.
|
|
43
|
+
*/
|
|
44
|
+
interface ApprovalStore {
|
|
45
|
+
create(request: ApprovalRequest): Promise<void>;
|
|
46
|
+
get(id: string): Promise<ApprovalRequest | null>;
|
|
47
|
+
getByToolCallId(toolCallId: string): Promise<ApprovalRequest | null>;
|
|
48
|
+
update(id: string, updates: Partial<Omit<ApprovalRequest, 'id' | 'sessionId'>>): Promise<void>;
|
|
49
|
+
list(options?: {
|
|
50
|
+
status?: ApprovalStatus;
|
|
51
|
+
agentId?: string;
|
|
52
|
+
tenantId?: string;
|
|
53
|
+
}): Promise<ApprovalRequest[]>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* In-memory approval store for development and testing.
|
|
57
|
+
*/
|
|
58
|
+
declare class InMemoryApprovalStore implements ApprovalStore {
|
|
59
|
+
private readonly items;
|
|
60
|
+
create(request: ApprovalRequest): Promise<void>;
|
|
61
|
+
get(id: string): Promise<ApprovalRequest | null>;
|
|
62
|
+
getByToolCallId(toolCallId: string): Promise<ApprovalRequest | null>;
|
|
63
|
+
update(id: string, updates: Partial<Omit<ApprovalRequest, 'id' | 'sessionId'>>): Promise<void>;
|
|
64
|
+
list(options?: {
|
|
65
|
+
status?: ApprovalStatus;
|
|
66
|
+
agentId?: string;
|
|
67
|
+
tenantId?: string;
|
|
68
|
+
}): Promise<ApprovalRequest[]>;
|
|
69
|
+
clear(): void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Approval workflow for managing tool execution approvals.
|
|
73
|
+
*
|
|
74
|
+
* Integrates with AI SDK v6's `needsApproval` feature on tools.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const workflow = new ApprovalWorkflow();
|
|
79
|
+
*
|
|
80
|
+
* // When a tool needs approval
|
|
81
|
+
* const request = await workflow.requestApproval({
|
|
82
|
+
* sessionId: 'sess_123',
|
|
83
|
+
* agentId: 'support.bot.v1',
|
|
84
|
+
* toolName: 'delete_account',
|
|
85
|
+
* toolCallId: 'call_abc',
|
|
86
|
+
* toolArgs: { userId: 'user_123' },
|
|
87
|
+
* reason: 'Account deletion requires human approval',
|
|
88
|
+
* });
|
|
89
|
+
*
|
|
90
|
+
* // When approval is granted
|
|
91
|
+
* await workflow.approve(request.id, 'admin@example.com', 'Verified identity');
|
|
92
|
+
*
|
|
93
|
+
* // Or rejected
|
|
94
|
+
* await workflow.reject(request.id, 'admin@example.com', 'Suspicious activity');
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare class ApprovalWorkflow {
|
|
98
|
+
private readonly store;
|
|
99
|
+
constructor(store?: ApprovalStore);
|
|
100
|
+
/**
|
|
101
|
+
* Request approval for a tool execution.
|
|
102
|
+
*/
|
|
103
|
+
requestApproval(params: {
|
|
104
|
+
sessionId: string;
|
|
105
|
+
agentId: string;
|
|
106
|
+
tenantId?: string;
|
|
107
|
+
toolName: string;
|
|
108
|
+
toolCallId: string;
|
|
109
|
+
toolArgs: unknown;
|
|
110
|
+
reason: string;
|
|
111
|
+
payload?: Record<string, unknown>;
|
|
112
|
+
}): Promise<ApprovalRequest>;
|
|
113
|
+
/**
|
|
114
|
+
* Request approval from an AI SDK tool call.
|
|
115
|
+
*/
|
|
116
|
+
requestApprovalFromToolCall(toolCall: ToolCallInfo, context: {
|
|
117
|
+
sessionId: string;
|
|
118
|
+
agentId: string;
|
|
119
|
+
tenantId?: string;
|
|
120
|
+
reason?: string;
|
|
121
|
+
}): Promise<ApprovalRequest>;
|
|
122
|
+
/**
|
|
123
|
+
* Approve a pending request.
|
|
124
|
+
*/
|
|
125
|
+
approve(id: string, reviewer: string, notes?: string): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Reject a pending request.
|
|
128
|
+
*/
|
|
129
|
+
reject(id: string, reviewer: string, notes?: string): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Get approval status for a tool call.
|
|
132
|
+
*/
|
|
133
|
+
getStatus(toolCallId: string): Promise<ApprovalStatus | null>;
|
|
134
|
+
/**
|
|
135
|
+
* Check if a tool call is approved.
|
|
136
|
+
*/
|
|
137
|
+
isApproved(toolCallId: string): Promise<boolean>;
|
|
138
|
+
/**
|
|
139
|
+
* List pending approvals.
|
|
140
|
+
*/
|
|
141
|
+
listPending(options?: {
|
|
142
|
+
agentId?: string;
|
|
143
|
+
tenantId?: string;
|
|
144
|
+
}): Promise<ApprovalRequest[]>;
|
|
145
|
+
/**
|
|
146
|
+
* Get approval request by ID.
|
|
147
|
+
*/
|
|
148
|
+
get(id: string): Promise<ApprovalRequest | null>;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create an approval workflow instance.
|
|
152
|
+
*/
|
|
153
|
+
declare function createApprovalWorkflow(store?: ApprovalStore): ApprovalWorkflow;
|
|
154
|
+
//#endregion
|
|
155
|
+
export { ApprovalRequest, ApprovalStatus, ApprovalStore, ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow };
|
|
156
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","names":[],"sources":["../../src/approval/workflow.ts"],"sourcesContent":[],"mappings":";;;KAGY,cAAA;;AAAZ;AAQA;;;;AA0Be,UA1BE,eAAA,CA0BF;EAAI;EAQF,EAAA,EAAA,MAAA;EACC;EAAkB,SAAA,EAAA,MAAA;EACT;EAAR,OAAA,EAAA,MAAA;EAC4B;EAAR,QAAA,CAAA,EAAA,MAAA;EAGb;EAAL,QAAA,EAAA,MAAA;EAAR;EACR,UAAA,EAAA,MAAA;EAEQ;EAGC,QAAA,EAAA,OAAA;EAAR;EAAO,MAAA,EAAA,MAAA;EAMA;EAGW,WAAA,EArCT,IAqCS;EAAkB;EAIT,MAAA,EAvCvB,cAuCuB;EAAR;EAI4B,OAAA,CAAA,EAzCzC,MAyCyC,CAAA,MAAA,EAAA,OAAA,CAAA;EAAR;EAWnB,QAAA,CAAA,EAAA,MAAA;EAAL;EAAR,UAAA,CAAA,EAhDE,IAgDF;EACR;EAQQ,KAAA,CAAA,EAAA,MAAA;;;;;AAoDA,UArGI,aAAA,CAqGY;EAED,MAAA,CAAA,OAAA,EAtGV,eAsGU,CAAA,EAtGQ,OAsGR,CAAA,IAAA,CAAA;EAcd,GAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAnHK,OAmHL,CAnHa,eAmHb,GAAA,IAAA,CAAA;EACA,eAAA,CAAA,UAAA,EAAA,MAAA,CAAA,EAnHyB,OAmHzB,CAnHiC,eAmHjC,GAAA,IAAA,CAAA;EAAR,MAAA,CAAA,EAAA,EAAA,MAAA,EAAA,OAAA,EAhHO,OAgHP,CAhHe,IAgHf,CAhHoB,eAgHpB,EAAA,IAAA,GAAA,WAAA,CAAA,CAAA,CAAA,EA/GD,OA+GC,CAAA,IAAA,CAAA;EAuBQ,IAAA,CAAA,OAkCgD,CAlChD,EAAA;IAOD,MAAA,CAAA,EA3IA,cA2IA;IAAR,OAAA,CAAA,EAAA,MAAA;IAe0D,QAAA,CAAA,EAAA,MAAA;EAYD,CAAA,CAAA,EAnKxD,OAmKwD,CAnKhD,eAmKgD,EAAA,CAAA;;;;;AA+BxD,cA5LO,qBAAA,YAAiC,aA4LxC,CAAA;EAO2B,iBAAA,KAAA;EAAR,MAAA,CAAA,OAAA,EAhMD,eAgMC,CAAA,EAhMiB,OAgMjB,CAAA,IAAA,CAAA;EAAO,GAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EA5LP,OA4LO,CA5LC,eA4LD,GAAA,IAAA,CAAA;EAQhB,eAAA,CAAA,UAAsB,EAAA,MAAA,CAAA,EAhMO,OAiMnC,CAjM2C,eAkMlD,GAAA,IAAA,CAAA;8BAvLU,QAAQ,KAAK,wCACrB;;aAQQ;;;MAGP,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiDD,gBAAA;;sBAEe;;;;;;;;;;;;cAcd;MACR,QAAQ;;;;wCAuBA;;;;;MAOT,QAAQ;;;;yDAekD;;;;wDAYD;;;;iCAYvB,QAAQ;;;;kCAQP;;;;;;;MAWlC,QAAQ;;;;mBAOW,QAAQ;;;;;iBAQjB,sBAAA,SACN,gBACP"}
|