@witqq/agent-sdk 0.7.0 → 0.9.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.
Files changed (154) hide show
  1. package/dist/{types-CqvUAYxt.d.ts → agent-C6H2CgJA.d.cts} +139 -102
  2. package/dist/{types-CqvUAYxt.d.cts → agent-F7oB6eKp.d.ts} +139 -102
  3. package/dist/auth/index.cjs +72 -1
  4. package/dist/auth/index.cjs.map +1 -1
  5. package/dist/auth/index.d.cts +21 -154
  6. package/dist/auth/index.d.ts +21 -154
  7. package/dist/auth/index.js +72 -1
  8. package/dist/auth/index.js.map +1 -1
  9. package/dist/backends/claude.cjs +480 -261
  10. package/dist/backends/claude.cjs.map +1 -1
  11. package/dist/backends/claude.d.cts +3 -1
  12. package/dist/backends/claude.d.ts +3 -1
  13. package/dist/backends/claude.js +480 -261
  14. package/dist/backends/claude.js.map +1 -1
  15. package/dist/backends/copilot.cjs +337 -112
  16. package/dist/backends/copilot.cjs.map +1 -1
  17. package/dist/backends/copilot.d.cts +12 -4
  18. package/dist/backends/copilot.d.ts +12 -4
  19. package/dist/backends/copilot.js +337 -112
  20. package/dist/backends/copilot.js.map +1 -1
  21. package/dist/backends/mock-llm.cjs +719 -0
  22. package/dist/backends/mock-llm.cjs.map +1 -0
  23. package/dist/backends/mock-llm.d.cts +37 -0
  24. package/dist/backends/mock-llm.d.ts +37 -0
  25. package/dist/backends/mock-llm.js +717 -0
  26. package/dist/backends/mock-llm.js.map +1 -0
  27. package/dist/backends/vercel-ai.cjs +301 -61
  28. package/dist/backends/vercel-ai.cjs.map +1 -1
  29. package/dist/backends/vercel-ai.d.cts +3 -1
  30. package/dist/backends/vercel-ai.d.ts +3 -1
  31. package/dist/backends/vercel-ai.js +301 -61
  32. package/dist/backends/vercel-ai.js.map +1 -1
  33. package/dist/backends-Cno0gZjy.d.cts +114 -0
  34. package/dist/backends-Cno0gZjy.d.ts +114 -0
  35. package/dist/chat/accumulator.cjs +1 -1
  36. package/dist/chat/accumulator.cjs.map +1 -1
  37. package/dist/chat/accumulator.d.cts +5 -2
  38. package/dist/chat/accumulator.d.ts +5 -2
  39. package/dist/chat/accumulator.js +1 -1
  40. package/dist/chat/accumulator.js.map +1 -1
  41. package/dist/chat/backends.cjs +1084 -821
  42. package/dist/chat/backends.cjs.map +1 -1
  43. package/dist/chat/backends.d.cts +10 -6
  44. package/dist/chat/backends.d.ts +10 -6
  45. package/dist/chat/backends.js +1082 -800
  46. package/dist/chat/backends.js.map +1 -1
  47. package/dist/chat/context.cjs +50 -0
  48. package/dist/chat/context.cjs.map +1 -1
  49. package/dist/chat/context.d.cts +27 -3
  50. package/dist/chat/context.d.ts +27 -3
  51. package/dist/chat/context.js +50 -0
  52. package/dist/chat/context.js.map +1 -1
  53. package/dist/chat/core.cjs +60 -27
  54. package/dist/chat/core.cjs.map +1 -1
  55. package/dist/chat/core.d.cts +41 -382
  56. package/dist/chat/core.d.ts +41 -382
  57. package/dist/chat/core.js +58 -28
  58. package/dist/chat/core.js.map +1 -1
  59. package/dist/chat/errors.cjs +48 -26
  60. package/dist/chat/errors.cjs.map +1 -1
  61. package/dist/chat/errors.d.cts +6 -31
  62. package/dist/chat/errors.d.ts +6 -31
  63. package/dist/chat/errors.js +48 -25
  64. package/dist/chat/errors.js.map +1 -1
  65. package/dist/chat/events.cjs.map +1 -1
  66. package/dist/chat/events.d.cts +6 -2
  67. package/dist/chat/events.d.ts +6 -2
  68. package/dist/chat/events.js.map +1 -1
  69. package/dist/chat/index.cjs +1612 -1125
  70. package/dist/chat/index.cjs.map +1 -1
  71. package/dist/chat/index.d.cts +35 -10
  72. package/dist/chat/index.d.ts +35 -10
  73. package/dist/chat/index.js +1600 -1097
  74. package/dist/chat/index.js.map +1 -1
  75. package/dist/chat/react/theme.css +2517 -0
  76. package/dist/chat/react.cjs +2212 -1158
  77. package/dist/chat/react.cjs.map +1 -1
  78. package/dist/chat/react.d.cts +665 -122
  79. package/dist/chat/react.d.ts +665 -122
  80. package/dist/chat/react.js +2191 -1156
  81. package/dist/chat/react.js.map +1 -1
  82. package/dist/chat/runtime.cjs +405 -186
  83. package/dist/chat/runtime.cjs.map +1 -1
  84. package/dist/chat/runtime.d.cts +92 -28
  85. package/dist/chat/runtime.d.ts +92 -28
  86. package/dist/chat/runtime.js +405 -186
  87. package/dist/chat/runtime.js.map +1 -1
  88. package/dist/chat/server.cjs +2247 -212
  89. package/dist/chat/server.cjs.map +1 -1
  90. package/dist/chat/server.d.cts +451 -90
  91. package/dist/chat/server.d.ts +451 -90
  92. package/dist/chat/server.js +2234 -213
  93. package/dist/chat/server.js.map +1 -1
  94. package/dist/chat/sessions.cjs +64 -66
  95. package/dist/chat/sessions.cjs.map +1 -1
  96. package/dist/chat/sessions.d.cts +37 -118
  97. package/dist/chat/sessions.d.ts +37 -118
  98. package/dist/chat/sessions.js +65 -67
  99. package/dist/chat/sessions.js.map +1 -1
  100. package/dist/chat/sqlite.cjs +536 -0
  101. package/dist/chat/sqlite.cjs.map +1 -0
  102. package/dist/chat/sqlite.d.cts +164 -0
  103. package/dist/chat/sqlite.d.ts +164 -0
  104. package/dist/chat/sqlite.js +527 -0
  105. package/dist/chat/sqlite.js.map +1 -0
  106. package/dist/chat/state.cjs +14 -1
  107. package/dist/chat/state.cjs.map +1 -1
  108. package/dist/chat/state.d.cts +5 -2
  109. package/dist/chat/state.d.ts +5 -2
  110. package/dist/chat/state.js +14 -1
  111. package/dist/chat/state.js.map +1 -1
  112. package/dist/chat/storage.cjs +58 -33
  113. package/dist/chat/storage.cjs.map +1 -1
  114. package/dist/chat/storage.d.cts +18 -8
  115. package/dist/chat/storage.d.ts +18 -8
  116. package/dist/chat/storage.js +59 -34
  117. package/dist/chat/storage.js.map +1 -1
  118. package/dist/errors-C-so0M4t.d.cts +33 -0
  119. package/dist/errors-C-so0M4t.d.ts +33 -0
  120. package/dist/errors-CmVvczxZ.d.cts +28 -0
  121. package/dist/errors-CmVvczxZ.d.ts +28 -0
  122. package/dist/{in-process-transport-C2oPTYs6.d.ts → in-process-transport-7EIit9Xk.d.ts} +72 -33
  123. package/dist/{in-process-transport-DG-w5G6k.d.cts → in-process-transport-Ct9YcX8I.d.cts} +72 -33
  124. package/dist/index.cjs +354 -60
  125. package/dist/index.cjs.map +1 -1
  126. package/dist/index.d.cts +294 -123
  127. package/dist/index.d.ts +294 -123
  128. package/dist/index.js +347 -60
  129. package/dist/index.js.map +1 -1
  130. package/dist/provider-types-PTSlRPNB.d.cts +39 -0
  131. package/dist/provider-types-PTSlRPNB.d.ts +39 -0
  132. package/dist/refresh-manager-B81PpYBr.d.cts +153 -0
  133. package/dist/refresh-manager-Dlv_iNZi.d.ts +153 -0
  134. package/dist/testing.cjs +1107 -0
  135. package/dist/testing.cjs.map +1 -0
  136. package/dist/testing.d.cts +144 -0
  137. package/dist/testing.d.ts +144 -0
  138. package/dist/testing.js +1101 -0
  139. package/dist/testing.js.map +1 -0
  140. package/dist/token-store-CSUBgYwn.d.ts +48 -0
  141. package/dist/token-store-CuC4hB9Z.d.cts +48 -0
  142. package/dist/{transport-DX1Nhm4N.d.cts → transport-DLWCN18G.d.cts} +5 -4
  143. package/dist/{transport-D1OaUgRk.d.ts → transport-DsuS-GeM.d.ts} +5 -4
  144. package/dist/{types-CGF7AEX1.d.cts → types-4vbcmPTp.d.cts} +4 -2
  145. package/dist/{types-Bh5AhqD-.d.ts → types-BxggH0Yh.d.ts} +4 -2
  146. package/dist/types-DgtI1hzh.d.ts +364 -0
  147. package/dist/types-DkSXALKg.d.cts +364 -0
  148. package/package.json +41 -5
  149. package/LICENSE +0 -21
  150. package/README.md +0 -948
  151. package/dist/errors-BDLbNu9w.d.cts +0 -13
  152. package/dist/errors-BDLbNu9w.d.ts +0 -13
  153. package/dist/types-DLZzlJxt.d.ts +0 -39
  154. package/dist/types-tE0CXwBl.d.cts +0 -39
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var fs = require('fs');
3
+ var fsp = require('fs/promises');
4
4
  var path = require('path');
