@witqq/agent-sdk 0.1.0
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 +310 -0
- package/dist/backends/claude.cjs +718 -0
- package/dist/backends/claude.cjs.map +1 -0
- package/dist/backends/claude.d.cts +118 -0
- package/dist/backends/claude.d.ts +118 -0
- package/dist/backends/claude.js +714 -0
- package/dist/backends/claude.js.map +1 -0
- package/dist/backends/copilot.cjs +651 -0
- package/dist/backends/copilot.cjs.map +1 -0
- package/dist/backends/copilot.d.cts +121 -0
- package/dist/backends/copilot.d.ts +121 -0
- package/dist/backends/copilot.js +647 -0
- package/dist/backends/copilot.js.map +1 -0
- package/dist/backends/vercel-ai.cjs +620 -0
- package/dist/backends/vercel-ai.cjs.map +1 -0
- package/dist/backends/vercel-ai.d.cts +99 -0
- package/dist/backends/vercel-ai.d.ts +99 -0
- package/dist/backends/vercel-ai.js +615 -0
- package/dist/backends/vercel-ai.js.map +1 -0
- package/dist/index.cjs +505 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +444 -0
- package/dist/index.d.ts +444 -0
- package/dist/index.js +453 -0
- package/dist/index.js.map +1 -0
- package/dist/types-JVBEqeDw.d.cts +288 -0
- package/dist/types-JVBEqeDw.d.ts +288 -0
- package/package.json +110 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/** Pluggable store for persisting permission (scope) decisions across runs. */
|
|
4
|
+
interface IPermissionStore {
|
|
5
|
+
/** Check if tool is already approved */
|
|
6
|
+
isApproved(toolName: string): Promise<boolean>;
|
|
7
|
+
/** Store an approval decision */
|
|
8
|
+
approve(toolName: string, scope: PermissionScope): Promise<void>;
|
|
9
|
+
/** Revoke approval for a tool */
|
|
10
|
+
revoke(toolName: string): Promise<void>;
|
|
11
|
+
/** Clear all approvals */
|
|
12
|
+
clear(): Promise<void>;
|
|
13
|
+
/** Dispose resources */
|
|
14
|
+
dispose(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** JSON-serializable value used for tool arguments and results */
|
|
18
|
+
type JSONValue = string | number | boolean | null | JSONValue[] | {
|
|
19
|
+
[key: string]: JSONValue;
|
|
20
|
+
};
|
|
21
|
+
/** Message content — plain string or array of text/image parts */
|
|
22
|
+
type MessageContent = string | Array<ContentPart>;
|
|
23
|
+
/** Individual content part within a multi-part message */
|
|
24
|
+
type ContentPart = {
|
|
25
|
+
type: "text";
|
|
26
|
+
text: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: "image";
|
|
29
|
+
data: string;
|
|
30
|
+
mimeType: string;
|
|
31
|
+
};
|
|
32
|
+
/** What the LLM sees — name, description, schema. Passed to all backends. */
|
|
33
|
+
interface ToolDeclaration<TParams = unknown> {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
parameters: z.ZodType<TParams>;
|
|
37
|
+
needsApproval?: boolean;
|
|
38
|
+
metadata?: {
|
|
39
|
+
category?: string;
|
|
40
|
+
icon?: string;
|
|
41
|
+
tags?: string[];
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Full tool with execute function. Required for API-based backends.
|
|
45
|
+
* CLI backends extract declaration; execute map held internally. */
|
|
46
|
+
interface ToolDefinition<TParams = unknown> extends ToolDeclaration<TParams> {
|
|
47
|
+
execute: (params: TParams) => Promise<JSONValue> | JSONValue;
|
|
48
|
+
}
|
|
49
|
+
/** A tool call made by the LLM during execution */
|
|
50
|
+
interface ToolCall {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
args: JSONValue;
|
|
54
|
+
}
|
|
55
|
+
/** Result of executing a tool call */
|
|
56
|
+
interface ToolResult {
|
|
57
|
+
toolCallId: string;
|
|
58
|
+
name: string;
|
|
59
|
+
result: JSONValue;
|
|
60
|
+
isError?: boolean;
|
|
61
|
+
}
|
|
62
|
+
/** Conversation message — discriminated union on `role` */
|
|
63
|
+
type Message = {
|
|
64
|
+
role: "user";
|
|
65
|
+
content: MessageContent;
|
|
66
|
+
} | {
|
|
67
|
+
role: "assistant";
|
|
68
|
+
content: MessageContent;
|
|
69
|
+
toolCalls?: ToolCall[];
|
|
70
|
+
} | {
|
|
71
|
+
role: "tool";
|
|
72
|
+
content?: string;
|
|
73
|
+
toolResults: ToolResult[];
|
|
74
|
+
} | {
|
|
75
|
+
role: "system";
|
|
76
|
+
content: string;
|
|
77
|
+
};
|
|
78
|
+
/** Scope for "remember this decision" */
|
|
79
|
+
type PermissionScope = "once" | "session" | "project" | "always";
|
|
80
|
+
/** What the permission callback receives */
|
|
81
|
+
interface PermissionRequest {
|
|
82
|
+
toolName: string;
|
|
83
|
+
toolArgs: Record<string, unknown>;
|
|
84
|
+
/** SDK-suggested scope (from Claude CLI's suggestions) */
|
|
85
|
+
suggestedScope?: PermissionScope;
|
|
86
|
+
/** Original SDK permission request (for pass-through) */
|
|
87
|
+
rawSDKRequest?: unknown;
|
|
88
|
+
}
|
|
89
|
+
/** What the permission callback returns */
|
|
90
|
+
interface PermissionDecision {
|
|
91
|
+
allowed: boolean;
|
|
92
|
+
/** How long to remember this decision */
|
|
93
|
+
scope?: PermissionScope;
|
|
94
|
+
/** Modified tool arguments (tool args may be altered by user) */
|
|
95
|
+
modifiedInput?: Record<string, unknown>;
|
|
96
|
+
/** Denial reason (if denied) */
|
|
97
|
+
reason?: string;
|
|
98
|
+
}
|
|
99
|
+
/** Permission callback signature */
|
|
100
|
+
type PermissionCallback = (request: PermissionRequest, signal: AbortSignal) => Promise<PermissionDecision>;
|
|
101
|
+
/** Request for user input — separate from permissions */
|
|
102
|
+
interface UserInputRequest {
|
|
103
|
+
question: string;
|
|
104
|
+
choices?: string[];
|
|
105
|
+
/** Whether to allow freeform text input (default: true) */
|
|
106
|
+
allowFreeform?: boolean;
|
|
107
|
+
}
|
|
108
|
+
/** Response from user to an input request */
|
|
109
|
+
interface UserInputResponse {
|
|
110
|
+
answer: string;
|
|
111
|
+
/** true if user typed a custom answer instead of selecting a choice */
|
|
112
|
+
wasFreeform: boolean;
|
|
113
|
+
/** Index of selected choice (if choice was selected) */
|
|
114
|
+
selectedChoiceIndex?: number;
|
|
115
|
+
}
|
|
116
|
+
/** Hooks for supervisor/UI to intercept agent actions */
|
|
117
|
+
interface SupervisorHooks {
|
|
118
|
+
onPermission?: PermissionCallback;
|
|
119
|
+
onAskUser?: (request: UserInputRequest, signal: AbortSignal) => Promise<UserInputResponse>;
|
|
120
|
+
}
|
|
121
|
+
/** Configuration for typed structured output from LLM */
|
|
122
|
+
interface StructuredOutputConfig<T = unknown> {
|
|
123
|
+
schema: z.ZodType<T>;
|
|
124
|
+
name?: string;
|
|
125
|
+
description?: string;
|
|
126
|
+
}
|
|
127
|
+
/** Events emitted during streaming agent execution */
|
|
128
|
+
type AgentEvent = {
|
|
129
|
+
type: "text_delta";
|
|
130
|
+
text: string;
|
|
131
|
+
} | {
|
|
132
|
+
type: "tool_call_start";
|
|
133
|
+
toolName: string;
|
|
134
|
+
args: JSONValue;
|
|
135
|
+
} | {
|
|
136
|
+
type: "tool_call_end";
|
|
137
|
+
toolName: string;
|
|
138
|
+
result: JSONValue;
|
|
139
|
+
} | {
|
|
140
|
+
type: "permission_request";
|
|
141
|
+
request: PermissionRequest;
|
|
142
|
+
} | {
|
|
143
|
+
type: "permission_response";
|
|
144
|
+
toolName: string;
|
|
145
|
+
decision: PermissionDecision;
|
|
146
|
+
} | {
|
|
147
|
+
type: "ask_user";
|
|
148
|
+
request: UserInputRequest;
|
|
149
|
+
} | {
|
|
150
|
+
type: "ask_user_response";
|
|
151
|
+
answer: string;
|
|
152
|
+
} | {
|
|
153
|
+
type: "thinking_start";
|
|
154
|
+
} | {
|
|
155
|
+
type: "thinking_end";
|
|
156
|
+
} | {
|
|
157
|
+
type: "usage_update";
|
|
158
|
+
promptTokens: number;
|
|
159
|
+
completionTokens: number;
|
|
160
|
+
} | {
|
|
161
|
+
type: "error";
|
|
162
|
+
error: string;
|
|
163
|
+
recoverable: boolean;
|
|
164
|
+
} | {
|
|
165
|
+
type: "done";
|
|
166
|
+
finalOutput: string | null;
|
|
167
|
+
structuredOutput?: unknown;
|
|
168
|
+
};
|
|
169
|
+
/** Options passed to agent.run() / agent.stream() */
|
|
170
|
+
interface RunOptions {
|
|
171
|
+
/** AbortSignal for cancellation */
|
|
172
|
+
signal?: AbortSignal;
|
|
173
|
+
/** Arbitrary context passed to the agent run */
|
|
174
|
+
context?: Record<string, unknown>;
|
|
175
|
+
}
|
|
176
|
+
/** LLM model parameters */
|
|
177
|
+
interface ModelParams {
|
|
178
|
+
temperature?: number;
|
|
179
|
+
maxTokens?: number;
|
|
180
|
+
topP?: number;
|
|
181
|
+
stopSequences?: string[];
|
|
182
|
+
}
|
|
183
|
+
/** Timeout configuration for agent operations */
|
|
184
|
+
interface TimeoutConfig {
|
|
185
|
+
/** Max time for entire agent run (ms) */
|
|
186
|
+
total?: number;
|
|
187
|
+
/** Max time for a single tool execution (ms) */
|
|
188
|
+
perTool?: number;
|
|
189
|
+
/** Max time for a single LLM request (ms) */
|
|
190
|
+
perLLMRequest?: number;
|
|
191
|
+
}
|
|
192
|
+
/** Error handling strategy configuration */
|
|
193
|
+
interface ErrorHandlingConfig {
|
|
194
|
+
/** What to do when a tool throws */
|
|
195
|
+
onToolError?: "fail" | "continue" | "ask-llm";
|
|
196
|
+
/** Retry config for transient LLM failures */
|
|
197
|
+
retryLLM?: {
|
|
198
|
+
maxAttempts: number;
|
|
199
|
+
backoffMs: number;
|
|
200
|
+
};
|
|
201
|
+
/** Global error callback for monitoring */
|
|
202
|
+
onError?: (error: Error, context: {
|
|
203
|
+
phase: "tool" | "llm" | "permission" | "ask-user";
|
|
204
|
+
}) => void;
|
|
205
|
+
}
|
|
206
|
+
/** Configuration for creating an agent */
|
|
207
|
+
interface AgentConfig {
|
|
208
|
+
model?: string;
|
|
209
|
+
modelParams?: ModelParams;
|
|
210
|
+
systemPrompt: string;
|
|
211
|
+
tools: ToolDefinition[];
|
|
212
|
+
supervisor?: SupervisorHooks;
|
|
213
|
+
maxTurns?: number;
|
|
214
|
+
timeout?: TimeoutConfig;
|
|
215
|
+
errorHandling?: ErrorHandlingConfig;
|
|
216
|
+
/** Pluggable store for persisting permission scope decisions across runs */
|
|
217
|
+
permissionStore?: IPermissionStore;
|
|
218
|
+
}
|
|
219
|
+
/** Result of an agent run, generic over structured output type T */
|
|
220
|
+
interface AgentResult<T = void> {
|
|
221
|
+
output: string | null;
|
|
222
|
+
structuredOutput: T extends void ? undefined : T;
|
|
223
|
+
toolCalls: Array<{
|
|
224
|
+
toolName: string;
|
|
225
|
+
args: JSONValue;
|
|
226
|
+
result: JSONValue;
|
|
227
|
+
approved: boolean;
|
|
228
|
+
}>;
|
|
229
|
+
messages: Message[];
|
|
230
|
+
usage?: {
|
|
231
|
+
promptTokens: number;
|
|
232
|
+
completionTokens: number;
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/** Agent lifecycle state */
|
|
236
|
+
type AgentState = "idle" | "running" | "streaming" | "disposed";
|
|
237
|
+
/** Core agent interface — run prompts, stream events, manage lifecycle */
|
|
238
|
+
interface IAgent {
|
|
239
|
+
run(prompt: MessageContent, options?: RunOptions): Promise<AgentResult>;
|
|
240
|
+
runWithContext(messages: Message[], options?: RunOptions): Promise<AgentResult>;
|
|
241
|
+
runStructured<T>(prompt: MessageContent, schema: StructuredOutputConfig<T>, options?: RunOptions): Promise<AgentResult<T>>;
|
|
242
|
+
stream(prompt: MessageContent, options?: RunOptions): AsyncIterable<AgentEvent>;
|
|
243
|
+
abort(): void;
|
|
244
|
+
getState(): AgentState;
|
|
245
|
+
getConfig(): Readonly<AgentConfig>;
|
|
246
|
+
/** Release resources. After dispose(), agent must not be used. */
|
|
247
|
+
dispose(): void;
|
|
248
|
+
}
|
|
249
|
+
/** Model metadata returned by listModels() */
|
|
250
|
+
interface ModelInfo {
|
|
251
|
+
id: string;
|
|
252
|
+
name?: string;
|
|
253
|
+
provider?: string;
|
|
254
|
+
}
|
|
255
|
+
/** Result of backend validation check */
|
|
256
|
+
interface ValidationResult {
|
|
257
|
+
valid: boolean;
|
|
258
|
+
errors: string[];
|
|
259
|
+
}
|
|
260
|
+
/** Backend service interface — creates agents, lists models, validates config */
|
|
261
|
+
interface IAgentService {
|
|
262
|
+
readonly name: string;
|
|
263
|
+
createAgent(config: AgentConfig): IAgent;
|
|
264
|
+
listModels(): Promise<ModelInfo[]>;
|
|
265
|
+
validate(): Promise<ValidationResult>;
|
|
266
|
+
dispose(): Promise<void>;
|
|
267
|
+
}
|
|
268
|
+
/** Options for Copilot CLI backend */
|
|
269
|
+
interface CopilotBackendOptions {
|
|
270
|
+
cliPath?: string;
|
|
271
|
+
workingDirectory?: string;
|
|
272
|
+
githubToken?: string;
|
|
273
|
+
useLoggedInUser?: boolean;
|
|
274
|
+
}
|
|
275
|
+
/** Options for Claude CLI backend */
|
|
276
|
+
interface ClaudeBackendOptions {
|
|
277
|
+
cliPath?: string;
|
|
278
|
+
workingDirectory?: string;
|
|
279
|
+
maxTurns?: number;
|
|
280
|
+
}
|
|
281
|
+
/** Options for Vercel AI SDK backend */
|
|
282
|
+
interface VercelAIBackendOptions {
|
|
283
|
+
apiKey: string;
|
|
284
|
+
provider?: string;
|
|
285
|
+
baseUrl?: string;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export type { CopilotBackendOptions as C, IAgentService as I, VercelAIBackendOptions as V, ClaudeBackendOptions as a };
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/** Pluggable store for persisting permission (scope) decisions across runs. */
|
|
4
|
+
interface IPermissionStore {
|
|
5
|
+
/** Check if tool is already approved */
|
|
6
|
+
isApproved(toolName: string): Promise<boolean>;
|
|
7
|
+
/** Store an approval decision */
|
|
8
|
+
approve(toolName: string, scope: PermissionScope): Promise<void>;
|
|
9
|
+
/** Revoke approval for a tool */
|
|
10
|
+
revoke(toolName: string): Promise<void>;
|
|
11
|
+
/** Clear all approvals */
|
|
12
|
+
clear(): Promise<void>;
|
|
13
|
+
/** Dispose resources */
|
|
14
|
+
dispose(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** JSON-serializable value used for tool arguments and results */
|
|
18
|
+
type JSONValue = string | number | boolean | null | JSONValue[] | {
|
|
19
|
+
[key: string]: JSONValue;
|
|
20
|
+
};
|
|
21
|
+
/** Message content — plain string or array of text/image parts */
|
|
22
|
+
type MessageContent = string | Array<ContentPart>;
|
|
23
|
+
/** Individual content part within a multi-part message */
|
|
24
|
+
type ContentPart = {
|
|
25
|
+
type: "text";
|
|
26
|
+
text: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: "image";
|
|
29
|
+
data: string;
|
|
30
|
+
mimeType: string;
|
|
31
|
+
};
|
|
32
|
+
/** What the LLM sees — name, description, schema. Passed to all backends. */
|
|
33
|
+
interface ToolDeclaration<TParams = unknown> {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
parameters: z.ZodType<TParams>;
|
|
37
|
+
needsApproval?: boolean;
|
|
38
|
+
metadata?: {
|
|
39
|
+
category?: string;
|
|
40
|
+
icon?: string;
|
|
41
|
+
tags?: string[];
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Full tool with execute function. Required for API-based backends.
|
|
45
|
+
* CLI backends extract declaration; execute map held internally. */
|
|
46
|
+
interface ToolDefinition<TParams = unknown> extends ToolDeclaration<TParams> {
|
|
47
|
+
execute: (params: TParams) => Promise<JSONValue> | JSONValue;
|
|
48
|
+
}
|
|
49
|
+
/** A tool call made by the LLM during execution */
|
|
50
|
+
interface ToolCall {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
args: JSONValue;
|
|
54
|
+
}
|
|
55
|
+
/** Result of executing a tool call */
|
|
56
|
+
interface ToolResult {
|
|
57
|
+
toolCallId: string;
|
|
58
|
+
name: string;
|
|
59
|
+
result: JSONValue;
|
|
60
|
+
isError?: boolean;
|
|
61
|
+
}
|
|
62
|
+
/** Conversation message — discriminated union on `role` */
|
|
63
|
+
type Message = {
|
|
64
|
+
role: "user";
|
|
65
|
+
content: MessageContent;
|
|
66
|
+
} | {
|
|
67
|
+
role: "assistant";
|
|
68
|
+
content: MessageContent;
|
|
69
|
+
toolCalls?: ToolCall[];
|
|
70
|
+
} | {
|
|
71
|
+
role: "tool";
|
|
72
|
+
content?: string;
|
|
73
|
+
toolResults: ToolResult[];
|
|
74
|
+
} | {
|
|
75
|
+
role: "system";
|
|
76
|
+
content: string;
|
|
77
|
+
};
|
|
78
|
+
/** Scope for "remember this decision" */
|
|
79
|
+
type PermissionScope = "once" | "session" | "project" | "always";
|
|
80
|
+
/** What the permission callback receives */
|
|
81
|
+
interface PermissionRequest {
|
|
82
|
+
toolName: string;
|
|
83
|
+
toolArgs: Record<string, unknown>;
|
|
84
|
+
/** SDK-suggested scope (from Claude CLI's suggestions) */
|
|
85
|
+
suggestedScope?: PermissionScope;
|
|
86
|
+
/** Original SDK permission request (for pass-through) */
|
|
87
|
+
rawSDKRequest?: unknown;
|
|
88
|
+
}
|
|
89
|
+
/** What the permission callback returns */
|
|
90
|
+
interface PermissionDecision {
|
|
91
|
+
allowed: boolean;
|
|
92
|
+
/** How long to remember this decision */
|
|
93
|
+
scope?: PermissionScope;
|
|
94
|
+
/** Modified tool arguments (tool args may be altered by user) */
|
|
95
|
+
modifiedInput?: Record<string, unknown>;
|
|
96
|
+
/** Denial reason (if denied) */
|
|
97
|
+
reason?: string;
|
|
98
|
+
}
|
|
99
|
+
/** Permission callback signature */
|
|
100
|
+
type PermissionCallback = (request: PermissionRequest, signal: AbortSignal) => Promise<PermissionDecision>;
|
|
101
|
+
/** Request for user input — separate from permissions */
|
|
102
|
+
interface UserInputRequest {
|
|
103
|
+
question: string;
|
|
104
|
+
choices?: string[];
|
|
105
|
+
/** Whether to allow freeform text input (default: true) */
|
|
106
|
+
allowFreeform?: boolean;
|
|
107
|
+
}
|
|
108
|
+
/** Response from user to an input request */
|
|
109
|
+
interface UserInputResponse {
|
|
110
|
+
answer: string;
|
|
111
|
+
/** true if user typed a custom answer instead of selecting a choice */
|
|
112
|
+
wasFreeform: boolean;
|
|
113
|
+
/** Index of selected choice (if choice was selected) */
|
|
114
|
+
selectedChoiceIndex?: number;
|
|
115
|
+
}
|
|
116
|
+
/** Hooks for supervisor/UI to intercept agent actions */
|
|
117
|
+
interface SupervisorHooks {
|
|
118
|
+
onPermission?: PermissionCallback;
|
|
119
|
+
onAskUser?: (request: UserInputRequest, signal: AbortSignal) => Promise<UserInputResponse>;
|
|
120
|
+
}
|
|
121
|
+
/** Configuration for typed structured output from LLM */
|
|
122
|
+
interface StructuredOutputConfig<T = unknown> {
|
|
123
|
+
schema: z.ZodType<T>;
|
|
124
|
+
name?: string;
|
|
125
|
+
description?: string;
|
|
126
|
+
}
|
|
127
|
+
/** Events emitted during streaming agent execution */
|
|
128
|
+
type AgentEvent = {
|
|
129
|
+
type: "text_delta";
|
|
130
|
+
text: string;
|
|
131
|
+
} | {
|
|
132
|
+
type: "tool_call_start";
|
|
133
|
+
toolName: string;
|
|
134
|
+
args: JSONValue;
|
|
135
|
+
} | {
|
|
136
|
+
type: "tool_call_end";
|
|
137
|
+
toolName: string;
|
|
138
|
+
result: JSONValue;
|
|
139
|
+
} | {
|
|
140
|
+
type: "permission_request";
|
|
141
|
+
request: PermissionRequest;
|
|
142
|
+
} | {
|
|
143
|
+
type: "permission_response";
|
|
144
|
+
toolName: string;
|
|
145
|
+
decision: PermissionDecision;
|
|
146
|
+
} | {
|
|
147
|
+
type: "ask_user";
|
|
148
|
+
request: UserInputRequest;
|
|
149
|
+
} | {
|
|
150
|
+
type: "ask_user_response";
|
|
151
|
+
answer: string;
|
|
152
|
+
} | {
|
|
153
|
+
type: "thinking_start";
|
|
154
|
+
} | {
|
|
155
|
+
type: "thinking_end";
|
|
156
|
+
} | {
|
|
157
|
+
type: "usage_update";
|
|
158
|
+
promptTokens: number;
|
|
159
|
+
completionTokens: number;
|
|
160
|
+
} | {
|
|
161
|
+
type: "error";
|
|
162
|
+
error: string;
|
|
163
|
+
recoverable: boolean;
|
|
164
|
+
} | {
|
|
165
|
+
type: "done";
|
|
166
|
+
finalOutput: string | null;
|
|
167
|
+
structuredOutput?: unknown;
|
|
168
|
+
};
|
|
169
|
+
/** Options passed to agent.run() / agent.stream() */
|
|
170
|
+
interface RunOptions {
|
|
171
|
+
/** AbortSignal for cancellation */
|
|
172
|
+
signal?: AbortSignal;
|
|
173
|
+
/** Arbitrary context passed to the agent run */
|
|
174
|
+
context?: Record<string, unknown>;
|
|
175
|
+
}
|
|
176
|
+
/** LLM model parameters */
|
|
177
|
+
interface ModelParams {
|
|
178
|
+
temperature?: number;
|
|
179
|
+
maxTokens?: number;
|
|
180
|
+
topP?: number;
|
|
181
|
+
stopSequences?: string[];
|
|
182
|
+
}
|
|
183
|
+
/** Timeout configuration for agent operations */
|
|
184
|
+
interface TimeoutConfig {
|
|
185
|
+
/** Max time for entire agent run (ms) */
|
|
186
|
+
total?: number;
|
|
187
|
+
/** Max time for a single tool execution (ms) */
|
|
188
|
+
perTool?: number;
|
|
189
|
+
/** Max time for a single LLM request (ms) */
|
|
190
|
+
perLLMRequest?: number;
|
|
191
|
+
}
|
|
192
|
+
/** Error handling strategy configuration */
|
|
193
|
+
interface ErrorHandlingConfig {
|
|
194
|
+
/** What to do when a tool throws */
|
|
195
|
+
onToolError?: "fail" | "continue" | "ask-llm";
|
|
196
|
+
/** Retry config for transient LLM failures */
|
|
197
|
+
retryLLM?: {
|
|
198
|
+
maxAttempts: number;
|
|
199
|
+
backoffMs: number;
|
|
200
|
+
};
|
|
201
|
+
/** Global error callback for monitoring */
|
|
202
|
+
onError?: (error: Error, context: {
|
|
203
|
+
phase: "tool" | "llm" | "permission" | "ask-user";
|
|
204
|
+
}) => void;
|
|
205
|
+
}
|
|
206
|
+
/** Configuration for creating an agent */
|
|
207
|
+
interface AgentConfig {
|
|
208
|
+
model?: string;
|
|
209
|
+
modelParams?: ModelParams;
|
|
210
|
+
systemPrompt: string;
|
|
211
|
+
tools: ToolDefinition[];
|
|
212
|
+
supervisor?: SupervisorHooks;
|
|
213
|
+
maxTurns?: number;
|
|
214
|
+
timeout?: TimeoutConfig;
|
|
215
|
+
errorHandling?: ErrorHandlingConfig;
|
|
216
|
+
/** Pluggable store for persisting permission scope decisions across runs */
|
|
217
|
+
permissionStore?: IPermissionStore;
|
|
218
|
+
}
|
|
219
|
+
/** Result of an agent run, generic over structured output type T */
|
|
220
|
+
interface AgentResult<T = void> {
|
|
221
|
+
output: string | null;
|
|
222
|
+
structuredOutput: T extends void ? undefined : T;
|
|
223
|
+
toolCalls: Array<{
|
|
224
|
+
toolName: string;
|
|
225
|
+
args: JSONValue;
|
|
226
|
+
result: JSONValue;
|
|
227
|
+
approved: boolean;
|
|
228
|
+
}>;
|
|
229
|
+
messages: Message[];
|
|
230
|
+
usage?: {
|
|
231
|
+
promptTokens: number;
|
|
232
|
+
completionTokens: number;
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/** Agent lifecycle state */
|
|
236
|
+
type AgentState = "idle" | "running" | "streaming" | "disposed";
|
|
237
|
+
/** Core agent interface — run prompts, stream events, manage lifecycle */
|
|
238
|
+
interface IAgent {
|
|
239
|
+
run(prompt: MessageContent, options?: RunOptions): Promise<AgentResult>;
|
|
240
|
+
runWithContext(messages: Message[], options?: RunOptions): Promise<AgentResult>;
|
|
241
|
+
runStructured<T>(prompt: MessageContent, schema: StructuredOutputConfig<T>, options?: RunOptions): Promise<AgentResult<T>>;
|
|
242
|
+
stream(prompt: MessageContent, options?: RunOptions): AsyncIterable<AgentEvent>;
|
|
243
|
+
abort(): void;
|
|
244
|
+
getState(): AgentState;
|
|
245
|
+
getConfig(): Readonly<AgentConfig>;
|
|
246
|
+
/** Release resources. After dispose(), agent must not be used. */
|
|
247
|
+
dispose(): void;
|
|
248
|
+
}
|
|
249
|
+
/** Model metadata returned by listModels() */
|
|
250
|
+
interface ModelInfo {
|
|
251
|
+
id: string;
|
|
252
|
+
name?: string;
|
|
253
|
+
provider?: string;
|
|
254
|
+
}
|
|
255
|
+
/** Result of backend validation check */
|
|
256
|
+
interface ValidationResult {
|
|
257
|
+
valid: boolean;
|
|
258
|
+
errors: string[];
|
|
259
|
+
}
|
|
260
|
+
/** Backend service interface — creates agents, lists models, validates config */
|
|
261
|
+
interface IAgentService {
|
|
262
|
+
readonly name: string;
|
|
263
|
+
createAgent(config: AgentConfig): IAgent;
|
|
264
|
+
listModels(): Promise<ModelInfo[]>;
|
|
265
|
+
validate(): Promise<ValidationResult>;
|
|
266
|
+
dispose(): Promise<void>;
|
|
267
|
+
}
|
|
268
|
+
/** Options for Copilot CLI backend */
|
|
269
|
+
interface CopilotBackendOptions {
|
|
270
|
+
cliPath?: string;
|
|
271
|
+
workingDirectory?: string;
|
|
272
|
+
githubToken?: string;
|
|
273
|
+
useLoggedInUser?: boolean;
|
|
274
|
+
}
|
|
275
|
+
/** Options for Claude CLI backend */
|
|
276
|
+
interface ClaudeBackendOptions {
|
|
277
|
+
cliPath?: string;
|
|
278
|
+
workingDirectory?: string;
|
|
279
|
+
maxTurns?: number;
|
|
280
|
+
}
|
|
281
|
+
/** Options for Vercel AI SDK backend */
|
|
282
|
+
interface VercelAIBackendOptions {
|
|
283
|
+
apiKey: string;
|
|
284
|
+
provider?: string;
|
|
285
|
+
baseUrl?: string;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export type { CopilotBackendOptions as C, IAgentService as I, VercelAIBackendOptions as V, ClaudeBackendOptions as a };
|
package/package.json
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@witqq/agent-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Universal AI agent abstraction layer supporting Copilot CLI, Claude CLI, and Vercel AI SDK backends",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"./copilot": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/backends/copilot.d.ts",
|
|
23
|
+
"default": "./dist/backends/copilot.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/backends/copilot.d.cts",
|
|
27
|
+
"default": "./dist/backends/copilot.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"./claude": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/backends/claude.d.ts",
|
|
33
|
+
"default": "./dist/backends/claude.js"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/backends/claude.d.cts",
|
|
37
|
+
"default": "./dist/backends/claude.cjs"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"./vercel-ai": {
|
|
41
|
+
"import": {
|
|
42
|
+
"types": "./dist/backends/vercel-ai.d.ts",
|
|
43
|
+
"default": "./dist/backends/vercel-ai.js"
|
|
44
|
+
},
|
|
45
|
+
"require": {
|
|
46
|
+
"types": "./dist/backends/vercel-ai.d.cts",
|
|
47
|
+
"default": "./dist/backends/vercel-ai.cjs"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"files": [
|
|
52
|
+
"dist",
|
|
53
|
+
"README.md"
|
|
54
|
+
],
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsup",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"test:watch": "vitest",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"lint": "tsc --noEmit",
|
|
61
|
+
"prepublishOnly": "npm run build"
|
|
62
|
+
},
|
|
63
|
+
"keywords": [
|
|
64
|
+
"ai",
|
|
65
|
+
"agent",
|
|
66
|
+
"copilot",
|
|
67
|
+
"claude",
|
|
68
|
+
"vercel-ai",
|
|
69
|
+
"llm",
|
|
70
|
+
"tools",
|
|
71
|
+
"sdk"
|
|
72
|
+
],
|
|
73
|
+
"license": "MIT",
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=18"
|
|
76
|
+
},
|
|
77
|
+
"peerDependencies": {
|
|
78
|
+
"@ai-sdk/openai-compatible": ">=2.0.0",
|
|
79
|
+
"@anthropic-ai/claude-agent-sdk": ">=0.2.0",
|
|
80
|
+
"@github/copilot-sdk": "^0.1.22",
|
|
81
|
+
"ai": ">=4.0.0",
|
|
82
|
+
"zod": "^3.23.0"
|
|
83
|
+
},
|
|
84
|
+
"peerDependenciesMeta": {
|
|
85
|
+
"@github/copilot-sdk": {
|
|
86
|
+
"optional": true
|
|
87
|
+
},
|
|
88
|
+
"@anthropic-ai/claude-agent-sdk": {
|
|
89
|
+
"optional": true
|
|
90
|
+
},
|
|
91
|
+
"ai": {
|
|
92
|
+
"optional": true
|
|
93
|
+
},
|
|
94
|
+
"@ai-sdk/openai-compatible": {
|
|
95
|
+
"optional": true
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"devDependencies": {
|
|
99
|
+
"@ai-sdk/openai-compatible": "^2.0.27",
|
|
100
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.34",
|
|
101
|
+
"@github/copilot-sdk": "^0.1.22",
|
|
102
|
+
"@types/node": "^25.2.1",
|
|
103
|
+
"ai": "^6.0.73",
|
|
104
|
+
"testfold": "^0.2.1",
|
|
105
|
+
"tsup": "^8.4.0",
|
|
106
|
+
"typescript": "^5.8.0",
|
|
107
|
+
"vitest": "^3.0.0",
|
|
108
|
+
"zod": "^3.24.0"
|
|
109
|
+
}
|
|
110
|
+
}
|