@witqq/agent-sdk 0.6.1 → 0.8.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/README.md +539 -6
- package/dist/{types-BvwNzZCj.d.cts → agent-CW9XbmG_.d.ts} +148 -95
- package/dist/{types-BvwNzZCj.d.ts → agent-DxY68NZL.d.cts} +148 -95
- package/dist/auth/index.cjs +260 -2
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.d.cts +21 -138
- package/dist/auth/index.d.ts +21 -138
- package/dist/auth/index.js +260 -3
- package/dist/auth/index.js.map +1 -1
- package/dist/backends/claude.cjs +653 -140
- package/dist/backends/claude.cjs.map +1 -1
- package/dist/backends/claude.d.cts +4 -1
- package/dist/backends/claude.d.ts +4 -1
- package/dist/backends/claude.js +653 -140
- package/dist/backends/claude.js.map +1 -1
- package/dist/backends/copilot.cjs +428 -88
- package/dist/backends/copilot.cjs.map +1 -1
- package/dist/backends/copilot.d.cts +13 -4
- package/dist/backends/copilot.d.ts +13 -4
- package/dist/backends/copilot.js +428 -88
- package/dist/backends/copilot.js.map +1 -1
- package/dist/backends/vercel-ai.cjs +349 -77
- package/dist/backends/vercel-ai.cjs.map +1 -1
- package/dist/backends/vercel-ai.d.cts +3 -1
- package/dist/backends/vercel-ai.d.ts +3 -1
- package/dist/backends/vercel-ai.js +349 -77
- package/dist/backends/vercel-ai.js.map +1 -1
- package/dist/backends-BSrsBYFn.d.cts +39 -0
- package/dist/backends-BSrsBYFn.d.ts +39 -0
- package/dist/chat/accumulator.cjs +147 -0
- package/dist/chat/accumulator.cjs.map +1 -0
- package/dist/chat/accumulator.d.cts +64 -0
- package/dist/chat/accumulator.d.ts +64 -0
- package/dist/chat/accumulator.js +145 -0
- package/dist/chat/accumulator.js.map +1 -0
- package/dist/chat/backends.cjs +3524 -0
- package/dist/chat/backends.cjs.map +1 -0
- package/dist/chat/backends.d.cts +66 -0
- package/dist/chat/backends.d.ts +66 -0
- package/dist/chat/backends.js +3512 -0
- package/dist/chat/backends.js.map +1 -0
- package/dist/chat/context.cjs +280 -0
- package/dist/chat/context.cjs.map +1 -0
- package/dist/chat/context.d.cts +191 -0
- package/dist/chat/context.d.ts +191 -0
- package/dist/chat/context.js +277 -0
- package/dist/chat/context.js.map +1 -0
- package/dist/chat/core.cjs +305 -0
- package/dist/chat/core.cjs.map +1 -0
- package/dist/chat/core.d.cts +84 -0
- package/dist/chat/core.d.ts +84 -0
- package/dist/chat/core.js +282 -0
- package/dist/chat/core.js.map +1 -0
- package/dist/chat/errors.cjs +273 -0
- package/dist/chat/errors.cjs.map +1 -0
- package/dist/chat/errors.d.cts +97 -0
- package/dist/chat/errors.d.ts +97 -0
- package/dist/chat/errors.js +266 -0
- package/dist/chat/errors.js.map +1 -0
- package/dist/chat/events.cjs +203 -0
- package/dist/chat/events.cjs.map +1 -0
- package/dist/chat/events.d.cts +245 -0
- package/dist/chat/events.d.ts +245 -0
- package/dist/chat/events.js +196 -0
- package/dist/chat/events.js.map +1 -0
- package/dist/chat/index.cjs +5550 -0
- package/dist/chat/index.cjs.map +1 -0
- package/dist/chat/index.d.cts +77 -0
- package/dist/chat/index.d.ts +77 -0
- package/dist/chat/index.js +5505 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/react/theme.css +2517 -0
- package/dist/chat/react.cjs +3589 -0
- package/dist/chat/react.cjs.map +1 -0
- package/dist/chat/react.d.cts +1088 -0
- package/dist/chat/react.d.ts +1088 -0
- package/dist/chat/react.js +3547 -0
- package/dist/chat/react.js.map +1 -0
- package/dist/chat/runtime.cjs +1245 -0
- package/dist/chat/runtime.cjs.map +1 -0
- package/dist/chat/runtime.d.cts +182 -0
- package/dist/chat/runtime.d.ts +182 -0
- package/dist/chat/runtime.js +1243 -0
- package/dist/chat/runtime.js.map +1 -0
- package/dist/chat/server.cjs +2668 -0
- package/dist/chat/server.cjs.map +1 -0
- package/dist/chat/server.d.cts +648 -0
- package/dist/chat/server.d.ts +648 -0
- package/dist/chat/server.js +2628 -0
- package/dist/chat/server.js.map +1 -0
- package/dist/chat/sessions.cjs +380 -0
- package/dist/chat/sessions.cjs.map +1 -0
- package/dist/chat/sessions.d.cts +158 -0
- package/dist/chat/sessions.d.ts +158 -0
- package/dist/chat/sessions.js +376 -0
- package/dist/chat/sessions.js.map +1 -0
- package/dist/chat/sqlite.cjs +441 -0
- package/dist/chat/sqlite.cjs.map +1 -0
- package/dist/chat/sqlite.d.cts +128 -0
- package/dist/chat/sqlite.d.ts +128 -0
- package/dist/chat/sqlite.js +435 -0
- package/dist/chat/sqlite.js.map +1 -0
- package/dist/chat/state.cjs +190 -0
- package/dist/chat/state.cjs.map +1 -0
- package/dist/chat/state.d.cts +95 -0
- package/dist/chat/state.d.ts +95 -0
- package/dist/chat/state.js +180 -0
- package/dist/chat/state.js.map +1 -0
- package/dist/chat/storage.cjs +249 -0
- package/dist/chat/storage.cjs.map +1 -0
- package/dist/chat/storage.d.cts +197 -0
- package/dist/chat/storage.d.ts +197 -0
- package/dist/chat/storage.js +245 -0
- package/dist/chat/storage.js.map +1 -0
- package/dist/errors-C-so0M4t.d.cts +33 -0
- package/dist/errors-C-so0M4t.d.ts +33 -0
- package/dist/errors-CmVvczxZ.d.cts +28 -0
- package/dist/errors-CmVvczxZ.d.ts +28 -0
- package/dist/in-process-transport-C1JnJGVR.d.ts +228 -0
- package/dist/in-process-transport-C7DSqPyX.d.cts +228 -0
- package/dist/index.cjs +365 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +322 -125
- package/dist/index.d.ts +322 -125
- package/dist/index.js +359 -60
- package/dist/index.js.map +1 -1
- package/dist/provider-types-PTSlRPNB.d.cts +39 -0
- package/dist/provider-types-PTSlRPNB.d.ts +39 -0
- package/dist/refresh-manager-B81PpYBr.d.cts +153 -0
- package/dist/refresh-manager-Dlv_iNZi.d.ts +153 -0
- package/dist/testing.cjs +383 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +132 -0
- package/dist/testing.d.ts +132 -0
- package/dist/testing.js +377 -0
- package/dist/testing.js.map +1 -0
- package/dist/token-store-CSUBgYwn.d.ts +48 -0
- package/dist/token-store-CuC4hB9Z.d.cts +48 -0
- package/dist/transport-Cdh3M0tS.d.cts +68 -0
- package/dist/transport-Ciap4PWK.d.ts +68 -0
- package/dist/types-4vbcmPTp.d.cts +143 -0
- package/dist/types-BxggH0Yh.d.ts +143 -0
- package/dist/types-DRgd_9R7.d.cts +363 -0
- package/dist/types-ajANVzf7.d.ts +363 -0
- package/package.json +178 -6
package/dist/index.js
CHANGED
|
@@ -2,7 +2,76 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
|
|
5
|
-
// src/types.ts
|
|
5
|
+
// src/types/errors.ts
|
|
6
|
+
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
|
7
|
+
ErrorCode2["AUTH_EXPIRED"] = "AUTH_EXPIRED";
|
|
8
|
+
ErrorCode2["AUTH_INVALID"] = "AUTH_INVALID";
|
|
9
|
+
ErrorCode2["RATE_LIMIT"] = "RATE_LIMIT";
|
|
10
|
+
ErrorCode2["NETWORK"] = "NETWORK";
|
|
11
|
+
ErrorCode2["TIMEOUT"] = "TIMEOUT";
|
|
12
|
+
ErrorCode2["PROVIDER_ERROR"] = "PROVIDER_ERROR";
|
|
13
|
+
ErrorCode2["MODEL_NOT_FOUND"] = "MODEL_NOT_FOUND";
|
|
14
|
+
ErrorCode2["MODEL_OVERLOADED"] = "MODEL_OVERLOADED";
|
|
15
|
+
ErrorCode2["CONTEXT_OVERFLOW"] = "CONTEXT_OVERFLOW";
|
|
16
|
+
ErrorCode2["INVALID_INPUT"] = "INVALID_INPUT";
|
|
17
|
+
ErrorCode2["INVALID_RESPONSE"] = "INVALID_RESPONSE";
|
|
18
|
+
ErrorCode2["REENTRANCY"] = "REENTRANCY";
|
|
19
|
+
ErrorCode2["DISPOSED"] = "DISPOSED";
|
|
20
|
+
ErrorCode2["ABORTED"] = "ABORTED";
|
|
21
|
+
ErrorCode2["INVALID_TRANSITION"] = "INVALID_TRANSITION";
|
|
22
|
+
ErrorCode2["DEPENDENCY_MISSING"] = "DEPENDENCY_MISSING";
|
|
23
|
+
ErrorCode2["BACKEND_NOT_INSTALLED"] = "BACKEND_NOT_INSTALLED";
|
|
24
|
+
ErrorCode2["TOOL_EXECUTION"] = "TOOL_EXECUTION";
|
|
25
|
+
ErrorCode2["PERMISSION_DENIED"] = "PERMISSION_DENIED";
|
|
26
|
+
ErrorCode2["SESSION_NOT_FOUND"] = "SESSION_NOT_FOUND";
|
|
27
|
+
ErrorCode2["SESSION_EXPIRED"] = "SESSION_EXPIRED";
|
|
28
|
+
ErrorCode2["PROVIDER_NOT_FOUND"] = "PROVIDER_NOT_FOUND";
|
|
29
|
+
ErrorCode2["AUTH_REQUIRED"] = "AUTH_REQUIRED";
|
|
30
|
+
ErrorCode2["STORAGE_ERROR"] = "STORAGE_ERROR";
|
|
31
|
+
ErrorCode2["STORAGE_NOT_FOUND"] = "STORAGE_NOT_FOUND";
|
|
32
|
+
ErrorCode2["STORAGE_DUPLICATE_KEY"] = "STORAGE_DUPLICATE_KEY";
|
|
33
|
+
ErrorCode2["STORAGE_IO_ERROR"] = "STORAGE_IO_ERROR";
|
|
34
|
+
ErrorCode2["STORAGE_SERIALIZATION_ERROR"] = "STORAGE_SERIALIZATION_ERROR";
|
|
35
|
+
return ErrorCode2;
|
|
36
|
+
})(ErrorCode || {});
|
|
37
|
+
var RECOVERABLE_CODES = /* @__PURE__ */ new Set([
|
|
38
|
+
"TIMEOUT" /* TIMEOUT */,
|
|
39
|
+
"RATE_LIMIT" /* RATE_LIMIT */,
|
|
40
|
+
"NETWORK" /* NETWORK */,
|
|
41
|
+
"TOOL_EXECUTION" /* TOOL_EXECUTION */,
|
|
42
|
+
"MODEL_OVERLOADED" /* MODEL_OVERLOADED */,
|
|
43
|
+
"PROVIDER_ERROR" /* PROVIDER_ERROR */
|
|
44
|
+
]);
|
|
45
|
+
function isRecoverableErrorCode(code) {
|
|
46
|
+
return RECOVERABLE_CODES.has(code);
|
|
47
|
+
}
|
|
48
|
+
function classifyAgentError(error) {
|
|
49
|
+
const msg = (error instanceof Error ? error.message : error).toLowerCase();
|
|
50
|
+
if (msg.includes("timeout") || msg.includes("timed out") || msg.includes("timedout") || msg.includes("etimedout")) {
|
|
51
|
+
return "TIMEOUT" /* TIMEOUT */;
|
|
52
|
+
}
|
|
53
|
+
if (msg.includes("rate limit") || msg.includes("rate_limit") || msg.includes("429") || msg.includes("too many requests")) {
|
|
54
|
+
return "RATE_LIMIT" /* RATE_LIMIT */;
|
|
55
|
+
}
|
|
56
|
+
if (msg.includes("unauthorized") || msg.includes("401") || msg.includes("auth") && (msg.includes("expired") || msg.includes("invalid") || msg.includes("denied") || msg.includes("failed"))) {
|
|
57
|
+
return "AUTH_EXPIRED" /* AUTH_EXPIRED */;
|
|
58
|
+
}
|
|
59
|
+
if (msg.includes("econnrefused") || msg.includes("econnreset") || msg.includes("enotfound") || msg.includes("network") || msg.includes("fetch failed") || msg.includes("socket hang up")) {
|
|
60
|
+
return "NETWORK" /* NETWORK */;
|
|
61
|
+
}
|
|
62
|
+
if (msg.includes("subprocess") || msg.includes("process exited") || msg.includes("spawn") || msg.includes("enoent") || msg.includes("killed")) {
|
|
63
|
+
return "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */;
|
|
64
|
+
}
|
|
65
|
+
if (msg.includes("abort") || msg.includes("cancel")) {
|
|
66
|
+
return "ABORTED" /* ABORTED */;
|
|
67
|
+
}
|
|
68
|
+
if (msg.includes("500") || msg.includes("502") || msg.includes("503") || msg.includes("internal server error") || msg.includes("service unavailable") || msg.includes("bad gateway") || msg.includes("overloaded")) {
|
|
69
|
+
return "PROVIDER_ERROR" /* PROVIDER_ERROR */;
|
|
70
|
+
}
|
|
71
|
+
return "PROVIDER_ERROR" /* PROVIDER_ERROR */;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/types/guards.ts
|
|
6
75
|
function isToolDefinition(tool) {
|
|
7
76
|
return "execute" in tool && typeof tool.execute === "function";
|
|
8
77
|
}
|
|
@@ -19,27 +88,47 @@ function getTextContent(content) {
|
|
|
19
88
|
|
|
20
89
|
// src/errors.ts
|
|
21
90
|
var AgentSDKError = class extends Error {
|
|
91
|
+
/** @internal Marker for cross-bundle identity checks */
|
|
92
|
+
_agentSDKError = true;
|
|
93
|
+
/** Machine-readable error code. Prefer values from the ErrorCode enum. */
|
|
94
|
+
code;
|
|
95
|
+
/** Whether this error is safe to retry */
|
|
96
|
+
retryable;
|
|
97
|
+
/** HTTP status code hint for error classification */
|
|
98
|
+
httpStatus;
|
|
22
99
|
constructor(message, options) {
|
|
23
100
|
super(message, options);
|
|
24
101
|
this.name = "AgentSDKError";
|
|
102
|
+
this.code = options?.code;
|
|
103
|
+
this.retryable = options?.retryable ?? false;
|
|
104
|
+
this.httpStatus = options?.httpStatus;
|
|
105
|
+
}
|
|
106
|
+
/** Check if an error is an AgentSDKError (works across bundled copies) */
|
|
107
|
+
static is(error) {
|
|
108
|
+
return error instanceof Error && "_agentSDKError" in error && error._agentSDKError === true;
|
|
25
109
|
}
|
|
26
110
|
};
|
|
27
111
|
var ReentrancyError = class extends AgentSDKError {
|
|
28
112
|
constructor() {
|
|
29
|
-
super("Agent is already running. Await the current run before starting another."
|
|
113
|
+
super("Agent is already running. Await the current run before starting another.", {
|
|
114
|
+
code: "REENTRANCY" /* REENTRANCY */
|
|
115
|
+
});
|
|
30
116
|
this.name = "ReentrancyError";
|
|
31
117
|
}
|
|
32
118
|
};
|
|
33
119
|
var DisposedError = class extends AgentSDKError {
|
|
34
120
|
constructor(entity) {
|
|
35
|
-
super(`${entity} has been disposed and cannot be used
|
|
121
|
+
super(`${entity} has been disposed and cannot be used.`, {
|
|
122
|
+
code: "DISPOSED" /* DISPOSED */
|
|
123
|
+
});
|
|
36
124
|
this.name = "DisposedError";
|
|
37
125
|
}
|
|
38
126
|
};
|
|
39
127
|
var BackendNotFoundError = class extends AgentSDKError {
|
|
40
128
|
constructor(backend) {
|
|
41
129
|
super(
|
|
42
|
-
`Unknown backend: "${backend}". Built-in: copilot, claude, vercel-ai. Custom: use registerBackend() first
|
|
130
|
+
`Unknown backend: "${backend}". Built-in: copilot, claude, vercel-ai. Custom: use registerBackend() first.`,
|
|
131
|
+
{ code: "BACKEND_NOT_INSTALLED" /* BACKEND_NOT_INSTALLED */ }
|
|
43
132
|
);
|
|
44
133
|
this.name = "BackendNotFoundError";
|
|
45
134
|
}
|
|
@@ -52,41 +141,56 @@ var BackendAlreadyRegisteredError = class extends AgentSDKError {
|
|
|
52
141
|
};
|
|
53
142
|
var SubprocessError = class extends AgentSDKError {
|
|
54
143
|
constructor(message, options) {
|
|
55
|
-
super(message, options);
|
|
144
|
+
super(message, { ...options, code: "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */ });
|
|
56
145
|
this.name = "SubprocessError";
|
|
57
146
|
}
|
|
58
147
|
};
|
|
59
148
|
var DependencyError = class extends AgentSDKError {
|
|
60
149
|
packageName;
|
|
61
150
|
constructor(packageName) {
|
|
62
|
-
super(`${packageName} is not installed. Install it: npm install ${packageName}
|
|
151
|
+
super(`${packageName} is not installed. Install it: npm install ${packageName}`, {
|
|
152
|
+
code: "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */
|
|
153
|
+
});
|
|
63
154
|
this.name = "DependencyError";
|
|
64
155
|
this.packageName = packageName;
|
|
65
156
|
}
|
|
66
157
|
};
|
|
67
158
|
var AbortError = class extends AgentSDKError {
|
|
68
159
|
constructor() {
|
|
69
|
-
super("Agent run was aborted.");
|
|
160
|
+
super("Agent run was aborted.", { code: "ABORTED" /* ABORTED */ });
|
|
70
161
|
this.name = "AbortError";
|
|
71
162
|
}
|
|
72
163
|
};
|
|
73
164
|
var ToolExecutionError = class extends AgentSDKError {
|
|
74
165
|
toolName;
|
|
75
166
|
constructor(toolName, message, options) {
|
|
76
|
-
super(`Tool "${toolName}" failed: ${message}`, options);
|
|
167
|
+
super(`Tool "${toolName}" failed: ${message}`, { ...options, code: "TOOL_EXECUTION" /* TOOL_EXECUTION */ });
|
|
77
168
|
this.name = "ToolExecutionError";
|
|
78
169
|
this.toolName = toolName;
|
|
79
170
|
}
|
|
80
171
|
};
|
|
172
|
+
var ActivityTimeoutError = class extends AgentSDKError {
|
|
173
|
+
constructor(timeoutMs) {
|
|
174
|
+
super(`Stream activity timeout: no event received within ${timeoutMs}ms.`, {
|
|
175
|
+
code: "TIMEOUT" /* TIMEOUT */,
|
|
176
|
+
retryable: true
|
|
177
|
+
});
|
|
178
|
+
this.name = "ActivityTimeoutError";
|
|
179
|
+
}
|
|
180
|
+
};
|
|
81
181
|
var StructuredOutputError = class extends AgentSDKError {
|
|
82
182
|
constructor(message, options) {
|
|
83
|
-
super(`Structured output error: ${message}`, options);
|
|
183
|
+
super(`Structured output error: ${message}`, { ...options, code: "INVALID_RESPONSE" /* INVALID_RESPONSE */ });
|
|
84
184
|
this.name = "StructuredOutputError";
|
|
85
185
|
}
|
|
86
186
|
};
|
|
87
187
|
|
|
88
188
|
// src/registry.ts
|
|
89
189
|
var registry = /* @__PURE__ */ new Map();
|
|
190
|
+
var serviceCache = /* @__PURE__ */ new Map();
|
|
191
|
+
function configCacheKey(name, configId) {
|
|
192
|
+
return `${name}:${configId}`;
|
|
193
|
+
}
|
|
90
194
|
function registerBackend(name, factory) {
|
|
91
195
|
if (registry.has(name)) {
|
|
92
196
|
throw new BackendAlreadyRegisteredError(name);
|
|
@@ -97,49 +201,94 @@ function unregisterBackend(name) {
|
|
|
97
201
|
return registry.delete(name);
|
|
98
202
|
}
|
|
99
203
|
function hasBackend(name) {
|
|
100
|
-
return registry.has(name) ||
|
|
204
|
+
return registry.has(name) || lazyLoaders.has(name);
|
|
101
205
|
}
|
|
102
206
|
function listBackends() {
|
|
103
207
|
const names = new Set(registry.keys());
|
|
104
|
-
for (const
|
|
105
|
-
names.add(
|
|
208
|
+
for (const name of lazyLoaders.keys()) {
|
|
209
|
+
names.add(name);
|
|
106
210
|
}
|
|
107
211
|
return [...names];
|
|
108
212
|
}
|
|
109
213
|
function resetRegistry() {
|
|
110
214
|
registry.clear();
|
|
215
|
+
serviceCache.clear();
|
|
111
216
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
217
|
+
async function disposeBackend(name, configId) {
|
|
218
|
+
if (configId !== void 0) {
|
|
219
|
+
const key = configCacheKey(name, configId);
|
|
220
|
+
const svc = serviceCache.get(key);
|
|
221
|
+
if (!svc) return 0;
|
|
222
|
+
serviceCache.delete(key);
|
|
223
|
+
await svc.dispose();
|
|
224
|
+
return 1;
|
|
225
|
+
}
|
|
226
|
+
const prefix = `${name}:`;
|
|
227
|
+
const toDispose = [];
|
|
228
|
+
for (const [key, svc] of serviceCache) {
|
|
229
|
+
if (key.startsWith(prefix)) {
|
|
230
|
+
toDispose.push(svc);
|
|
231
|
+
serviceCache.delete(key);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
await Promise.all(toDispose.map((s) => s.dispose()));
|
|
235
|
+
return toDispose.length;
|
|
236
|
+
}
|
|
237
|
+
function listConfigs(name) {
|
|
238
|
+
const prefix = `${name}:`;
|
|
239
|
+
const ids = [];
|
|
240
|
+
for (const key of serviceCache.keys()) {
|
|
241
|
+
if (key.startsWith(prefix)) {
|
|
242
|
+
ids.push(key.slice(prefix.length));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return ids;
|
|
119
246
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
247
|
+
var lazyLoaders = /* @__PURE__ */ new Map([
|
|
248
|
+
[
|
|
249
|
+
"copilot",
|
|
250
|
+
async () => {
|
|
123
251
|
const mod = await import('./backends/copilot.js');
|
|
124
252
|
return (opts) => mod.createCopilotService(opts);
|
|
125
253
|
}
|
|
126
|
-
|
|
254
|
+
],
|
|
255
|
+
[
|
|
256
|
+
"claude",
|
|
257
|
+
async () => {
|
|
127
258
|
const mod = await import('./backends/claude.js');
|
|
128
259
|
return (opts) => mod.createClaudeService(opts);
|
|
129
260
|
}
|
|
130
|
-
|
|
261
|
+
],
|
|
262
|
+
[
|
|
263
|
+
"vercel-ai",
|
|
264
|
+
async () => {
|
|
131
265
|
const mod = await import('./backends/vercel-ai.js');
|
|
132
266
|
return (opts) => mod.createVercelAIService(opts);
|
|
133
267
|
}
|
|
134
|
-
|
|
268
|
+
]
|
|
269
|
+
]);
|
|
270
|
+
function registerLazyBackend(name, loader) {
|
|
271
|
+
lazyLoaders.set(name, loader);
|
|
135
272
|
}
|
|
136
|
-
async function createAgentService(name, options) {
|
|
273
|
+
async function createAgentService(name, options, configId) {
|
|
274
|
+
if (configId !== void 0) {
|
|
275
|
+
const key = configCacheKey(name, configId);
|
|
276
|
+
const cached = serviceCache.get(key);
|
|
277
|
+
if (cached) return cached;
|
|
278
|
+
const service = await createServiceInstance(name, options);
|
|
279
|
+
serviceCache.set(key, service);
|
|
280
|
+
return service;
|
|
281
|
+
}
|
|
282
|
+
return createServiceInstance(name, options);
|
|
283
|
+
}
|
|
284
|
+
async function createServiceInstance(name, options) {
|
|
137
285
|
const entry = registry.get(name);
|
|
138
286
|
if (entry) {
|
|
139
287
|
return entry.factory(options);
|
|
140
288
|
}
|
|
141
|
-
|
|
142
|
-
|
|
289
|
+
const loader = lazyLoaders.get(name);
|
|
290
|
+
if (loader) {
|
|
291
|
+
const factory = await loader();
|
|
143
292
|
registry.set(name, { factory, builtin: true });
|
|
144
293
|
return factory(options);
|
|
145
294
|
}
|
|
@@ -151,6 +300,8 @@ var BaseAgent = class {
|
|
|
151
300
|
state = "idle";
|
|
152
301
|
abortController = null;
|
|
153
302
|
config;
|
|
303
|
+
_cleanupExternalSignal = null;
|
|
304
|
+
_streamMiddleware = [];
|
|
154
305
|
/** CLI session ID for persistent mode. Override in backends that support it. */
|
|
155
306
|
get sessionId() {
|
|
156
307
|
return void 0;
|
|
@@ -166,12 +317,14 @@ var BaseAgent = class {
|
|
|
166
317
|
this.state = "running";
|
|
167
318
|
try {
|
|
168
319
|
const messages = [{ role: "user", content: prompt }];
|
|
169
|
-
const result = await this.
|
|
170
|
-
|
|
320
|
+
const result = await this.withRetry(
|
|
321
|
+
() => this.executeRun(messages, options, ac.signal),
|
|
322
|
+
options
|
|
323
|
+
);
|
|
324
|
+
this.enrichAndNotifyUsage(result, options);
|
|
171
325
|
return result;
|
|
172
326
|
} finally {
|
|
173
|
-
this.
|
|
174
|
-
this.abortController = null;
|
|
327
|
+
this.cleanupRun();
|
|
175
328
|
}
|
|
176
329
|
}
|
|
177
330
|
async runWithContext(messages, options) {
|
|
@@ -180,12 +333,14 @@ var BaseAgent = class {
|
|
|
180
333
|
const ac = this.createAbortController(options?.signal);
|
|
181
334
|
this.state = "running";
|
|
182
335
|
try {
|
|
183
|
-
const result = await this.
|
|
184
|
-
|
|
336
|
+
const result = await this.withRetry(
|
|
337
|
+
() => this.executeRun(messages, options, ac.signal),
|
|
338
|
+
options
|
|
339
|
+
);
|
|
340
|
+
this.enrichAndNotifyUsage(result, options);
|
|
185
341
|
return result;
|
|
186
342
|
} finally {
|
|
187
|
-
this.
|
|
188
|
-
this.abortController = null;
|
|
343
|
+
this.cleanupRun();
|
|
189
344
|
}
|
|
190
345
|
}
|
|
191
346
|
async runStructured(prompt, schema, options) {
|
|
@@ -195,17 +350,14 @@ var BaseAgent = class {
|
|
|
195
350
|
this.state = "running";
|
|
196
351
|
try {
|
|
197
352
|
const messages = [{ role: "user", content: prompt }];
|
|
198
|
-
const result = await this.
|
|
199
|
-
messages,
|
|
200
|
-
|
|
201
|
-
options,
|
|
202
|
-
ac.signal
|
|
353
|
+
const result = await this.withRetry(
|
|
354
|
+
() => this.executeRunStructured(messages, schema, options, ac.signal),
|
|
355
|
+
options
|
|
203
356
|
);
|
|
204
|
-
this.enrichAndNotifyUsage(result);
|
|
357
|
+
this.enrichAndNotifyUsage(result, options);
|
|
205
358
|
return result;
|
|
206
359
|
} finally {
|
|
207
|
-
this.
|
|
208
|
-
this.abortController = null;
|
|
360
|
+
this.cleanupRun();
|
|
209
361
|
}
|
|
210
362
|
}
|
|
211
363
|
async *stream(prompt, options) {
|
|
@@ -215,11 +367,12 @@ var BaseAgent = class {
|
|
|
215
367
|
this.state = "streaming";
|
|
216
368
|
try {
|
|
217
369
|
const messages = [{ role: "user", content: prompt }];
|
|
218
|
-
|
|
219
|
-
|
|
370
|
+
yield* this.streamWithRetry(
|
|
371
|
+
() => this.applyStreamPipeline(this.executeStream(messages, options, ac.signal), options, ac),
|
|
372
|
+
options
|
|
373
|
+
);
|
|
220
374
|
} finally {
|
|
221
|
-
this.
|
|
222
|
-
this.abortController = null;
|
|
375
|
+
this.cleanupRun();
|
|
223
376
|
}
|
|
224
377
|
}
|
|
225
378
|
async *streamWithContext(messages, options) {
|
|
@@ -228,12 +381,36 @@ var BaseAgent = class {
|
|
|
228
381
|
const ac = this.createAbortController(options?.signal);
|
|
229
382
|
this.state = "streaming";
|
|
230
383
|
try {
|
|
231
|
-
|
|
232
|
-
|
|
384
|
+
yield* this.streamWithRetry(
|
|
385
|
+
() => this.applyStreamPipeline(this.executeStream(messages, options, ac.signal), options, ac),
|
|
386
|
+
options
|
|
387
|
+
);
|
|
233
388
|
} finally {
|
|
234
|
-
this.
|
|
235
|
-
|
|
389
|
+
this.cleanupRun();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/** Register a stream middleware. Applied in registration order after built-in transforms. */
|
|
393
|
+
addStreamMiddleware(middleware) {
|
|
394
|
+
this.guardDisposed();
|
|
395
|
+
this._streamMiddleware.push(middleware);
|
|
396
|
+
}
|
|
397
|
+
/** Apply built-in transforms (enrich→timeout→heartbeat) then custom middleware */
|
|
398
|
+
async *applyStreamPipeline(source, options, ac) {
|
|
399
|
+
let stream = this.enrichStream(source, options);
|
|
400
|
+
stream = this.activityTimeoutStream(stream, options?.activityTimeoutMs, ac);
|
|
401
|
+
stream = this.heartbeatStream(stream);
|
|
402
|
+
if (this._streamMiddleware.length > 0) {
|
|
403
|
+
const ctx = {
|
|
404
|
+
model: options.model,
|
|
405
|
+
backend: this.backendName,
|
|
406
|
+
abortController: ac,
|
|
407
|
+
config: Object.freeze({ ...this.config })
|
|
408
|
+
};
|
|
409
|
+
for (const mw of this._streamMiddleware) {
|
|
410
|
+
stream = mw(stream, ctx);
|
|
411
|
+
}
|
|
236
412
|
}
|
|
413
|
+
yield* stream;
|
|
237
414
|
}
|
|
238
415
|
abort() {
|
|
239
416
|
if (this.abortController) {
|
|
@@ -252,29 +429,114 @@ var BaseAgent = class {
|
|
|
252
429
|
}
|
|
253
430
|
/** Mark agent as disposed. Override to add cleanup. */
|
|
254
431
|
dispose() {
|
|
432
|
+
this._cleanupExternalSignal?.();
|
|
433
|
+
this._cleanupExternalSignal = null;
|
|
255
434
|
this.abort();
|
|
256
435
|
this.state = "disposed";
|
|
257
436
|
}
|
|
437
|
+
// ─── Retry Logic ─────────────────────────────────────────────
|
|
438
|
+
/** Check if an error should be retried given the retry configuration. */
|
|
439
|
+
isRetryableError(error, retry) {
|
|
440
|
+
if (error instanceof AbortError || error instanceof ReentrancyError || error instanceof DisposedError) {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
if (AgentSDKError.is(error)) {
|
|
444
|
+
if (retry.retryableErrors && retry.retryableErrors.length > 0 && error.code) {
|
|
445
|
+
return retry.retryableErrors.includes(error.code);
|
|
446
|
+
}
|
|
447
|
+
if (error.retryable) return true;
|
|
448
|
+
if (error.code) return isRecoverableErrorCode(error.code);
|
|
449
|
+
}
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
/** Execute a function with retry logic per RetryConfig. */
|
|
453
|
+
async withRetry(fn, options) {
|
|
454
|
+
const retry = options?.retry;
|
|
455
|
+
if (!retry || !retry.maxRetries || retry.maxRetries <= 0) {
|
|
456
|
+
return fn();
|
|
457
|
+
}
|
|
458
|
+
const maxRetries = retry.maxRetries;
|
|
459
|
+
const initialDelay = retry.initialDelayMs ?? 1e3;
|
|
460
|
+
const multiplier = retry.backoffMultiplier ?? 2;
|
|
461
|
+
let lastError;
|
|
462
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
463
|
+
try {
|
|
464
|
+
return await fn();
|
|
465
|
+
} catch (err) {
|
|
466
|
+
lastError = err;
|
|
467
|
+
if (attempt >= maxRetries || !this.isRetryableError(err, retry)) {
|
|
468
|
+
throw err;
|
|
469
|
+
}
|
|
470
|
+
const delay = initialDelay * Math.pow(multiplier, attempt);
|
|
471
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
472
|
+
if (options?.signal?.aborted || this.abortController?.signal.aborted) {
|
|
473
|
+
throw err;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
throw lastError;
|
|
478
|
+
}
|
|
479
|
+
/** Execute a stream factory with pre-stream retry: retries until first event, then committed. */
|
|
480
|
+
async *streamWithRetry(factory, options) {
|
|
481
|
+
const retry = options?.retry;
|
|
482
|
+
if (!retry || !retry.maxRetries || retry.maxRetries <= 0) {
|
|
483
|
+
yield* factory();
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const maxRetries = retry.maxRetries;
|
|
487
|
+
const initialDelay = retry.initialDelayMs ?? 1e3;
|
|
488
|
+
const multiplier = retry.backoffMultiplier ?? 2;
|
|
489
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
490
|
+
try {
|
|
491
|
+
const stream = factory();
|
|
492
|
+
const iterator = stream[Symbol.asyncIterator]();
|
|
493
|
+
const first = await iterator.next();
|
|
494
|
+
if (first.done) return;
|
|
495
|
+
yield first.value;
|
|
496
|
+
while (true) {
|
|
497
|
+
const next = await iterator.next();
|
|
498
|
+
if (next.done) break;
|
|
499
|
+
yield next.value;
|
|
500
|
+
}
|
|
501
|
+
return;
|
|
502
|
+
} catch (err) {
|
|
503
|
+
if (attempt >= maxRetries || !this.isRetryableError(err, retry)) {
|
|
504
|
+
throw err;
|
|
505
|
+
}
|
|
506
|
+
const delay = initialDelay * Math.pow(multiplier, attempt);
|
|
507
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
508
|
+
if (options?.signal?.aborted || this.abortController?.signal.aborted) {
|
|
509
|
+
throw err;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
// ─── CallOptions Resolution ──────────────────────────────────
|
|
515
|
+
/** Resolve tools to use for this call (per-call override > config default) */
|
|
516
|
+
resolveTools(options) {
|
|
517
|
+
return options?.tools ?? this.config.tools ?? [];
|
|
518
|
+
}
|
|
258
519
|
// ─── Usage Enrichment ───────────────────────────────────────────
|
|
259
520
|
/** Enrich result usage with model/backend and fire onUsage callback */
|
|
260
|
-
enrichAndNotifyUsage(result) {
|
|
521
|
+
enrichAndNotifyUsage(result, options) {
|
|
261
522
|
if (result.usage) {
|
|
262
523
|
result.usage = {
|
|
263
524
|
...result.usage,
|
|
264
|
-
model:
|
|
525
|
+
model: options.model,
|
|
265
526
|
backend: this.backendName
|
|
266
527
|
};
|
|
267
528
|
this.callOnUsage(result.usage);
|
|
268
529
|
}
|
|
269
530
|
}
|
|
270
531
|
/** Wrap a stream to enrich usage_update events and fire onUsage callback */
|
|
271
|
-
async *enrichStream(source) {
|
|
532
|
+
async *enrichStream(source, options) {
|
|
533
|
+
const model = options.model;
|
|
272
534
|
for await (const event of source) {
|
|
273
535
|
if (event.type === "usage_update") {
|
|
274
536
|
const usage = {
|
|
275
537
|
promptTokens: event.promptTokens,
|
|
276
538
|
completionTokens: event.completionTokens,
|
|
277
|
-
model
|
|
539
|
+
model,
|
|
278
540
|
backend: this.backendName
|
|
279
541
|
};
|
|
280
542
|
this.callOnUsage(usage);
|
|
@@ -344,6 +606,35 @@ var BaseAgent = class {
|
|
|
344
606
|
heartbeatResolve = null;
|
|
345
607
|
}
|
|
346
608
|
}
|
|
609
|
+
// ─── Activity Timeout ────────────────────────────────────────
|
|
610
|
+
/** Wrap a stream to abort on inactivity. Resets timer on every event.
|
|
611
|
+
* When timeoutMs is not set, passes through directly. */
|
|
612
|
+
async *activityTimeoutStream(source, timeoutMs, ac) {
|
|
613
|
+
if (!timeoutMs || timeoutMs <= 0) {
|
|
614
|
+
yield* source;
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
618
|
+
let timerId;
|
|
619
|
+
try {
|
|
620
|
+
while (true) {
|
|
621
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
622
|
+
timerId = setTimeout(() => reject(new ActivityTimeoutError(timeoutMs)), timeoutMs);
|
|
623
|
+
});
|
|
624
|
+
const result = await Promise.race([iterator.next(), timeoutPromise]);
|
|
625
|
+
clearTimeout(timerId);
|
|
626
|
+
if (result.done) break;
|
|
627
|
+
yield result.value;
|
|
628
|
+
}
|
|
629
|
+
} catch (err) {
|
|
630
|
+
if (err instanceof ActivityTimeoutError) {
|
|
631
|
+
ac.abort(err);
|
|
632
|
+
}
|
|
633
|
+
throw err;
|
|
634
|
+
} finally {
|
|
635
|
+
clearTimeout(timerId);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
347
638
|
// ─── Guards ───────────────────────────────────────────────────
|
|
348
639
|
guardReentrancy() {
|
|
349
640
|
if (this.state === "running" || this.state === "streaming") {
|
|
@@ -362,16 +653,24 @@ var BaseAgent = class {
|
|
|
362
653
|
}
|
|
363
654
|
}
|
|
364
655
|
// ─── Internal Helpers ─────────────────────────────────────────
|
|
656
|
+
/** Clean up after a run completes (success, error, or abort). */
|
|
657
|
+
cleanupRun() {
|
|
658
|
+
this._cleanupExternalSignal?.();
|
|
659
|
+
this._cleanupExternalSignal = null;
|
|
660
|
+
this.state = "idle";
|
|
661
|
+
this.abortController = null;
|
|
662
|
+
}
|
|
365
663
|
createAbortController(externalSignal) {
|
|
366
664
|
const ac = new AbortController();
|
|
367
665
|
this.abortController = ac;
|
|
666
|
+
this._cleanupExternalSignal = null;
|
|
368
667
|
if (externalSignal) {
|
|
369
668
|
if (externalSignal.aborted) {
|
|
370
669
|
ac.abort();
|
|
371
670
|
} else {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
671
|
+
const listener = () => ac.abort();
|
|
672
|
+
externalSignal.addEventListener("abort", listener, { once: true });
|
|
673
|
+
this._cleanupExternalSignal = () => externalSignal.removeEventListener("abort", listener);
|
|
375
674
|
}
|
|
376
675
|
}
|
|
377
676
|
return ac;
|
|
@@ -568,6 +867,6 @@ function createDefaultPermissionStore(projectDir) {
|
|
|
568
867
|
return new CompositePermissionStore(sessionStore, projectStore, userStore);
|
|
569
868
|
}
|
|
570
869
|
|
|
571
|
-
export { AbortError, AgentSDKError, BackendAlreadyRegisteredError, BackendNotFoundError, BaseAgent, CompositePermissionStore, DependencyError, DisposedError, FilePermissionStore, InMemoryPermissionStore, ReentrancyError, StructuredOutputError, SubprocessError, ToolExecutionError, buildSystemPrompt, contentToText, createAgentService, createDefaultPermissionStore, getTextContent, hasBackend, isMultiPartContent, isTextContent, isToolDefinition, listBackends, messagesToPrompt, registerBackend, resetRegistry, unregisterBackend, zodToJsonSchema };
|
|
870
|
+
export { AbortError, ActivityTimeoutError, AgentSDKError, BackendAlreadyRegisteredError, BackendNotFoundError, BaseAgent, CompositePermissionStore, DependencyError, DisposedError, ErrorCode, FilePermissionStore, InMemoryPermissionStore, ReentrancyError, StructuredOutputError, SubprocessError, ToolExecutionError, buildSystemPrompt, classifyAgentError, contentToText, createAgentService, createDefaultPermissionStore, disposeBackend, getTextContent, hasBackend, isMultiPartContent, isRecoverableErrorCode, isTextContent, isToolDefinition, listBackends, listConfigs, messagesToPrompt, registerBackend, registerLazyBackend, resetRegistry, unregisterBackend, zodToJsonSchema };
|
|
572
871
|
//# sourceMappingURL=index.js.map
|
|
573
872
|
//# sourceMappingURL=index.js.map
|