5
5
  var os = require('os');
6
6
 
@@ -22,11 +22,80 @@ function _interopNamespace(e) {
22
22
  return Object.freeze(n);
23
23
  }
24
24
 
25
- var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
25
+ var fsp__namespace = /*#__PURE__*/_interopNamespace(fsp);
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
  }
@@ -45,9 +114,18 @@ function getTextContent(content) {
45
114
  var AgentSDKError = class extends Error {
46
115
  /** @internal Marker for cross-bundle identity checks */
47
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;
48
123
  constructor(message, options) {
49
124
  super(message, options);
50
125
  this.name = "AgentSDKError";
126
+ this.code = options?.code;
127
+ this.retryable = options?.retryable ?? false;
128
+ this.httpStatus = options?.httpStatus;
51
129
  }
52
130
  /** Check if an error is an AgentSDKError (works across bundled copies) */
53
131
  static is(error) {
@@ -56,20 +134,25 @@ var AgentSDKError = class extends Error {
56
134
  };
57
135
  var ReentrancyError = class extends AgentSDKError {
58
136
  constructor() {
59
- 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
+ });
60
140
  this.name = "ReentrancyError";
61
141
  }
62
142
  };
63
143
  var DisposedError = class extends AgentSDKError {
64
144
  constructor(entity) {
65
- super(`${entity} has been disposed and cannot be used.`);
145
+ super(`${entity} has been disposed and cannot be used.`, {
146
+ code: "DISPOSED" /* DISPOSED */
147
+ });
66
148
  this.name = "DisposedError";
67
149
  }
68
150
  };
69
151
  var BackendNotFoundError = class extends AgentSDKError {
70
152
  constructor(backend) {
71
153
  super(
72
- `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 */ }
73
156
  );
74
157
  this.name = "BackendNotFoundError";
75
158
  }
@@ -82,41 +165,56 @@ var BackendAlreadyRegisteredError = class extends AgentSDKError {
82
165
  };
83
166
  var SubprocessError = class extends AgentSDKError {
84
167
  constructor(message, options) {
85
- super(message, options);
168
+ super(message, { ...options, code: "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */ });
86
169
  this.name = "SubprocessError";
87
170
  }
88
171
  };
89
172
  var DependencyError = class extends AgentSDKError {
90
173
  packageName;
91
174
  constructor(packageName) {
92
- 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
+ });
93
178
  this.name = "DependencyError";
94
179
  this.packageName = packageName;
95
180
  }
96
181
  };
97
182
  var AbortError = class extends AgentSDKError {
98
183
  constructor() {
99
- super("Agent run was aborted.");
184
+ super("Agent run was aborted.", { code: "ABORTED" /* ABORTED */ });
100
185
  this.name = "AbortError";
101
186
  }
102
187
  };
103
188
  var ToolExecutionError = class extends AgentSDKError {
104
189
  toolName;
105
190
  constructor(toolName, message, options) {
106
- super(`Tool "${toolName}" failed: ${message}`, options);
191
+ super(`Tool "${toolName}" failed: ${message}`, { ...options, code: "TOOL_EXECUTION" /* TOOL_EXECUTION */ });
107
192
  this.name = "ToolExecutionError";
108
193
  this.toolName = toolName;
109
194
  }
110
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
+ };
111
205
  var StructuredOutputError = class extends AgentSDKError {
112
206
  constructor(message, options) {
113
- super(`Structured output error: ${message}`, options);
207
+ super(`Structured output error: ${message}`, { ...options, code: "INVALID_RESPONSE" /* INVALID_RESPONSE */ });
114
208
  this.name = "StructuredOutputError";
115
209
  }
116
210
  };
117
211
 
118
212
  // src/registry.ts
119
213
  var registry = /* @__PURE__ */ new Map();
214
+ var serviceCache = /* @__PURE__ */ new Map();
215
+ function configCacheKey(name, configId) {
216
+ return `${name}:${configId}`;
217
+ }
120
218
  function registerBackend(name, factory) {
121
219
  if (registry.has(name)) {
122
220
  throw new BackendAlreadyRegisteredError(name);
@@ -127,49 +225,94 @@ function unregisterBackend(name) {
127
225
  return registry.delete(name);
128
226
  }
129
227
  function hasBackend(name) {
130
- return registry.has(name) || isBuiltinName(name);
228
+ return registry.has(name) || lazyLoaders.has(name);
131
229
  }
132
230
  function listBackends() {
133
231
  const names = new Set(registry.keys());
134
- for (const builtin of BUILTIN_BACKENDS) {
135
- names.add(builtin);
232
+ for (const name of lazyLoaders.keys()) {
233
+ names.add(name);
136
234
  }
137
235
  return [...names];
138
236
  }
139
237
  function resetRegistry() {
140
238
  registry.clear();
239
+ serviceCache.clear();
141
240
  }
142
- var BUILTIN_BACKENDS = /* @__PURE__ */ new Set([
143
- "copilot",
144
- "claude",
145
- "vercel-ai"
146
- ]);
147
- function isBuiltinName(name) {
148
- return BUILTIN_BACKENDS.has(name);
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;
149
260
  }
150
- async function loadBuiltinFactory(name) {
151
- switch (name) {
152
- case "copilot": {
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 () => {
153
275
  const mod = await import('./backends/copilot.js');
154
276
  return (opts) => mod.createCopilotService(opts);
155
277
  }
156
- case "claude": {
278
+ ],
279
+ [
280
+ "claude",
281
+ async () => {
157
282
  const mod = await import('./backends/claude.js');
158
283
  return (opts) => mod.createClaudeService(opts);
159
284
  }
160
- case "vercel-ai": {
285
+ ],
286
+ [
287
+ "vercel-ai",
288
+ async () => {
161
289
  const mod = await import('./backends/vercel-ai.js');
162
290
  return (opts) => mod.createVercelAIService(opts);
163
291
  }
164
- }
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);
165
307
  }
166
- async function createAgentService(name, options) {
308
+ async function createServiceInstance(name, options) {
167
309
  const entry = registry.get(name);
168
310
  if (entry) {
169
311
  return entry.factory(options);
170
312
  }
171
- if (isBuiltinName(name)) {
172
- const factory = await loadBuiltinFactory(name);
313
+ const loader = lazyLoaders.get(name);
314
+ if (loader) {
315
+ const factory = await loader();
173
316
  registry.set(name, { factory, builtin: true });
174
317
  return factory(options);
175
318
  }
@@ -182,6 +325,7 @@ var BaseAgent = class {
182
325
  abortController = null;
183
326
  config;
184
327
  _cleanupExternalSignal = null;
328
+ _streamMiddleware = [];
185
329
  /** CLI session ID for persistent mode. Override in backends that support it. */
186
330
  get sessionId() {
187
331
  return void 0;
@@ -197,8 +341,11 @@ var BaseAgent = class {
197
341
  this.state = "running";
198
342
  try {
199
343
  const messages = [{ role: "user", content: prompt }];
200
- const result = await this.executeRun(messages, options, ac.signal);
201
- this.enrichAndNotifyUsage(result);
344
+ const result = await this.withRetry(
345
+ () => this.executeRun(messages, options, ac.signal),
346
+ options
347
+ );
348
+ this.enrichAndNotifyUsage(result, options);
202
349
  return result;
203
350
  } finally {
204
351
  this.cleanupRun();
@@ -210,8 +357,11 @@ var BaseAgent = class {
210
357
  const ac = this.createAbortController(options?.signal);
211
358
  this.state = "running";
212
359
  try {
213
- const result = await this.executeRun(messages, options, ac.signal);
214
- this.enrichAndNotifyUsage(result);
360
+ const result = await this.withRetry(
361
+ () => this.executeRun(messages, options, ac.signal),
362
+ options
363
+ );
364
+ this.enrichAndNotifyUsage(result, options);
215
365
  return result;
216
366
  } finally {
217
367
  this.cleanupRun();
@@ -224,13 +374,11 @@ var BaseAgent = class {
224
374
  this.state = "running";
225
375
  try {
226
376
  const messages = [{ role: "user", content: prompt }];
227
- const result = await this.executeRunStructured(
228
- messages,
229
- schema,
230
- options,
231
- ac.signal
377
+ const result = await this.withRetry(
378
+ () => this.executeRunStructured(messages, schema, options, ac.signal),
379
+ options
232
380
  );
233
- this.enrichAndNotifyUsage(result);
381
+ this.enrichAndNotifyUsage(result, options);
234
382
  return result;
235
383
  } finally {
236
384
  this.cleanupRun();
@@ -243,8 +391,10 @@ var BaseAgent = class {
243
391
  this.state = "streaming";
244
392
  try {
245
393
  const messages = [{ role: "user", content: prompt }];
246
- const enriched = this.enrichStream(this.executeStream(messages, options, ac.signal));
247
- yield* this.heartbeatStream(enriched);
394
+ yield* this.streamWithRetry(
395
+ () => this.applyStreamPipeline(this.executeStream(messages, options, ac.signal), options, ac),
396
+ options
397
+ );
248
398
  } finally {
249
399
  this.cleanupRun();
250
400
  }
@@ -255,12 +405,37 @@ var BaseAgent = class {
255
405
  const ac = this.createAbortController(options?.signal);
256
406
  this.state = "streaming";
257
407
  try {
258
- const enriched = this.enrichStream(this.executeStream(messages, options, ac.signal));
259
- yield* this.heartbeatStream(enriched);
408
+ yield* this.streamWithRetry(
409
+ () => this.applyStreamPipeline(this.executeStream(messages, options, ac.signal), options, ac),
410
+ options
411
+ );
260
412
  } finally {
261
413
  this.cleanupRun();
262
414
  }
263
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
+ }
264
439
  abort() {
265
440
  if (this.abortController) {
266
441
  this.abortController.abort();
@@ -283,26 +458,109 @@ var BaseAgent = class {
283
458
  this.abort();
284
459
  this.state = "disposed";
285
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
+ }
286
543
  // ─── Usage Enrichment ───────────────────────────────────────────
287
544
  /** Enrich result usage with model/backend and fire onUsage callback */
288
- enrichAndNotifyUsage(result) {
545
+ enrichAndNotifyUsage(result, options) {
289
546
  if (result.usage) {
290
547
  result.usage = {
291
548
  ...result.usage,
292
- model: this.config.model,
549
+ model: options.model,
293
550
  backend: this.backendName
294
551
  };
295
552
  this.callOnUsage(result.usage);
296
553
  }
297
554
  }
298
555
  /** Wrap a stream to enrich usage_update events and fire onUsage callback */
299
- async *enrichStream(source) {
556
+ async *enrichStream(source, options) {
557
+ const model = options.model;
300
558
  for await (const event of source) {
301
559
  if (event.type === "usage_update") {
302
560
  const usage = {
303
561
  promptTokens: event.promptTokens,
304
562
  completionTokens: event.completionTokens,
305
- model: this.config.model,
563
+ model,
306
564
  backend: this.backendName
307
565
  };
308
566
  this.callOnUsage(usage);
@@ -372,6 +630,35 @@ var BaseAgent = class {
372
630
  heartbeatResolve = null;
373
631
  }
374
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
+ }
375
662
  // ─── Guards ───────────────────────────────────────────────────
376
663
  guardReentrancy() {
377
664
  if (this.state === "running" || this.state === "streaming") {
@@ -519,40 +806,40 @@ var FilePermissionStore = class {
519
806
  this.filePath = path__namespace.resolve(filePath);
520
807
  }
521
808
  async isApproved(toolName) {
522
- const data = this.readFile();
809
+ const data = await this.readStore();
523
810
  return toolName in data.approvals;
524
811
  }
525
812
  async approve(toolName, scope) {
526
813
  if (scope === "once") return;
527
- const data = this.readFile();
814
+ const data = await this.readStore();
528
815
  data.approvals[toolName] = { scope, timestamp: Date.now() };
529
- this.writeFileAtomic(data);
816
+ await this.writeStoreAtomic(data);
530
817
  }
531
818
  async revoke(toolName) {
532
- const data = this.readFile();
819
+ const data = await this.readStore();
533
820
  delete data.approvals[toolName];
534
- this.writeFileAtomic(data);
821
+ await this.writeStoreAtomic(data);
535
822
  }
536
823
  async clear() {
537
- this.writeFileAtomic({ approvals: {} });
824
+ await this.writeStoreAtomic({ approvals: {} });
538
825
  }
539
826
  async dispose() {
540
827
  }
541
- readFile() {
828
+ async readStore() {
542
829
  try {
543
- const raw = fs__namespace.readFileSync(this.filePath, "utf-8");
830
+ const raw = await fsp__namespace.readFile(this.filePath, "utf-8");
544
831
  const parsed = JSON.parse(raw);
545
832
  if (parsed && typeof parsed.approvals === "object") return parsed;
546
833
  } catch {
547
834
  }
548
835
  return { approvals: {} };
549
836
  }
550
- writeFileAtomic(data) {
837
+ async writeStoreAtomic(data) {
551
838
  const dir = path__namespace.dirname(this.filePath);
552
- fs__namespace.mkdirSync(dir, { recursive: true });
839
+ await fsp__namespace.mkdir(dir, { recursive: true });
553
840
  const tmpPath = this.filePath + `.tmp.${process.pid}.${Date.now()}`;
554
- fs__namespace.writeFileSync(tmpPath, JSON.stringify(data, null, 2), "utf-8");
555
- fs__namespace.renameSync(tmpPath, this.filePath);
841
+ await fsp__namespace.writeFile(tmpPath, JSON.stringify(data, null, 2), "utf-8");
842
+ await fsp__namespace.rename(tmpPath, this.filePath);
556
843
  }
557
844
  };
558
845
  var CompositePermissionStore = class {
@@ -605,6 +892,7 @@ function createDefaultPermissionStore(projectDir) {
605
892
  }
606
893
 
607
894
  exports.AbortError = AbortError;
895
+ exports.ActivityTimeoutError = ActivityTimeoutError;
608
896
  exports.AgentSDKError = AgentSDKError;
609
897
  exports.BackendAlreadyRegisteredError = BackendAlreadyRegisteredError;
610
898
  exports.BackendNotFoundError = BackendNotFoundError;
@@ -612,6 +900,7 @@ exports.BaseAgent = BaseAgent;
612
900
  exports.CompositePermissionStore = CompositePermissionStore;
613
901
  exports.DependencyError = DependencyError;
614
902
  exports.DisposedError = DisposedError;
903
+ exports.ErrorCode = ErrorCode;
615
904
  exports.FilePermissionStore = FilePermissionStore;
616
905
  exports.InMemoryPermissionStore = InMemoryPermissionStore;
617
906
  exports.ReentrancyError = ReentrancyError;
@@ -619,17 +908,22 @@ exports.StructuredOutputError = StructuredOutputError;
619
908
  exports.SubprocessError = SubprocessError;
620
909
  exports.ToolExecutionError = ToolExecutionError;
621
910
  exports.buildSystemPrompt = buildSystemPrompt;
911
+ exports.classifyAgentError = classifyAgentError;
622
912
  exports.contentToText = contentToText;
623
913
  exports.createAgentService = createAgentService;
624
914
  exports.createDefaultPermissionStore = createDefaultPermissionStore;
915
+ exports.disposeBackend = disposeBackend;
625
916
  exports.getTextContent = getTextContent;
626
917
  exports.hasBackend = hasBackend;
627
918
  exports.isMultiPartContent = isMultiPartContent;
919
+ exports.isRecoverableErrorCode = isRecoverableErrorCode;
628
920
  exports.isTextContent = isTextContent;
629
921
  exports.isToolDefinition = isToolDefinition;
630
922
  exports.listBackends = listBackends;
923
+ exports.listConfigs = listConfigs;
631
924
  exports.messagesToPrompt = messagesToPrompt;
632
925
  exports.registerBackend = registerBackend;
926
+ exports.registerLazyBackend = registerLazyBackend;
633
927
  exports.resetRegistry = resetRegistry;
634
928
  exports.unregisterBackend = unregisterBackend;
635
929
  exports.zodToJsonSchema = zodToJsonSchema;