@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.cjs
CHANGED
|
@@ -26,7 +26,76 @@ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
|
26
26
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
27
27
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
28
28
|
|
|
29
|
-
// src/types.ts
|
|
29
|
+
// src/types/errors.ts
|
|
30
|
+
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
|
31
|
+
ErrorCode2["AUTH_EXPIRED"] = "AUTH_EXPIRED";
|
|
32
|
+
ErrorCode2["AUTH_INVALID"] = "AUTH_INVALID";
|
|
33
|
+
ErrorCode2["RATE_LIMIT"] = "RATE_LIMIT";
|
|
34
|
+
ErrorCode2["NETWORK"] = "NETWORK";
|
|
35
|
+
ErrorCode2["TIMEOUT"] = "TIMEOUT";
|
|
36
|
+
ErrorCode2["PROVIDER_ERROR"] = "PROVIDER_ERROR";
|
|
37
|
+
ErrorCode2["MODEL_NOT_FOUND"] = "MODEL_NOT_FOUND";
|
|
38
|
+
ErrorCode2["MODEL_OVERLOADED"] = "MODEL_OVERLOADED";
|
|
39
|
+
ErrorCode2["CONTEXT_OVERFLOW"] = "CONTEXT_OVERFLOW";
|
|
40
|
+
ErrorCode2["INVALID_INPUT"] = "INVALID_INPUT";
|
|
41
|
+
ErrorCode2["INVALID_RESPONSE"] = "INVALID_RESPONSE";
|
|
42
|
+
ErrorCode2["REENTRANCY"] = "REENTRANCY";
|
|
43
|
+
ErrorCode2["DISPOSED"] = "DISPOSED";
|
|
44
|
+
ErrorCode2["ABORTED"] = "ABORTED";
|
|
45
|
+
ErrorCode2["INVALID_TRANSITION"] = "INVALID_TRANSITION";
|
|
46
|
+
ErrorCode2["DEPENDENCY_MISSING"] = "DEPENDENCY_MISSING";
|
|
47
|
+
ErrorCode2["BACKEND_NOT_INSTALLED"] = "BACKEND_NOT_INSTALLED";
|
|
48
|
+
ErrorCode2["TOOL_EXECUTION"] = "TOOL_EXECUTION";
|
|
49
|
+
ErrorCode2["PERMISSION_DENIED"] = "PERMISSION_DENIED";
|
|
50
|
+
ErrorCode2["SESSION_NOT_FOUND"] = "SESSION_NOT_FOUND";
|
|
51
|
+
ErrorCode2["SESSION_EXPIRED"] = "SESSION_EXPIRED";
|
|
52
|
+
ErrorCode2["PROVIDER_NOT_FOUND"] = "PROVIDER_NOT_FOUND";
|
|
53
|
+
ErrorCode2["AUTH_REQUIRED"] = "AUTH_REQUIRED";
|
|
54
|
+
ErrorCode2["STORAGE_ERROR"] = "STORAGE_ERROR";
|
|
55
|
+
ErrorCode2["STORAGE_NOT_FOUND"] = "STORAGE_NOT_FOUND";
|
|
56
|
+
ErrorCode2["STORAGE_DUPLICATE_KEY"] = "STORAGE_DUPLICATE_KEY";
|
|
57
|
+
ErrorCode2["STORAGE_IO_ERROR"] = "STORAGE_IO_ERROR";
|
|
58
|
+
ErrorCode2["STORAGE_SERIALIZATION_ERROR"] = "STORAGE_SERIALIZATION_ERROR";
|
|
59
|
+
return ErrorCode2;
|
|
60
|
+
})(ErrorCode || {});
|
|
61
|
+
var RECOVERABLE_CODES = /* @__PURE__ */ new Set([
|
|
62
|
+
"TIMEOUT" /* TIMEOUT */,
|
|
63
|
+
"RATE_LIMIT" /* RATE_LIMIT */,
|
|
64
|
+
"NETWORK" /* NETWORK */,
|
|
65
|
+
"TOOL_EXECUTION" /* TOOL_EXECUTION */,
|
|
66
|
+
"MODEL_OVERLOADED" /* MODEL_OVERLOADED */,
|
|
67
|
+
"PROVIDER_ERROR" /* PROVIDER_ERROR */
|
|
68
|
+
]);
|
|
69
|
+
function isRecoverableErrorCode(code) {
|
|
70
|
+
return RECOVERABLE_CODES.has(code);
|
|
71
|
+
}
|
|
72
|
+
function classifyAgentError(error) {
|
|
73
|
+
const msg = (error instanceof Error ? error.message : error).toLowerCase();
|
|
74
|
+
if (msg.includes("timeout") || msg.includes("timed out") || msg.includes("timedout") || msg.includes("etimedout")) {
|
|
75
|
+
return "TIMEOUT" /* TIMEOUT */;
|
|
76
|
+
}
|
|
77
|
+
if (msg.includes("rate limit") || msg.includes("rate_limit") || msg.includes("429") || msg.includes("too many requests")) {
|
|
78
|
+
return "RATE_LIMIT" /* RATE_LIMIT */;
|
|
79
|
+
}
|
|
80
|
+
if (msg.includes("unauthorized") || msg.includes("401") || msg.includes("auth") && (msg.includes("expired") || msg.includes("invalid") || msg.includes("denied") || msg.includes("failed"))) {
|
|
81
|
+
return "AUTH_EXPIRED" /* AUTH_EXPIRED */;
|
|
82
|
+
}
|
|
83
|
+
if (msg.includes("econnrefused") || msg.includes("econnreset") || msg.includes("enotfound") || msg.includes("network") || msg.includes("fetch failed") || msg.includes("socket hang up")) {
|
|
84
|
+
return "NETWORK" /* NETWORK */;
|
|
85
|
+
}
|
|
86
|
+
if (msg.includes("subprocess") || msg.includes("process exited") || msg.includes("spawn") || msg.includes("enoent") || msg.includes("killed")) {
|
|
87
|
+
return "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */;
|
|
88
|
+
}
|
|
89
|
+
if (msg.includes("abort") || msg.includes("cancel")) {
|
|
90
|
+
return "ABORTED" /* ABORTED */;
|
|
91
|
+
}
|
|
92
|
+
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")) {
|
|
93
|
+
return "PROVIDER_ERROR" /* PROVIDER_ERROR */;
|
|
94
|
+
}
|
|
95
|
+
return "PROVIDER_ERROR" /* PROVIDER_ERROR */;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/types/guards.ts
|
|
30
99
|
function isToolDefinition(tool) {
|
|
31
100
|
return "execute" in tool && typeof tool.execute === "function";
|
|
32
101
|
}
|
|
@@ -43,27 +112,47 @@ function getTextContent(content) {
|
|
|
43
112
|
|
|
44
113
|
// src/errors.ts
|
|
45
114
|
var AgentSDKError = class extends Error {
|
|
115
|
+
/** @internal Marker for cross-bundle identity checks */
|
|
116
|
+
_agentSDKError = true;
|
|
117
|
+
/** Machine-readable error code. Prefer values from the ErrorCode enum. */
|
|
118
|
+
code;
|
|
119
|
+
/** Whether this error is safe to retry */
|
|
120
|
+
retryable;
|
|
121
|
+
/** HTTP status code hint for error classification */
|
|
122
|
+
httpStatus;
|
|
46
123
|
constructor(message, options) {
|
|
47
124
|
super(message, options);
|
|
48
125
|
this.name = "AgentSDKError";
|
|
126
|
+
this.code = options?.code;
|
|
127
|
+
this.retryable = options?.retryable ?? false;
|
|
128
|
+
this.httpStatus = options?.httpStatus;
|
|
129
|
+
}
|
|
130
|
+
/** Check if an error is an AgentSDKError (works across bundled copies) */
|
|
131
|
+
static is(error) {
|
|
132
|
+
return error instanceof Error && "_agentSDKError" in error && error._agentSDKError === true;
|
|
49
133
|
}
|
|
50
134
|
};
|
|
51
135
|
var ReentrancyError = class extends AgentSDKError {
|
|
52
136
|
constructor() {
|
|
53
|
-
super("Agent is already running. Await the current run before starting another."
|
|
137
|
+
super("Agent is already running. Await the current run before starting another.", {
|
|
138
|
+
code: "REENTRANCY" /* REENTRANCY */
|
|
139
|
+
});
|
|
54
140
|
this.name = "ReentrancyError";
|
|
55
141
|
}
|
|
56
142
|
};
|
|
57
143
|
var DisposedError = class extends AgentSDKError {
|
|
58
144
|
constructor(entity) {
|
|
59
|
-
super(`${entity} has been disposed and cannot be used
|
|
145
|
+
super(`${entity} has been disposed and cannot be used.`, {
|
|
146
|
+
code: "DISPOSED" /* DISPOSED */
|
|
147
|
+
});
|
|
60
148
|
this.name = "DisposedError";
|
|
61
149
|
}
|
|
62
150
|
};
|
|
63
151
|
var BackendNotFoundError = class extends AgentSDKError {
|
|
64
152
|
constructor(backend) {
|
|
65
153
|
super(
|
|
66
|
-
`Unknown backend: "${backend}". Built-in: copilot, claude, vercel-ai. Custom: use registerBackend() first
|
|
154
|
+
`Unknown backend: "${backend}". Built-in: copilot, claude, vercel-ai. Custom: use registerBackend() first.`,
|
|
155
|
+
{ code: "BACKEND_NOT_INSTALLED" /* BACKEND_NOT_INSTALLED */ }
|
|
67
156
|
);
|
|
68
157
|
this.name = "BackendNotFoundError";
|
|
69
158
|
}
|
|
@@ -76,41 +165,56 @@ var BackendAlreadyRegisteredError = class extends AgentSDKError {
|
|
|
76
165
|
};
|
|
77
166
|
var SubprocessError = class extends AgentSDKError {
|
|
78
167
|
constructor(message, options) {
|
|
79
|
-
super(message, options);
|
|
168
|
+
super(message, { ...options, code: "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */ });
|
|
80
169
|
this.name = "SubprocessError";
|
|
81
170
|
}
|
|
82
171
|
};
|
|
83
172
|
var DependencyError = class extends AgentSDKError {
|
|
84
173
|
packageName;
|
|
85
174
|
constructor(packageName) {
|
|
86
|
-
super(`${packageName} is not installed. Install it: npm install ${packageName}
|
|
175
|
+
super(`${packageName} is not installed. Install it: npm install ${packageName}`, {
|
|
176
|
+
code: "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */
|
|
177
|
+
});
|
|
87
178
|
this.name = "DependencyError";
|
|
88
179
|
this.packageName = packageName;
|
|
89
180
|
}
|
|
90
181
|
};
|
|
91
182
|
var AbortError = class extends AgentSDKError {
|
|
92
183
|
constructor() {
|
|
93
|
-
super("Agent run was aborted.");
|
|
184
|
+
super("Agent run was aborted.", { code: "ABORTED" /* ABORTED */ });
|
|
94
185
|
this.name = "AbortError";
|
|
95
186
|
}
|
|
96
187
|
};
|
|
97
188
|
var ToolExecutionError = class extends AgentSDKError {
|
|
98
189
|
toolName;
|
|
99
190
|
constructor(toolName, message, options) {
|
|
100
|
-
super(`Tool "${toolName}" failed: ${message}`, options);
|
|
191
|
+
super(`Tool "${toolName}" failed: ${message}`, { ...options, code: "TOOL_EXECUTION" /* TOOL_EXECUTION */ });
|
|
101
192
|
this.name = "ToolExecutionError";
|
|
102
193
|
this.toolName = toolName;
|
|
103
194
|
}
|
|
104
195
|
};
|
|
196
|
+
var ActivityTimeoutError = class extends AgentSDKError {
|
|
197
|
+
constructor(timeoutMs) {
|
|
198
|
+
super(`Stream activity timeout: no event received within ${timeoutMs}ms.`, {
|
|
199
|
+
code: "TIMEOUT" /* TIMEOUT */,
|
|
200
|
+
retryable: true
|
|
201
|
+
});
|
|
202
|
+
this.name = "ActivityTimeoutError";
|
|
203
|
+
}
|
|
204
|
+
};
|
|
105
205
|
var StructuredOutputError = class extends AgentSDKError {
|
|
106
206
|
constructor(message, options) {
|
|
107
|
-
super(`Structured output error: ${message}`, options);
|
|
207
|
+
super(`Structured output error: ${message}`, { ...options, code: "INVALID_RESPONSE" /* INVALID_RESPONSE */ });
|
|
108
208
|
this.name = "StructuredOutputError";
|
|
109
209
|
}
|
|
110
210
|
};
|
|
111
211
|
|
|
112
212
|
// src/registry.ts
|
|
113
213
|
var registry = /* @__PURE__ */ new Map();
|
|
214
|
+
var serviceCache = /* @__PURE__ */ new Map();
|
|
215
|
+
function configCacheKey(name, configId) {
|
|
216
|
+
return `${name}:${configId}`;
|
|
217
|
+
}
|
|
114
218
|
function registerBackend(name, factory) {
|
|
115
219
|
if (registry.has(name)) {
|
|
116
220
|
throw new BackendAlreadyRegisteredError(name);
|
|
@@ -121,49 +225,94 @@ function unregisterBackend(name) {
|
|
|
121
225
|
return registry.delete(name);
|
|
122
226
|
}
|
|
123
227
|
function hasBackend(name) {
|
|
124
|
-
return registry.has(name) ||
|
|
228
|
+
return registry.has(name) || lazyLoaders.has(name);
|
|
125
229
|
}
|
|
126
230
|
function listBackends() {
|
|
127
231
|
const names = new Set(registry.keys());
|
|
128
|
-
for (const
|
|
129
|
-
names.add(
|
|
232
|
+
for (const name of lazyLoaders.keys()) {
|
|
233
|
+
names.add(name);
|
|
130
234
|
}
|
|
131
235
|
return [...names];
|
|
132
236
|
}
|
|
133
237
|
function resetRegistry() {
|
|
134
238
|
registry.clear();
|
|
239
|
+
serviceCache.clear();
|
|
135
240
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
241
|
+
async function disposeBackend(name, configId) {
|
|
242
|
+
if (configId !== void 0) {
|
|
243
|
+
const key = configCacheKey(name, configId);
|
|
244
|
+
const svc = serviceCache.get(key);
|
|
245
|
+
if (!svc) return 0;
|
|
246
|
+
serviceCache.delete(key);
|
|
247
|
+
await svc.dispose();
|
|
248
|
+
return 1;
|
|
249
|
+
}
|
|
250
|
+
const prefix = `${name}:`;
|
|
251
|
+
const toDispose = [];
|
|
252
|
+
for (const [key, svc] of serviceCache) {
|
|
253
|
+
if (key.startsWith(prefix)) {
|
|
254
|
+
toDispose.push(svc);
|
|
255
|
+
serviceCache.delete(key);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
await Promise.all(toDispose.map((s) => s.dispose()));
|
|
259
|
+
return toDispose.length;
|
|
143
260
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
261
|
+
function listConfigs(name) {
|
|
262
|
+
const prefix = `${name}:`;
|
|
263
|
+
const ids = [];
|
|
264
|
+
for (const key of serviceCache.keys()) {
|
|
265
|
+
if (key.startsWith(prefix)) {
|
|
266
|
+
ids.push(key.slice(prefix.length));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return ids;
|
|
270
|
+
}
|
|
271
|
+
var lazyLoaders = /* @__PURE__ */ new Map([
|
|
272
|
+
[
|
|
273
|
+
"copilot",
|
|
274
|
+
async () => {
|
|
147
275
|
const mod = await import('./backends/copilot.js');
|
|
148
276
|
return (opts) => mod.createCopilotService(opts);
|
|
149
277
|
}
|
|
150
|
-
|
|
278
|
+
],
|
|
279
|
+
[
|
|
280
|
+
"claude",
|
|
281
|
+
async () => {
|
|
151
282
|
const mod = await import('./backends/claude.js');
|
|
152
283
|
return (opts) => mod.createClaudeService(opts);
|
|
153
284
|
}
|
|
154
|
-
|
|
285
|
+
],
|
|
286
|
+
[
|
|
287
|
+
"vercel-ai",
|
|
288
|
+
async () => {
|
|
155
289
|
const mod = await import('./backends/vercel-ai.js');
|
|
156
290
|
return (opts) => mod.createVercelAIService(opts);
|
|
157
291
|
}
|
|
158
|
-
|
|
292
|
+
]
|
|
293
|
+
]);
|
|
294
|
+
function registerLazyBackend(name, loader) {
|
|
295
|
+
lazyLoaders.set(name, loader);
|
|
296
|
+
}
|
|
297
|
+
async function createAgentService(name, options, configId) {
|
|
298
|
+
if (configId !== void 0) {
|
|
299
|
+
const key = configCacheKey(name, configId);
|
|
300
|
+
const cached = serviceCache.get(key);
|
|
301
|
+
if (cached) return cached;
|
|
302
|
+
const service = await createServiceInstance(name, options);
|
|
303
|
+
serviceCache.set(key, service);
|
|
304
|
+
return service;
|
|
305
|
+
}
|
|
306
|
+
return createServiceInstance(name, options);
|
|
159
307
|
}
|
|
160
|
-
async function
|
|
308
|
+
async function createServiceInstance(name, options) {
|
|
161
309
|
const entry = registry.get(name);
|
|
162
310
|
if (entry) {
|
|
163
311
|
return entry.factory(options);
|
|
164
312
|
}
|
|
165
|
-
|
|
166
|
-
|
|
313
|
+
const loader = lazyLoaders.get(name);
|
|
314
|
+
if (loader) {
|
|
315
|
+
const factory = await loader();
|
|
167
316
|
registry.set(name, { factory, builtin: true });
|
|
168
317
|
return factory(options);
|
|
169
318
|
}
|
|
@@ -175,6 +324,8 @@ var BaseAgent = class {
|
|
|
175
324
|
state = "idle";
|
|
176
325
|
abortController = null;
|
|
177
326
|
config;
|
|
327
|
+
_cleanupExternalSignal = null;
|
|
328
|
+
_streamMiddleware = [];
|
|
178
329
|
/** CLI session ID for persistent mode. Override in backends that support it. */
|
|
179
330
|
get sessionId() {
|
|
180
331
|
return void 0;
|
|
@@ -190,12 +341,14 @@ var BaseAgent = class {
|
|
|
190
341
|
this.state = "running";
|
|
191
342
|
try {
|
|
192
343
|
const messages = [{ role: "user", content: prompt }];
|
|
193
|
-
const result = await this.
|
|
194
|
-
|
|
344
|
+
const result = await this.withRetry(
|
|
345
|
+
() => this.executeRun(messages, options, ac.signal),
|
|
346
|
+
options
|
|
347
|
+
);
|
|
348
|
+
this.enrichAndNotifyUsage(result, options);
|
|
195
349
|
return result;
|
|
196
350
|
} finally {
|
|
197
|
-
this.
|
|
198
|
-
this.abortController = null;
|
|
351
|
+
this.cleanupRun();
|
|
199
352
|
}
|
|
200
353
|
}
|
|
201
354
|
async runWithContext(messages, options) {
|
|
@@ -204,12 +357,14 @@ var BaseAgent = class {
|
|
|
204
357
|
const ac = this.createAbortController(options?.signal);
|
|
205
358
|
this.state = "running";
|
|
206
359
|
try {
|
|
207
|
-
const result = await this.
|
|
208
|
-
|
|
360
|
+
const result = await this.withRetry(
|
|
361
|
+
() => this.executeRun(messages, options, ac.signal),
|
|
362
|
+
options
|
|
363
|
+
);
|
|
364
|
+
this.enrichAndNotifyUsage(result, options);
|
|
209
365
|
return result;
|
|
210
366
|
} finally {
|
|
211
|
-
this.
|
|
212
|
-
this.abortController = null;
|
|
367
|
+
this.cleanupRun();
|
|
213
368
|
}
|
|
214
369
|
}
|
|
215
370
|
async runStructured(prompt, schema, options) {
|
|
@@ -219,17 +374,14 @@ var BaseAgent = class {
|
|
|
219
374
|
this.state = "running";
|
|
220
375
|
try {
|
|
221
376
|
const messages = [{ role: "user", content: prompt }];
|
|
222
|
-
const result = await this.
|
|
223
|
-
messages,
|
|
224
|
-
|
|
225
|
-
options,
|
|
226
|
-
ac.signal
|
|
377
|
+
const result = await this.withRetry(
|
|
378
|
+
() => this.executeRunStructured(messages, schema, options, ac.signal),
|
|
379
|
+
options
|
|
227
380
|
);
|
|
228
|
-
this.enrichAndNotifyUsage(result);
|
|
381
|
+
this.enrichAndNotifyUsage(result, options);
|
|
229
382
|
return result;
|
|
230
383
|
} finally {
|
|
231
|
-
this.
|
|
232
|
-
this.abortController = null;
|
|
384
|
+
this.cleanupRun();
|
|
233
385
|
}
|
|
234
386
|
}
|
|
235
387
|
async *stream(prompt, options) {
|
|
@@ -239,11 +391,12 @@ var BaseAgent = class {
|
|
|
239
391
|
this.state = "streaming";
|
|
240
392
|
try {
|
|
241
393
|
const messages = [{ role: "user", content: prompt }];
|
|
242
|
-
|
|
243
|
-
|
|
394
|
+
yield* this.streamWithRetry(
|
|
395
|
+
() => this.applyStreamPipeline(this.executeStream(messages, options, ac.signal), options, ac),
|
|
396
|
+
options
|
|
397
|
+
);
|
|
244
398
|
} finally {
|
|
245
|
-
this.
|
|
246
|
-
this.abortController = null;
|
|
399
|
+
this.cleanupRun();
|
|
247
400
|
}
|
|
248
401
|
}
|
|
249
402
|
async *streamWithContext(messages, options) {
|
|
@@ -252,13 +405,37 @@ var BaseAgent = class {
|
|
|
252
405
|
const ac = this.createAbortController(options?.signal);
|
|
253
406
|
this.state = "streaming";
|
|
254
407
|
try {
|
|
255
|
-
|
|
256
|
-
|
|
408
|
+
yield* this.streamWithRetry(
|
|
409
|
+
() => this.applyStreamPipeline(this.executeStream(messages, options, ac.signal), options, ac),
|
|
410
|
+
options
|
|
411
|
+
);
|
|
257
412
|
} finally {
|
|
258
|
-
this.
|
|
259
|
-
this.abortController = null;
|
|
413
|
+
this.cleanupRun();
|
|
260
414
|
}
|
|
261
415
|
}
|
|
416
|
+
/** Register a stream middleware. Applied in registration order after built-in transforms. */
|
|
417
|
+
addStreamMiddleware(middleware) {
|
|
418
|
+
this.guardDisposed();
|
|
419
|
+
this._streamMiddleware.push(middleware);
|
|
420
|
+
}
|
|
421
|
+
/** Apply built-in transforms (enrich→timeout→heartbeat) then custom middleware */
|
|
422
|
+
async *applyStreamPipeline(source, options, ac) {
|
|
423
|
+
let stream = this.enrichStream(source, options);
|
|
424
|
+
stream = this.activityTimeoutStream(stream, options?.activityTimeoutMs, ac);
|
|
425
|
+
stream = this.heartbeatStream(stream);
|
|
426
|
+
if (this._streamMiddleware.length > 0) {
|
|
427
|
+
const ctx = {
|
|
428
|
+
model: options.model,
|
|
429
|
+
backend: this.backendName,
|
|
430
|
+
abortController: ac,
|
|
431
|
+
config: Object.freeze({ ...this.config })
|
|
432
|
+
};
|
|
433
|
+
for (const mw of this._streamMiddleware) {
|
|
434
|
+
stream = mw(stream, ctx);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
yield* stream;
|
|
438
|
+
}
|
|
262
439
|
abort() {
|
|
263
440
|
if (this.abortController) {
|
|
264
441
|
this.abortController.abort();
|
|
@@ -276,29 +453,114 @@ var BaseAgent = class {
|
|
|
276
453
|
}
|
|
277
454
|
/** Mark agent as disposed. Override to add cleanup. */
|
|
278
455
|
dispose() {
|
|
456
|
+
this._cleanupExternalSignal?.();
|
|
457
|
+
this._cleanupExternalSignal = null;
|
|
279
458
|
this.abort();
|
|
280
459
|
this.state = "disposed";
|
|
281
460
|
}
|
|
461
|
+
// ─── Retry Logic ─────────────────────────────────────────────
|
|
462
|
+
/** Check if an error should be retried given the retry configuration. */
|
|
463
|
+
isRetryableError(error, retry) {
|
|
464
|
+
if (error instanceof AbortError || error instanceof ReentrancyError || error instanceof DisposedError) {
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
if (AgentSDKError.is(error)) {
|
|
468
|
+
if (retry.retryableErrors && retry.retryableErrors.length > 0 && error.code) {
|
|
469
|
+
return retry.retryableErrors.includes(error.code);
|
|
470
|
+
}
|
|
471
|
+
if (error.retryable) return true;
|
|
472
|
+
if (error.code) return isRecoverableErrorCode(error.code);
|
|
473
|
+
}
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
/** Execute a function with retry logic per RetryConfig. */
|
|
477
|
+
async withRetry(fn, options) {
|
|
478
|
+
const retry = options?.retry;
|
|
479
|
+
if (!retry || !retry.maxRetries || retry.maxRetries <= 0) {
|
|
480
|
+
return fn();
|
|
481
|
+
}
|
|
482
|
+
const maxRetries = retry.maxRetries;
|
|
483
|
+
const initialDelay = retry.initialDelayMs ?? 1e3;
|
|
484
|
+
const multiplier = retry.backoffMultiplier ?? 2;
|
|
485
|
+
let lastError;
|
|
486
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
487
|
+
try {
|
|
488
|
+
return await fn();
|
|
489
|
+
} catch (err) {
|
|
490
|
+
lastError = err;
|
|
491
|
+
if (attempt >= maxRetries || !this.isRetryableError(err, retry)) {
|
|
492
|
+
throw err;
|
|
493
|
+
}
|
|
494
|
+
const delay = initialDelay * Math.pow(multiplier, attempt);
|
|
495
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
496
|
+
if (options?.signal?.aborted || this.abortController?.signal.aborted) {
|
|
497
|
+
throw err;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
throw lastError;
|
|
502
|
+
}
|
|
503
|
+
/** Execute a stream factory with pre-stream retry: retries until first event, then committed. */
|
|
504
|
+
async *streamWithRetry(factory, options) {
|
|
505
|
+
const retry = options?.retry;
|
|
506
|
+
if (!retry || !retry.maxRetries || retry.maxRetries <= 0) {
|
|
507
|
+
yield* factory();
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
const maxRetries = retry.maxRetries;
|
|
511
|
+
const initialDelay = retry.initialDelayMs ?? 1e3;
|
|
512
|
+
const multiplier = retry.backoffMultiplier ?? 2;
|
|
513
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
514
|
+
try {
|
|
515
|
+
const stream = factory();
|
|
516
|
+
const iterator = stream[Symbol.asyncIterator]();
|
|
517
|
+
const first = await iterator.next();
|
|
518
|
+
if (first.done) return;
|
|
519
|
+
yield first.value;
|
|
520
|
+
while (true) {
|
|
521
|
+
const next = await iterator.next();
|
|
522
|
+
if (next.done) break;
|
|
523
|
+
yield next.value;
|
|
524
|
+
}
|
|
525
|
+
return;
|
|
526
|
+
} catch (err) {
|
|
527
|
+
if (attempt >= maxRetries || !this.isRetryableError(err, retry)) {
|
|
528
|
+
throw err;
|
|
529
|
+
}
|
|
530
|
+
const delay = initialDelay * Math.pow(multiplier, attempt);
|
|
531
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
532
|
+
if (options?.signal?.aborted || this.abortController?.signal.aborted) {
|
|
533
|
+
throw err;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
// ─── CallOptions Resolution ──────────────────────────────────
|
|
539
|
+
/** Resolve tools to use for this call (per-call override > config default) */
|
|
540
|
+
resolveTools(options) {
|
|
541
|
+
return options?.tools ?? this.config.tools ?? [];
|
|
542
|
+
}
|
|
282
543
|
// ─── Usage Enrichment ───────────────────────────────────────────
|
|
283
544
|
/** Enrich result usage with model/backend and fire onUsage callback */
|
|
284
|
-
enrichAndNotifyUsage(result) {
|
|
545
|
+
enrichAndNotifyUsage(result, options) {
|
|
285
546
|
if (result.usage) {
|
|
286
547
|
result.usage = {
|
|
287
548
|
...result.usage,
|
|
288
|
-
model:
|
|
549
|
+
model: options.model,
|
|
289
550
|
backend: this.backendName
|
|
290
551
|
};
|
|
291
552
|
this.callOnUsage(result.usage);
|
|
292
553
|
}
|
|
293
554
|
}
|
|
294
555
|
/** Wrap a stream to enrich usage_update events and fire onUsage callback */
|
|
295
|
-
async *enrichStream(source) {
|
|
556
|
+
async *enrichStream(source, options) {
|
|
557
|
+
const model = options.model;
|
|
296
558
|
for await (const event of source) {
|
|
297
559
|
if (event.type === "usage_update") {
|
|
298
560
|
const usage = {
|
|
299
561
|
promptTokens: event.promptTokens,
|
|
300
562
|
completionTokens: event.completionTokens,
|
|
301
|
-
model
|
|
563
|
+
model,
|
|
302
564
|
backend: this.backendName
|
|
303
565
|
};
|
|
304
566
|
this.callOnUsage(usage);
|
|
@@ -368,6 +630,35 @@ var BaseAgent = class {
|
|
|
368
630
|
heartbeatResolve = null;
|
|
369
631
|
}
|
|
370
632
|
}
|
|
633
|
+
// ─── Activity Timeout ────────────────────────────────────────
|
|
634
|
+
/** Wrap a stream to abort on inactivity. Resets timer on every event.
|
|
635
|
+
* When timeoutMs is not set, passes through directly. */
|
|
636
|
+
async *activityTimeoutStream(source, timeoutMs, ac) {
|
|
637
|
+
if (!timeoutMs || timeoutMs <= 0) {
|
|
638
|
+
yield* source;
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
642
|
+
let timerId;
|
|
643
|
+
try {
|
|
644
|
+
while (true) {
|
|
645
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
646
|
+
timerId = setTimeout(() => reject(new ActivityTimeoutError(timeoutMs)), timeoutMs);
|
|
647
|
+
});
|
|
648
|
+
const result = await Promise.race([iterator.next(), timeoutPromise]);
|
|
649
|
+
clearTimeout(timerId);
|
|
650
|
+
if (result.done) break;
|
|
651
|
+
yield result.value;
|
|
652
|
+
}
|
|
653
|
+
} catch (err) {
|
|
654
|
+
if (err instanceof ActivityTimeoutError) {
|
|
655
|
+
ac.abort(err);
|
|
656
|
+
}
|
|
657
|
+
throw err;
|
|
658
|
+
} finally {
|
|
659
|
+
clearTimeout(timerId);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
371
662
|
// ─── Guards ───────────────────────────────────────────────────
|
|
372
663
|
guardReentrancy() {
|
|
373
664
|
if (this.state === "running" || this.state === "streaming") {
|
|
@@ -386,16 +677,24 @@ var BaseAgent = class {
|
|
|
386
677
|
}
|
|
387
678
|
}
|
|
388
679
|
// ─── Internal Helpers ─────────────────────────────────────────
|
|
680
|
+
/** Clean up after a run completes (success, error, or abort). */
|
|
681
|
+
cleanupRun() {
|
|
682
|
+
this._cleanupExternalSignal?.();
|
|
683
|
+
this._cleanupExternalSignal = null;
|
|
684
|
+
this.state = "idle";
|
|
685
|
+
this.abortController = null;
|
|
686
|
+
}
|
|
389
687
|
createAbortController(externalSignal) {
|
|
390
688
|
const ac = new AbortController();
|
|
391
689
|
this.abortController = ac;
|
|
690
|
+
this._cleanupExternalSignal = null;
|
|
392
691
|
if (externalSignal) {
|
|
393
692
|
if (externalSignal.aborted) {
|
|
394
693
|
ac.abort();
|
|
395
694
|
} else {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
695
|
+
const listener = () => ac.abort();
|
|
696
|
+
externalSignal.addEventListener("abort", listener, { once: true });
|
|
697
|
+
this._cleanupExternalSignal = () => externalSignal.removeEventListener("abort", listener);
|
|
399
698
|
}
|
|
400
699
|
}
|
|
401
700
|
return ac;
|
|
@@ -593,6 +892,7 @@ function createDefaultPermissionStore(projectDir) {
|
|
|
593
892
|
}
|
|
594
893
|
|
|
595
894
|
exports.AbortError = AbortError;
|
|
895
|
+
exports.ActivityTimeoutError = ActivityTimeoutError;
|
|
596
896
|
exports.AgentSDKError = AgentSDKError;
|
|
597
897
|
exports.BackendAlreadyRegisteredError = BackendAlreadyRegisteredError;
|
|
598
898
|
exports.BackendNotFoundError = BackendNotFoundError;
|
|
@@ -600,6 +900,7 @@ exports.BaseAgent = BaseAgent;
|
|
|
600
900
|
exports.CompositePermissionStore = CompositePermissionStore;
|
|
601
901
|
exports.DependencyError = DependencyError;
|
|
602
902
|
exports.DisposedError = DisposedError;
|
|
903
|
+
exports.ErrorCode = ErrorCode;
|
|
603
904
|
exports.FilePermissionStore = FilePermissionStore;
|
|
604
905
|
exports.InMemoryPermissionStore = InMemoryPermissionStore;
|
|
605
906
|
exports.ReentrancyError = ReentrancyError;
|
|
@@ -607,17 +908,22 @@ exports.StructuredOutputError = StructuredOutputError;
|
|
|
607
908
|
exports.SubprocessError = SubprocessError;
|
|
608
909
|
exports.ToolExecutionError = ToolExecutionError;
|
|
609
910
|
exports.buildSystemPrompt = buildSystemPrompt;
|
|
911
|
+
exports.classifyAgentError = classifyAgentError;
|
|
610
912
|
exports.contentToText = contentToText;
|
|
611
913
|
exports.createAgentService = createAgentService;
|
|
612
914
|
exports.createDefaultPermissionStore = createDefaultPermissionStore;
|
|
915
|
+
exports.disposeBackend = disposeBackend;
|
|
613
916
|
exports.getTextContent = getTextContent;
|
|
614
917
|
exports.hasBackend = hasBackend;
|
|
615
918
|
exports.isMultiPartContent = isMultiPartContent;
|
|
919
|
+
exports.isRecoverableErrorCode = isRecoverableErrorCode;
|
|
616
920
|
exports.isTextContent = isTextContent;
|
|
617
921
|
exports.isToolDefinition = isToolDefinition;
|
|
618
922
|
exports.listBackends = listBackends;
|
|
923
|
+
exports.listConfigs = listConfigs;
|
|
619
924
|
exports.messagesToPrompt = messagesToPrompt;
|
|
620
925
|
exports.registerBackend = registerBackend;
|
|
926
|
+
exports.registerLazyBackend = registerLazyBackend;
|
|
621
927
|
exports.resetRegistry = resetRegistry;
|
|
622
928
|
exports.unregisterBackend = unregisterBackend;
|
|
623
929
|
exports.zodToJsonSchema = zodToJsonSchema;
|