@witqq/agent-sdk 0.7.0 → 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.
Files changed (147) hide show
  1. package/README.md +140 -34
  2. package/dist/{types-CqvUAYxt.d.cts → agent-CW9XbmG_.d.ts} +137 -102
  3. package/dist/{types-CqvUAYxt.d.ts → agent-DxY68NZL.d.cts} +137 -102
  4. package/dist/auth/index.cjs +72 -1
  5. package/dist/auth/index.cjs.map +1 -1
  6. package/dist/auth/index.d.cts +21 -154
  7. package/dist/auth/index.d.ts +21 -154
  8. package/dist/auth/index.js +72 -1
  9. package/dist/auth/index.js.map +1 -1
  10. package/dist/backends/claude.cjs +480 -261
  11. package/dist/backends/claude.cjs.map +1 -1
  12. package/dist/backends/claude.d.cts +3 -1
  13. package/dist/backends/claude.d.ts +3 -1
  14. package/dist/backends/claude.js +480 -261
  15. package/dist/backends/claude.js.map +1 -1
  16. package/dist/backends/copilot.cjs +329 -97
  17. package/dist/backends/copilot.cjs.map +1 -1
  18. package/dist/backends/copilot.d.cts +12 -4
  19. package/dist/backends/copilot.d.ts +12 -4
  20. package/dist/backends/copilot.js +329 -97
  21. package/dist/backends/copilot.js.map +1 -1
  22. package/dist/backends/vercel-ai.cjs +294 -61
  23. package/dist/backends/vercel-ai.cjs.map +1 -1
  24. package/dist/backends/vercel-ai.d.cts +3 -1
  25. package/dist/backends/vercel-ai.d.ts +3 -1
  26. package/dist/backends/vercel-ai.js +294 -61
  27. package/dist/backends/vercel-ai.js.map +1 -1
  28. package/dist/backends-BSrsBYFn.d.cts +39 -0
  29. package/dist/backends-BSrsBYFn.d.ts +39 -0
  30. package/dist/chat/accumulator.cjs +1 -1
  31. package/dist/chat/accumulator.cjs.map +1 -1
  32. package/dist/chat/accumulator.d.cts +5 -2
  33. package/dist/chat/accumulator.d.ts +5 -2
  34. package/dist/chat/accumulator.js +1 -1
  35. package/dist/chat/accumulator.js.map +1 -1
  36. package/dist/chat/backends.cjs +736 -746
  37. package/dist/chat/backends.cjs.map +1 -1
  38. package/dist/chat/backends.d.cts +10 -6
  39. package/dist/chat/backends.d.ts +10 -6
  40. package/dist/chat/backends.js +736 -725
  41. package/dist/chat/backends.js.map +1 -1
  42. package/dist/chat/context.cjs +50 -0
  43. package/dist/chat/context.cjs.map +1 -1
  44. package/dist/chat/context.d.cts +27 -3
  45. package/dist/chat/context.d.ts +27 -3
  46. package/dist/chat/context.js +50 -0
  47. package/dist/chat/context.js.map +1 -1
  48. package/dist/chat/core.cjs +25 -2
  49. package/dist/chat/core.cjs.map +1 -1
  50. package/dist/chat/core.d.cts +30 -381
  51. package/dist/chat/core.d.ts +30 -381
  52. package/dist/chat/core.js +24 -3
  53. package/dist/chat/core.js.map +1 -1
  54. package/dist/chat/errors.cjs +48 -26
  55. package/dist/chat/errors.cjs.map +1 -1
  56. package/dist/chat/errors.d.cts +6 -31
  57. package/dist/chat/errors.d.ts +6 -31
  58. package/dist/chat/errors.js +48 -25
  59. package/dist/chat/errors.js.map +1 -1
  60. package/dist/chat/events.cjs.map +1 -1
  61. package/dist/chat/events.d.cts +6 -2
  62. package/dist/chat/events.d.ts +6 -2
  63. package/dist/chat/events.js.map +1 -1
  64. package/dist/chat/index.cjs +1199 -1008
  65. package/dist/chat/index.cjs.map +1 -1
  66. package/dist/chat/index.d.cts +35 -10
  67. package/dist/chat/index.d.ts +35 -10
  68. package/dist/chat/index.js +1196 -987
  69. package/dist/chat/index.js.map +1 -1
  70. package/dist/chat/react/theme.css +2517 -0
  71. package/dist/chat/react.cjs +2003 -1153
  72. package/dist/chat/react.cjs.map +1 -1
  73. package/dist/chat/react.d.cts +590 -121
  74. package/dist/chat/react.d.ts +590 -121
  75. package/dist/chat/react.js +1984 -1151
  76. package/dist/chat/react.js.map +1 -1
  77. package/dist/chat/runtime.cjs +401 -186
  78. package/dist/chat/runtime.cjs.map +1 -1
  79. package/dist/chat/runtime.d.cts +92 -28
  80. package/dist/chat/runtime.d.ts +92 -28
  81. package/dist/chat/runtime.js +401 -186
  82. package/dist/chat/runtime.js.map +1 -1
  83. package/dist/chat/server.cjs +2234 -209
  84. package/dist/chat/server.cjs.map +1 -1
  85. package/dist/chat/server.d.cts +451 -90
  86. package/dist/chat/server.d.ts +451 -90
  87. package/dist/chat/server.js +2221 -210
  88. package/dist/chat/server.js.map +1 -1
  89. package/dist/chat/sessions.cjs +25 -43
  90. package/dist/chat/sessions.cjs.map +1 -1
  91. package/dist/chat/sessions.d.cts +37 -118
  92. package/dist/chat/sessions.d.ts +37 -118
  93. package/dist/chat/sessions.js +25 -43
  94. package/dist/chat/sessions.js.map +1 -1
  95. package/dist/chat/sqlite.cjs +441 -0
  96. package/dist/chat/sqlite.cjs.map +1 -0
  97. package/dist/chat/sqlite.d.cts +128 -0
  98. package/dist/chat/sqlite.d.ts +128 -0
  99. package/dist/chat/sqlite.js +435 -0
  100. package/dist/chat/sqlite.js.map +1 -0
  101. package/dist/chat/state.cjs +14 -1
  102. package/dist/chat/state.cjs.map +1 -1
  103. package/dist/chat/state.d.cts +5 -2
  104. package/dist/chat/state.d.ts +5 -2
  105. package/dist/chat/state.js +14 -1
  106. package/dist/chat/state.js.map +1 -1
  107. package/dist/chat/storage.cjs +19 -10
  108. package/dist/chat/storage.cjs.map +1 -1
  109. package/dist/chat/storage.d.cts +11 -5
  110. package/dist/chat/storage.d.ts +11 -5
  111. package/dist/chat/storage.js +19 -10
  112. package/dist/chat/storage.js.map +1 -1
  113. package/dist/errors-C-so0M4t.d.cts +33 -0
  114. package/dist/errors-C-so0M4t.d.ts +33 -0
  115. package/dist/errors-CmVvczxZ.d.cts +28 -0
  116. package/dist/errors-CmVvczxZ.d.ts +28 -0
  117. package/dist/{in-process-transport-C2oPTYs6.d.ts → in-process-transport-C1JnJGVR.d.ts} +28 -23
  118. package/dist/{in-process-transport-DG-w5G6k.d.cts → in-process-transport-C7DSqPyX.d.cts} +28 -23
  119. package/dist/index.cjs +340 -46
  120. package/dist/index.cjs.map +1 -1
  121. package/dist/index.d.cts +292 -123
  122. package/dist/index.d.ts +292 -123
  123. package/dist/index.js +334 -47
  124. package/dist/index.js.map +1 -1
  125. package/dist/provider-types-PTSlRPNB.d.cts +39 -0
  126. package/dist/provider-types-PTSlRPNB.d.ts +39 -0
  127. package/dist/refresh-manager-B81PpYBr.d.cts +153 -0
  128. package/dist/refresh-manager-Dlv_iNZi.d.ts +153 -0
  129. package/dist/testing.cjs +383 -0
  130. package/dist/testing.cjs.map +1 -0
  131. package/dist/testing.d.cts +132 -0
  132. package/dist/testing.d.ts +132 -0
  133. package/dist/testing.js +377 -0
  134. package/dist/testing.js.map +1 -0
  135. package/dist/token-store-CSUBgYwn.d.ts +48 -0
  136. package/dist/token-store-CuC4hB9Z.d.cts +48 -0
  137. package/dist/{transport-DX1Nhm4N.d.cts → transport-Cdh3M0tS.d.cts} +5 -4
  138. package/dist/{transport-D1OaUgRk.d.ts → transport-Ciap4PWK.d.ts} +5 -4
  139. package/dist/{types-CGF7AEX1.d.cts → types-4vbcmPTp.d.cts} +4 -2
  140. package/dist/{types-Bh5AhqD-.d.ts → types-BxggH0Yh.d.ts} +4 -2
  141. package/dist/types-DRgd_9R7.d.cts +363 -0
  142. package/dist/types-ajANVzf7.d.ts +363 -0
  143. package/package.json +31 -6
  144. package/dist/errors-BDLbNu9w.d.cts +0 -13
  145. package/dist/errors-BDLbNu9w.d.ts +0 -13
  146. package/dist/types-DLZzlJxt.d.ts +0 -39
  147. package/dist/types-tE0CXwBl.d.cts +0 -39
@@ -4,9 +4,18 @@ import { createHash, randomBytes } from 'crypto';
4
4
  var AgentSDKError = class extends Error {
5
5
  /** @internal Marker for cross-bundle identity checks */
6
6
  _agentSDKError = true;
7
+ /** Machine-readable error code. Prefer values from the ErrorCode enum. */
8
+ code;
9
+ /** Whether this error is safe to retry */
10
+ retryable;
11
+ /** HTTP status code hint for error classification */
12
+ httpStatus;
7
13
  constructor(message, options) {
8
14
  super(message, options);
9
15
  this.name = "AgentSDKError";
16
+ this.code = options?.code;
17
+ this.retryable = options?.retryable ?? false;
18
+ this.httpStatus = options?.httpStatus;
10
19
  }
11
20
  /** Check if an error is an AgentSDKError (works across bundled copies) */
12
21
  static is(error) {
@@ -17,7 +26,7 @@ var AgentSDKError = class extends Error {
17
26
  // src/auth/types.ts
18
27
  var AuthError = class extends AgentSDKError {
19
28
  constructor(message, options) {
20
- super(message, options);
29
+ super(message, { ...options, code: "AUTH_EXPIRED" /* AUTH_EXPIRED */ });
21
30
  this.name = "AuthError";
22
31
  }
23
32
  };
@@ -130,6 +139,12 @@ var CopilotAuth = class {
130
139
  tokenType: data.token_type ?? "bearer",
131
140
  obtainedAt: Date.now()
132
141
  };
142
+ if (data.refresh_token) {
143
+ token.refreshToken = data.refresh_token;
144
+ }
145
+ if (data.expires_in) {
146
+ token.expiresIn = data.expires_in;
147
+ }
133
148
  try {
134
149
  const login = await this.fetchUserLogin(data.access_token, signal);
135
150
  if (login) token.login = login;
@@ -167,6 +182,62 @@ var CopilotAuth = class {
167
182
  const user = await response.json();
168
183
  return user.login;
169
184
  }
185
+ /**
186
+ * Refresh an expired Copilot token using a refresh token.
187
+ * Only works for GitHub App tokens that include a refresh_token.
188
+ *
189
+ * @param refreshToken - The refresh token from the original auth flow
190
+ * @param signal - Optional abort signal
191
+ * @returns Fresh CopilotAuthToken with new access and refresh tokens
192
+ * @throws {TokenExchangeError} If the refresh request fails
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * const auth = new CopilotAuth();
197
+ * const newToken = await auth.refreshToken(oldToken.refreshToken!);
198
+ * ```
199
+ */
200
+ async refreshToken(refreshToken, signal) {
201
+ const response = await this.fetchFn(ACCESS_TOKEN_URL, {
202
+ method: "POST",
203
+ headers: {
204
+ "Content-Type": "application/x-www-form-urlencoded",
205
+ Accept: "application/json"
206
+ },
207
+ body: new URLSearchParams({
208
+ client_id: CLIENT_ID,
209
+ grant_type: "refresh_token",
210
+ refresh_token: refreshToken
211
+ }),
212
+ signal
213
+ });
214
+ if (!response.ok) {
215
+ throw new TokenExchangeError(
216
+ `Token refresh failed: ${response.status} ${response.statusText}`
217
+ );
218
+ }
219
+ const data = await response.json();
220
+ if (data.error) {
221
+ throw new TokenExchangeError(
222
+ data.error_description ?? `Token refresh error: ${data.error}`
223
+ );
224
+ }
225
+ if (!data.access_token) {
226
+ throw new TokenExchangeError("Token refresh response missing access_token");
227
+ }
228
+ const token = {
229
+ accessToken: data.access_token,
230
+ tokenType: data.token_type ?? "bearer",
231
+ obtainedAt: Date.now()
232
+ };
233
+ if (data.refresh_token) {
234
+ token.refreshToken = data.refresh_token;
235
+ }
236
+ if (data.expires_in) {
237
+ token.expiresIn = data.expires_in;
238
+ }
239
+ return token;
240
+ }
170
241
  delay(ms, signal) {
171
242
  return new Promise((resolve, reject) => {
172
243
  const timer = setTimeout(resolve, ms);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/errors.ts","../../src/auth/types.ts","../../src/auth/copilot-auth.ts","../../src/auth/claude-auth.ts","../../src/auth/refresh-manager.ts"],"names":["CLIENT_ID","DEFAULT_SCOPES","nodeRandomBytes"],"mappings":";;;AAIO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA;AAAA,EAE9B,cAAA,GAAiB,IAAA;AAAA,EAE1B,WAAA,CAAY,SAAiB,OAAA,EAAwB;AACnD,IAAA,KAAA,CAAM,SAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AAAA;AAAA,EAGA,OAAO,GAAG,KAAA,EAAwC;AAChD,IAAA,OACE,KAAA,YAAiB,KAAA,IACjB,gBAAA,IAAoB,KAAA,IACnB,MAAwB,cAAA,KAAmB,IAAA;AAAA,EAEhD;AACF,CAAA;;;ACkHO,IAAM,SAAA,GAAN,cAAwB,aAAA,CAAc;AAAA,EAC3C,WAAA,CAAY,SAAiB,OAAA,EAAwB;AACnD,IAAA,KAAA,CAAM,SAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AAAA,EACd;AACF;AAGO,IAAM,sBAAA,GAAN,cAAqC,SAAA,CAAU;AAAA,EACpD,WAAA,GAAc;AACZ,IAAA,KAAA,CAAM,oDAAoD,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,wBAAA;AAAA,EACd;AACF;AAGO,IAAM,iBAAA,GAAN,cAAgC,SAAA,CAAU;AAAA,EAC/C,WAAA,GAAc;AACZ,IAAA,KAAA,CAAM,gCAAgC,CAAA;AACtC,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AAAA,EACd;AACF;AAMO,IAAM,kBAAA,GAAN,cAAiC,SAAA,CAAU;AAAA,EAChD,WAAA,CAAY,SAAiB,OAAA,EAAwB;AACnD,IAAA,KAAA,CAAM,SAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EACd;AACF;;;AChKA,IAAM,SAAA,GAAY,sBAAA;AAClB,IAAM,eAAA,GAAkB,sCAAA;AACxB,IAAM,gBAAA,GAAmB,6CAAA;AACzB,IAAM,YAAA,GAAe,6BAAA;AACrB,IAAM,cAAA,GAAiB,8BAAA;AACvB,IAAM,UAAA,GAAa,8CAAA;AAsCZ,IAAM,cAAN,MAAkB;AAAA,EACN,OAAA;AAAA;AAAA,EAGjB,YAAY,OAAA,EAA+B;AACzC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA,EAAS,KAAA,IAAS,UAAA,CAAW,KAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,gBAAgB,OAAA,EAGQ;AAC5B,IAAA,MAAM,MAAA,GAAS,SAAS,MAAA,IAAU,cAAA;AAClC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,eAAA,EAAiB;AAAA,MACnD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,mCAAA;AAAA,QAChB,MAAA,EAAQ;AAAA,OACV;AAAA,MACA,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,SAAA,EAAW,SAAA;AAAA,QACX,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,MACD,QAAQ,OAAA,EAAS;AAAA,KAClB,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,+BAAA,EAAkC,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA;AAAA,OAC1E;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAElC,IAAA,OAAO;AAAA,MACL,UAAU,IAAA,CAAK,SAAA;AAAA,MACf,iBAAiB,IAAA,CAAK,gBAAA;AAAA,MACtB,YAAA,EAAc,CAAC,MAAA,KACb,IAAA,CAAK,aAAa,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,QAAA,EAAU,MAAM;AAAA,KAC7D;AAAA,EACF;AAAA,EAEA,MAAc,YAAA,CACZ,UAAA,EACA,QAAA,EACA,MAAA,EAC2B;AAC3B,IAAA,IAAI,iBAAiB,QAAA,GAAW,GAAA;AAEhC,IAAA,OAAO,IAAA,EAAM;AACX,MAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,QAAA,MAAM,IAAI,UAAU,6BAA6B,CAAA;AAAA,MACnD;AAEA,MAAA,MAAM,IAAA,CAAK,KAAA,CAAM,cAAA,EAAgB,MAAM,CAAA;AAEvC,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAkB;AAAA,QACpD,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,mCAAA;AAAA,UAChB,MAAA,EAAQ;AAAA,SACV;AAAA,QACA,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,UACxB,SAAA,EAAW,SAAA;AAAA,UACX,WAAA,EAAa,UAAA;AAAA,UACb,UAAA,EAAY;AAAA,SACb,CAAA;AAAA,QACD;AAAA,OACD,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,SAAA;AAAA,UACR,CAAA,mBAAA,EAAsB,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA;AAAA,SAC9D;AAAA,MACF;AAEA,MAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAElC,MAAA,IAAI,KAAK,YAAA,EAAc;AACrB,QAAA,MAAM,KAAA,GAA0B;AAAA,UAC9B,aAAa,IAAA,CAAK,YAAA;AAAA,UAClB,SAAA,EAAW,KAAK,UAAA,IAAc,QAAA;AAAA,UAC9B,UAAA,EAAY,KAAK,GAAA;AAAI,SACvB;AAGA,QAAA,IAAI;AACF,UAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,cAAA,CAAe,IAAA,CAAK,cAAc,MAAM,CAAA;AACjE,UAAA,IAAI,KAAA,QAAa,KAAA,GAAQ,KAAA;AAAA,QAC3B,CAAA,CAAA,MAAQ;AAAA,QAER;AAEA,QAAA,OAAO,KAAA;AAAA,MACT;AAEA,MAAA,IAAI,IAAA,CAAK,UAAU,uBAAA,EAAyB;AAC1C,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,IAAA,CAAK,UAAU,WAAA,EAAa;AAC9B,QAAA,cAAA,GAAA,CAAkB,IAAA,CAAK,QAAA,IAAY,QAAA,GAAW,CAAA,IAAK,GAAA;AACnD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,IAAA,CAAK,UAAU,eAAA,EAAiB;AAClC,QAAA,MAAM,IAAI,sBAAA,EAAuB;AAAA,MACnC;AAEA,MAAA,IAAI,IAAA,CAAK,UAAU,eAAA,EAAiB;AAClC,QAAA,MAAM,IAAI,iBAAA,EAAkB;AAAA,MAC9B;AAEA,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,IAAA,CAAK,iBAAA,IAAqB,CAAA,kBAAA,EAAqB,IAAA,CAAK,KAAK,CAAA;AAAA,OAC3D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,cAAA,CACZ,KAAA,EACA,MAAA,EAC6B;AAC7B,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,YAAA,EAAc;AAAA,MAChD,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,UAAU,KAAK,CAAA,CAAA;AAAA,QAC9B,MAAA,EAAQ;AAAA,OACV;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,IAAI,CAAC,QAAA,CAAS,EAAA,EAAI,OAAO,MAAA;AAEzB,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEQ,KAAA,CAAM,IAAY,MAAA,EAAqC;AAC7D,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,EAAS,EAAE,CAAA;AACpC,MAAA,MAAA,EAAQ,gBAAA;AAAA,QACN,OAAA;AAAA,QACA,MAAM;AACJ,UAAA,YAAA,CAAa,KAAK,CAAA;AAClB,UAAA,MAAA,CAAO,IAAI,SAAA,CAAU,6BAA6B,CAAC,CAAA;AAAA,QACrD,CAAA;AAAA,QACA,EAAE,MAAM,IAAA;AAAK,OACf;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AACF;ACvNA,IAAMA,UAAAA,GAAY,sCAAA;AAClB,IAAM,aAAA,GAAgB,mCAAA;AACtB,IAAM,SAAA,GAAY,4CAAA;AAClB,IAAM,oBAAA,GACJ,iDAAA;AACF,IAAMC,eAAAA,GACJ,wEAAA;AAsBK,IAAM,UAAA,GAAN,MAAM,WAAA,CAAW;AAAA,EACL,OAAA;AAAA,EACA,WAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,YAAY,OAAA,EAGT;AACD,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA,EAAS,KAAA,IAAS,UAAA,CAAW,KAAA;AAC5C,IAAA,IAAA,CAAK,WAAA,GAAc,SAAS,WAAA,IAAe,kBAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,eAAe,OAAA,EAA6C;AAC1D,IAAA,MAAM,WAAA,GAAc,SAAS,WAAA,IAAe,oBAAA;AAC5C,IAAA,MAAM,MAAA,GAAS,SAAS,MAAA,IAAUA,eAAAA;AAElC,IAAA,MAAM,YAAA,GAAe,KAAK,oBAAA,EAAqB;AAC/C,IAAA,MAAM,KAAA,GAAQ,KAAK,aAAA,EAAc;AAEjC,IAAA,MAAM,eAAe,IAAA,CAAK,iBAAA;AAAA,MACxB,WAAA;AAAA,MACA,MAAA;AAAA,MACA,YAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OAAO;AAAA,MACL,YAAA;AAAA,MACA,YAAA,EAAc,CAAC,SAAA,KAAsB;AACnC,QAAA,MAAM,IAAA,GAAO,WAAA,CAAW,WAAA,CAAY,SAAS,CAAA;AAC7C,QAAA,OAAO,IAAA,CAAK,YAAA,CAAa,IAAA,EAAM,YAAA,EAAc,OAAO,WAAW,CAAA;AAAA,MACjE;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAO,YAAY,KAAA,EAAuB;AACxC,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAO,CAAA;AAC3B,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AACxC,MAAA,IAAI,MAAM,OAAO,IAAA;AAAA,IACnB,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AACnC,IAAA,IAAI,UAAU,CAAA,EAAG;AACf,MAAA,OAAO,OAAA,CAAQ,SAAA,CAAU,CAAA,EAAG,OAAO,CAAA;AAAA,IACrC;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,aAAa,YAAA,EAAgD;AACjE,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW;AAAA,MAC7C,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,UAAA,EAAY,eAAA;AAAA,QACZ,aAAA,EAAe,YAAA;AAAA,QACf,SAAA,EAAWD;AAAA,OACZ;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,MAAA,MAAM,IAAI,kBAAA;AAAA,QACR,CAAA,sBAAA,EAAyB,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA;AAAA,OAClD;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,OAAO,IAAA,CAAK,iBAAiB,IAAI,CAAA;AAAA,EACnC;AAAA,EAEQ,oBAAA,GAA+B;AACrC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,WAAA,CAAY,EAAE,CAAA;AACjC,IAAA,OAAO,YAAA,CAAa,KAAK,CAAA,CACtB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,OAAO,GAAG,CAAA;AAAA,EACvB;AAAA,EAEQ,aAAA,GAAwB;AAC9B,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,WAAA,CAAY,EAAE,CAAA;AACjC,IAAA,OAAO,UAAU,KAAK,CAAA;AAAA,EACxB;AAAA,EAEQ,iBAAA,CACN,WAAA,EACA,MAAA,EACA,YAAA,EACA,KAAA,EACQ;AACR,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,yBAAA,CAA0B,YAAY,CAAA;AAEjE,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,aAAa,CAAA;AACjC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AACnC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,WAAA,EAAaA,UAAS,CAAA;AAC3C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,eAAA,EAAiB,MAAM,CAAA;AAC5C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,WAAW,CAAA;AAChD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA;AACpC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,aAAa,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAM,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AAEnC,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAAA,EAEQ,0BAA0B,QAAA,EAA0B;AAC1D,IAAA,MAAM,IAAA,GAAO,WAAW,QAAQ,CAAA,CAAE,OAAO,QAAQ,CAAA,CAAE,OAAO,QAAQ,CAAA;AAClE,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAAA,EAClE;AAAA,EAEA,MAAc,YAAA,CACZ,IAAA,EACA,YAAA,EACA,OACA,WAAA,EAC0B;AAC1B,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW;AAAA,MAC7C,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,UAAA,EAAY,oBAAA;AAAA,QACZ,IAAA;AAAA,QACA,YAAA,EAAc,WAAA;AAAA,QACd,SAAA,EAAWA,UAAAA;AAAA,QACX,aAAA,EAAe,YAAA;AAAA,QACf;AAAA,OACD;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,MAAA,MAAM,IAAI,kBAAA;AAAA,QACR,CAAA,uBAAA,EAA0B,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA;AAAA,OACnD;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,OAAO,IAAA,CAAK,iBAAiB,IAAI,CAAA;AAAA,EACnC;AAAA,EAEQ,iBAAiB,IAAA,EAAsC;AAC7D,IAAA,OAAO;AAAA,MACL,aAAa,IAAA,CAAK,YAAA;AAAA,MAClB,SAAA,EAAW,KAAK,UAAA,IAAc,QAAA;AAAA,MAC9B,WAAW,IAAA,CAAK,UAAA;AAAA,MAChB,UAAA,EAAY,KAAK,GAAA,EAAI;AAAA,MACrB,cAAc,IAAA,CAAK,aAAA;AAAA,MACnB,QAAQ,IAAA,CAAK,KAAA,EAAO,KAAA,CAAM,GAAG,KAAK;AAAC,KACrC;AAAA,EACF;AACF;AAcA,SAAS,mBAAmB,IAAA,EAA0B;AACpD,EAAA,OAAO,IAAI,UAAA,CAAWE,WAAA,CAAgB,IAAI,CAAC,CAAA;AAC7C;AAEA,SAAS,aAAa,KAAA,EAA2B;AAC/C,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,QAAQ,CAAA;AAC7C;AAEA,SAAS,UAAU,KAAA,EAA2B;AAC5C,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,KAAK,CAAA;AAC1C;;;AC9IO,IAAM,sBAAN,MAA0B;AAAA,EACvB,YAAA;AAAA,EACS,SAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EAET,OAAA,GAAgD,IAAA;AAAA,EAChD,OAAA,GAAU,KAAA;AAAA,EACV,QAAA,GAAW,KAAA;AAAA,EAEF,SAAA,GAAyB;AAAA,IACxC,SAAA,sBAAe,GAAA,EAAI;AAAA,IACnB,KAAA,sBAAW,GAAA,EAAI;AAAA,IACf,OAAA,sBAAa,GAAA,EAAI;AAAA,IACjB,QAAA,sBAAc,GAAA;AAAI,GACpB;AAAA,EAEA,YAAY,OAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,YAAA,GAAe,EAAE,GAAG,OAAA,CAAQ,KAAA,EAAM;AACvC,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,OAAA;AACzB,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,gBAAA,IAAoB,GAAA;AAC7C,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,CAAA;AACxC,IAAA,IAAA,CAAK,YAAA,GAAe,QAAQ,YAAA,IAAgB,GAAA;AAC5C,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,GAAA;AAAA,EAC1C;AAAA;AAAA,EAGA,EAAA,CAAwB,OAAU,QAAA,EAAuC;AAEvE,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,CAAE,GAAA,CAAI,QAAiB,CAAA;AAC3C,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,GAAA,CAAyB,OAAU,QAAA,EAAuC;AAExE,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,CAAE,MAAA,CAAO,QAAiB,CAAA;AAC9C,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,KAAA,GAAmB;AACrB,IAAA,OAAO,EAAE,GAAG,IAAA,CAAK,YAAA,EAAa;AAAA,EAChC;AAAA;AAAA,EAGA,IAAI,SAAA,GAAqB;AACvB,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,UAAA,GAAsB;AACxB,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAA,GAAc;AACZ,IAAA,IAAI,KAAK,QAAA,EAAU;AACnB,IAAA,IAAI,KAAK,OAAA,EAAS;AAClB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,QAAA,EAAS;AAAA,EAChB;AAAA;AAAA,EAGA,IAAA,GAAa;AACX,IAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AACf,IAAA,IAAA,CAAK,UAAA,EAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,KAAA,EAAwB;AAClC,IAAA,IAAI,KAAK,QAAA,EAAU;AACnB,IAAA,IAAA,CAAK,YAAA,GAAe,EAAE,GAAG,KAAA,EAAM;AAC/B,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,IAAA,CAAK,UAAA,EAAW;AAChB,MAAA,IAAA,CAAK,QAAA,EAAS;AAAA,IAChB;AAAA,EACF;AAAA;AAAA,EAGA,OAAA,GAAgB;AACd,IAAA,IAAI,KAAK,QAAA,EAAU;AACnB,IAAA,IAAA,CAAK,IAAA,EAAK;AACV,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,KAAK,UAAU,CAAA;AAEpB,IAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,EAAG;AAC/C,MAAC,IAAqB,KAAA,EAAM;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA,EAIQ,QAAA,GAAiB;AACvB,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,QAAA,EAAU;AAEpC,IAAA,MAAM,OAAA,GAAU,KAAK,mBAAA,EAAoB;AAEzC,IAAA,IAAI,YAAY,IAAA,EAAM;AAEpB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,WAAW,CAAA,EAAG;AAEhB,MAAA,IAAA,CAAK,OAAA,GAAU,WAAW,MAAM;AAC9B,QAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,QAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,QAAA,EAAU;AACpC,QAAA,KAAK,KAAK,cAAA,EAAe;AAAA,MAC3B,GAAG,CAAC,CAAA;AACJ,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,OAAA,GAAU,WAAW,MAAM;AAC9B,MAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,MAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,QAAA,EAAU;AACpC,MAAA,KAAK,KAAK,cAAA,EAAe;AAAA,IAC3B,GAAG,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,IAAA,CAAK,UAAU,CAAC,CAAA;AAAA,EACvC;AAAA,EAEA,MAAc,cAAA,CAAe,OAAA,GAAU,CAAA,EAAkB;AACvD,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,QAAA,EAAU;AAEpC,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,YAAY,CAAA;AACvD,MAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,QAAA,EAAU;AACpC,MAAA,IAAA,CAAK,YAAA,GAAe,EAAE,GAAG,QAAA,EAAS;AAClC,MAAA,IAAA,CAAK,IAAA,CAAK,aAAa,QAAQ,CAAA;AAC/B,MAAA,IAAA,CAAK,QAAA,EAAS;AAAA,IAChB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,QAAA,EAAU;AACpC,MAAA,MAAM,KAAA,GAAQ,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAChE,MAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,KAAA,EAAO,OAAO,CAAA;AAEjC,MAAA,IAAI,OAAA,GAAU,KAAK,UAAA,EAAY;AAC7B,QAAA,MAAM,QAAQ,IAAA,CAAK,YAAA,GAAe,KAAK,GAAA,CAAI,CAAA,EAAG,UAAU,CAAC,CAAA;AACzD,QAAA,IAAA,CAAK,OAAA,GAAU,WAAW,MAAM;AAC9B,UAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,UAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,QAAA,EAAU;AACpC,UAAA,KAAK,IAAA,CAAK,cAAA,CAAe,OAAA,GAAU,CAAC,CAAA;AAAA,QACtC,GAAG,KAAK,CAAA;AAAA,MACV,CAAA,MAAO;AAEL,QAAA,IAAI,IAAA,CAAK,gBAAe,EAAG;AACzB,UAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AACf,UAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AAAA,QACrB,CAAA,MAAO;AAEL,UAAA,MAAM,SAAA,GAAY,KAAK,YAAA,CAAa,SAAA;AACpC,UAAA,IAAI,aAAa,IAAA,EAAM;AACvB,UAAA,MAAM,SAAA,GAAY,IAAA,CAAK,YAAA,CAAa,UAAA,GAAa,SAAA,GAAY,GAAA;AAC7D,UAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,SAAA,GAAY,KAAK,GAAA,EAAI,EAAG,KAAK,UAAU,CAAA;AAC/D,UAAA,IAAA,CAAK,OAAA,GAAU,WAAW,MAAM;AAC9B,YAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,YAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,QAAA,EAAU;AACpC,YAAA,KAAK,KAAK,cAAA,EAAe;AAAA,UAC3B,GAAG,MAAM,CAAA;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,mBAAA,GAAqC;AAC3C,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,SAAA,IAAa,IAAA,EAAM,OAAO,IAAA;AAEhD,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,SAAA,GAAY,GAAA;AACjD,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,YAAA,CAAa,UAAA,GAAa,aAAa,IAAA,CAAK,SAAA;AACrE,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,QAAQ,WAAA,GAAc,GAAA;AAG5B,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,cAAA,GAA0B;AAChC,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,SAAA,IAAa,IAAA,EAAM,OAAO,KAAA;AAChD,IAAA,MAAM,YAAY,IAAA,CAAK,YAAA,CAAa,UAAA,GAAa,IAAA,CAAK,aAAa,SAAA,GAAY,GAAA;AAC/E,IAAA,OAAO,IAAA,CAAK,KAAI,IAAK,SAAA;AAAA,EACvB;AAAA,EAEQ,UAAA,GAAmB;AACzB,IAAA,IAAI,IAAA,CAAK,YAAY,IAAA,EAAM;AACzB,MAAA,YAAA,CAAa,KAAK,OAAO,CAAA;AACzB,MAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AAAA,IACjB;AAAA,EACF;AAAA,EAEQ,IAAA,CAA0B,UAAa,IAAA,EAA+C;AAC5F,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,EAAG;AAC5C,MAAA,IAAI;AACF,QAAC,QAAA,CAAuC,GAAG,IAAI,CAAA;AAAA,MACjD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF","file":"index.js","sourcesContent":["/** Base error class for agent-sdk.\n *\n * Use `AgentSDKError.is(err)` for reliable cross-module `instanceof` checks\n * (works across separately bundled entry points where `instanceof` may fail). */\nexport class AgentSDKError extends Error {\n /** @internal Marker for cross-bundle identity checks */\n readonly _agentSDKError = true as const;\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AgentSDKError\";\n }\n\n /** Check if an error is an AgentSDKError (works across bundled copies) */\n static is(error: unknown): error is AgentSDKError {\n return (\n error instanceof Error &&\n \"_agentSDKError\" in error &&\n (error as AgentSDKError)._agentSDKError === true\n );\n }\n}\n\n/** Thrown when agent.run() is called while already running (M8 re-entrancy guard) */\nexport class ReentrancyError extends AgentSDKError {\n constructor() {\n super(\"Agent is already running. Await the current run before starting another.\");\n this.name = \"ReentrancyError\";\n }\n}\n\n/** Thrown when an operation is attempted on a disposed agent/service */\nexport class DisposedError extends AgentSDKError {\n constructor(entity: string) {\n super(`${entity} has been disposed and cannot be used.`);\n this.name = \"DisposedError\";\n }\n}\n\n/** Thrown when a backend is not found in the registry */\nexport class BackendNotFoundError extends AgentSDKError {\n constructor(backend: string) {\n super(\n `Unknown backend: \"${backend}\". ` +\n `Built-in: copilot, claude, vercel-ai. ` +\n `Custom: use registerBackend() first.`,\n );\n this.name = \"BackendNotFoundError\";\n }\n}\n\n/** Thrown when a backend is already registered */\nexport class BackendAlreadyRegisteredError extends AgentSDKError {\n constructor(backend: string) {\n super(`Backend \"${backend}\" is already registered. Use a different name or unregister first.`);\n this.name = \"BackendAlreadyRegisteredError\";\n }\n}\n\n/** Thrown when subprocess management fails */\nexport class SubprocessError extends AgentSDKError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"SubprocessError\";\n }\n}\n\n/** Thrown when a required peer dependency is not installed */\nexport class DependencyError extends AgentSDKError {\n public readonly packageName: string;\n\n constructor(packageName: string) {\n super(`${packageName} is not installed. Install it: npm install ${packageName}`);\n this.name = \"DependencyError\";\n this.packageName = packageName;\n }\n}\n\n/** Thrown when an agent run is aborted */\nexport class AbortError extends AgentSDKError {\n constructor() {\n super(\"Agent run was aborted.\");\n this.name = \"AbortError\";\n }\n}\n\n/** Thrown when a tool execution fails */\nexport class ToolExecutionError extends AgentSDKError {\n public readonly toolName: string;\n\n constructor(toolName: string, message: string, options?: ErrorOptions) {\n super(`Tool \"${toolName}\" failed: ${message}`, options);\n this.name = \"ToolExecutionError\";\n this.toolName = toolName;\n }\n}\n\n/** Thrown when structured output parsing fails */\nexport class StructuredOutputError extends AgentSDKError {\n constructor(message: string, options?: ErrorOptions) {\n super(`Structured output error: ${message}`, options);\n this.name = \"StructuredOutputError\";\n }\n}\n","// ─── Auth Token Types ──────────────────────────────────────────\n\nimport { AgentSDKError } from \"../errors.js\";\n\n/**\n * Base auth token returned by all auth providers.\n *\n * @example\n * ```ts\n * import type { AuthToken } from \"@witqq/agent-sdk/auth\";\n *\n * const token: AuthToken = {\n * accessToken: \"gho_abc123...\",\n * tokenType: \"bearer\",\n * obtainedAt: Date.now(),\n * };\n * ```\n */\nexport interface AuthToken {\n /** The access token string */\n accessToken: string;\n /** Token type (e.g. \"bearer\") */\n tokenType: string;\n /** Seconds until token expires (undefined = long-lived) */\n expiresIn?: number;\n /** Timestamp when the token was obtained */\n obtainedAt: number;\n}\n\n/**\n * Copilot-specific token (GitHub OAuth, long-lived).\n *\n * @example\n * ```ts\n * import type { CopilotAuthToken } from \"@witqq/agent-sdk/auth\";\n *\n * const token: CopilotAuthToken = {\n * accessToken: \"gho_abc123...\",\n * tokenType: \"bearer\",\n * obtainedAt: Date.now(),\n * login: \"octocat\",\n * };\n * ```\n */\nexport interface CopilotAuthToken extends AuthToken {\n /** GitHub user login associated with the token */\n login?: string;\n}\n\n/**\n * Claude-specific token (OAuth+PKCE, expires in 8h).\n *\n * @example\n * ```ts\n * import type { ClaudeAuthToken } from \"@witqq/agent-sdk/auth\";\n *\n * const token: ClaudeAuthToken = {\n * accessToken: \"sk-ant-oat01-...\",\n * tokenType: \"bearer\",\n * expiresIn: 28800,\n * obtainedAt: Date.now(),\n * refreshToken: \"sk-ant-rt01-...\",\n * scopes: [\"user:inference\", \"user:profile\"],\n * };\n * ```\n */\nexport interface ClaudeAuthToken extends AuthToken {\n /** Refresh token for obtaining new access tokens */\n refreshToken: string;\n /** OAuth scopes granted */\n scopes: string[];\n}\n\n// ─── Device Flow Types (Copilot) ──────────────────────────────\n\n/**\n * Result of initiating a GitHub Device Flow.\n *\n * @example\n * ```ts\n * import { CopilotAuth } from \"@witqq/agent-sdk/auth\";\n *\n * const auth = new CopilotAuth();\n * const { userCode, verificationUrl, waitForToken } = await auth.startDeviceFlow();\n * console.log(`Open ${verificationUrl} and enter code: ${userCode}`);\n * const token = await waitForToken();\n * ```\n */\nexport interface DeviceFlowResult {\n /** The code the user must enter at the verification URL */\n userCode: string;\n /** URL where the user enters the code */\n verificationUrl: string;\n /** Polls GitHub until user authorizes; resolves with token */\n waitForToken: (signal?: AbortSignal) => Promise<CopilotAuthToken>;\n}\n\n// ─── OAuth Flow Types (Claude) ────────────────────────────────\n\n/** Options for starting a Claude OAuth flow */\nexport interface OAuthFlowOptions {\n /** The redirect URI registered with the OAuth app */\n redirectUri?: string;\n /** OAuth scopes to request (defaults to user:profile user:inference) */\n scopes?: string;\n}\n\n/**\n * Result of initiating a Claude OAuth flow.\n *\n * @example\n * ```ts\n * import type { OAuthFlowResult } from \"@witqq/agent-sdk/auth\";\n *\n * const result: OAuthFlowResult = {\n * authorizeUrl: \"https://claude.ai/oauth/authorize?...\",\n * completeAuth: async (code) => ({ ... }),\n * };\n * // Open result.authorizeUrl in browser, get code from redirect\n * const token = await result.completeAuth(code);\n * ```\n */\nexport interface OAuthFlowResult {\n /** URL to open in browser for user authorization */\n authorizeUrl: string;\n /** Exchange the authorization code (or full redirect URL) for tokens */\n completeAuth: (codeOrUrl: string) => Promise<ClaudeAuthToken>;\n}\n\n// ─── Auth Errors ──────────────────────────────────────────────\n\n/** Base error for auth operations.\n * @param message - Error description\n * @param options - Standard ErrorOptions (e.g. cause)\n */\nexport class AuthError extends AgentSDKError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AuthError\";\n }\n}\n\n/** Device code expired before user authorized */\nexport class DeviceCodeExpiredError extends AuthError {\n constructor() {\n super(\"Device code expired. Please restart the auth flow.\");\n this.name = \"DeviceCodeExpiredError\";\n }\n}\n\n/** User denied access during OAuth flow */\nexport class AccessDeniedError extends AuthError {\n constructor() {\n super(\"Access was denied by the user.\");\n this.name = \"AccessDeniedError\";\n }\n}\n\n/** Token exchange or refresh failed.\n * @param message - Error description\n * @param options - Standard ErrorOptions (e.g. cause)\n */\nexport class TokenExchangeError extends AuthError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"TokenExchangeError\";\n }\n}\n","import type { CopilotAuthToken, DeviceFlowResult } from \"./types.js\";\nimport {\n AuthError,\n DeviceCodeExpiredError,\n AccessDeniedError,\n} from \"./types.js\";\n\nconst CLIENT_ID = \"Ov23ctDVkRmgkPke0Mmm\";\nconst DEVICE_CODE_URL = \"https://github.com/login/device/code\";\nconst ACCESS_TOKEN_URL = \"https://github.com/login/oauth/access_token\";\nconst USER_API_URL = \"https://api.github.com/user\";\nconst DEFAULT_SCOPES = \"read:user,read:org,repo,gist\";\nconst GRANT_TYPE = \"urn:ietf:params:oauth:grant-type:device_code\";\n\ninterface DeviceCodeResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n expires_in: number;\n interval: number;\n}\n\ninterface TokenPollResponse {\n access_token?: string;\n token_type?: string;\n scope?: string;\n error?: string;\n error_description?: string;\n interval?: number;\n}\n\ninterface GitHubUser {\n login: string;\n}\n\n/** Fetch function type for dependency injection in tests */\ntype FetchFn = typeof globalThis.fetch;\n\n/**\n * Programmatic GitHub Device Flow authentication for Copilot SDK.\n *\n * @example\n * ```ts\n * const auth = new CopilotAuth();\n * const flow = await auth.startDeviceFlow();\n * console.log(`Open ${flow.verificationUrl} and enter ${flow.userCode}`);\n * const token = await flow.waitForToken();\n * // Use token.accessToken with CopilotBackendOptions.githubToken\n * ```\n */\nexport class CopilotAuth {\n private readonly fetchFn: FetchFn;\n\n /** @param options - Optional configuration with custom fetch for testing */\n constructor(options?: { fetch?: FetchFn }) {\n this.fetchFn = options?.fetch ?? globalThis.fetch;\n }\n\n /**\n * Start the GitHub Device Flow.\n * Returns a device code result with user code, verification URL,\n * and a `waitForToken()` function that polls until the user authorizes.\n *\n * @param options - Optional scopes and abort signal\n * @returns Device flow result with user code, verification URL, and waitForToken poller\n * @throws {AuthError} If the device code request fails\n * @throws {DeviceCodeExpiredError} If the device code expires before user authorizes\n * @throws {AccessDeniedError} If the user denies access\n *\n * @example\n * ```ts\n * const auth = new CopilotAuth();\n * const { userCode, verificationUrl, waitForToken } = await auth.startDeviceFlow();\n * console.log(`Open ${verificationUrl} and enter code: ${userCode}`);\n * const token = await waitForToken();\n * ```\n */\n async startDeviceFlow(options?: {\n scopes?: string;\n signal?: AbortSignal;\n }): Promise<DeviceFlowResult> {\n const scopes = options?.scopes ?? DEFAULT_SCOPES;\n const response = await this.fetchFn(DEVICE_CODE_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n scope: scopes,\n }),\n signal: options?.signal,\n });\n\n if (!response.ok) {\n throw new AuthError(\n `Failed to request device code: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as DeviceCodeResponse;\n\n return {\n userCode: data.user_code,\n verificationUrl: data.verification_uri,\n waitForToken: (signal?: AbortSignal) =>\n this.pollForToken(data.device_code, data.interval, signal),\n };\n }\n\n private async pollForToken(\n deviceCode: string,\n interval: number,\n signal?: AbortSignal,\n ): Promise<CopilotAuthToken> {\n let pollIntervalMs = interval * 1000;\n\n while (true) {\n if (signal?.aborted) {\n throw new AuthError(\"Authentication was aborted.\");\n }\n\n await this.delay(pollIntervalMs, signal);\n\n const response = await this.fetchFn(ACCESS_TOKEN_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n device_code: deviceCode,\n grant_type: GRANT_TYPE,\n }),\n signal,\n });\n\n if (!response.ok) {\n throw new AuthError(\n `Token poll failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as TokenPollResponse;\n\n if (data.access_token) {\n const token: CopilotAuthToken = {\n accessToken: data.access_token,\n tokenType: data.token_type ?? \"bearer\",\n obtainedAt: Date.now(),\n };\n\n // Try to fetch user login\n try {\n const login = await this.fetchUserLogin(data.access_token, signal);\n if (login) token.login = login;\n } catch {\n // Non-critical: login is optional\n }\n\n return token;\n }\n\n if (data.error === \"authorization_pending\") {\n continue;\n }\n\n if (data.error === \"slow_down\") {\n pollIntervalMs = (data.interval ?? interval + 5) * 1000;\n continue;\n }\n\n if (data.error === \"expired_token\") {\n throw new DeviceCodeExpiredError();\n }\n\n if (data.error === \"access_denied\") {\n throw new AccessDeniedError();\n }\n\n throw new AuthError(\n data.error_description ?? `Unexpected error: ${data.error}`,\n );\n }\n }\n\n private async fetchUserLogin(\n token: string,\n signal?: AbortSignal,\n ): Promise<string | undefined> {\n const response = await this.fetchFn(USER_API_URL, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n },\n signal,\n });\n\n if (!response.ok) return undefined;\n\n const user = (await response.json()) as GitHubUser;\n return user.login;\n }\n\n private delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n reject(new AuthError(\"Authentication was aborted.\"));\n },\n { once: true },\n );\n });\n }\n}\n","import type { ClaudeAuthToken, OAuthFlowResult, OAuthFlowOptions } from \"./types.js\";\nimport { TokenExchangeError } from \"./types.js\";\nimport { createHash, randomBytes as nodeRandomBytes } from \"node:crypto\";\n\nconst CLIENT_ID = \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\";\nconst AUTHORIZE_URL = \"https://claude.ai/oauth/authorize\";\nconst TOKEN_URL = \"https://platform.claude.com/v1/oauth/token\";\nconst DEFAULT_REDIRECT_URI =\n \"https://platform.claude.com/oauth/code/callback\";\nconst DEFAULT_SCOPES =\n \"user:profile user:inference user:sessions:claude_code user:mcp_servers\";\n\n/** Fetch function type for dependency injection in tests */\ntype FetchFn = typeof globalThis.fetch;\n\n/** Random bytes generator for dependency injection in tests */\ntype RandomBytesFn = (size: number) => Uint8Array;\n\n/**\n * Programmatic OAuth+PKCE authentication for Claude SDK.\n *\n * @example\n * ```ts\n * const auth = new ClaudeAuth();\n * const { authorizeUrl, completeAuth } = auth.startOAuthFlow({\n * redirectUri: \"https://platform.claude.com/oauth/code/callback\",\n * });\n * // Open authorizeUrl in browser, get code from redirect\n * const token = await completeAuth(code);\n * // Use token with ClaudeBackendOptions: env.CLAUDE_CODE_OAUTH_TOKEN\n * ```\n */\nexport class ClaudeAuth {\n private readonly fetchFn: FetchFn;\n private readonly randomBytes: RandomBytesFn;\n\n /**\n * @param options - Optional configuration with custom fetch and random bytes for testing\n */\n constructor(options?: {\n fetch?: FetchFn;\n randomBytes?: RandomBytesFn;\n }) {\n this.fetchFn = options?.fetch ?? globalThis.fetch;\n this.randomBytes = options?.randomBytes ?? defaultRandomBytes;\n }\n\n /**\n * Start the Claude OAuth+PKCE flow.\n * Generates PKCE code verifier/challenge and returns an authorize URL\n * plus a `completeAuth(code)` function for token exchange.\n *\n * @param options - Redirect URI and optional scopes\n * @returns OAuth flow result with authorize URL and completeAuth function\n * @throws {AuthError} If PKCE generation fails\n *\n * @example\n * ```ts\n * const auth = new ClaudeAuth();\n * const { authorizeUrl, completeAuth } = auth.startOAuthFlow({\n * redirectUri: \"https://platform.claude.com/oauth/code/callback\",\n * });\n * console.log(`Open: ${authorizeUrl}`);\n * const token = await completeAuth(authorizationCode);\n * ```\n */\n startOAuthFlow(options?: OAuthFlowOptions): OAuthFlowResult {\n const redirectUri = options?.redirectUri ?? DEFAULT_REDIRECT_URI;\n const scopes = options?.scopes ?? DEFAULT_SCOPES;\n\n const codeVerifier = this.generateCodeVerifier();\n const state = this.generateState();\n\n const authorizeUrl = this.buildAuthorizeUrl(\n redirectUri,\n scopes,\n codeVerifier,\n state,\n );\n\n return {\n authorizeUrl,\n completeAuth: (codeOrUrl: string) => {\n const code = ClaudeAuth.extractCode(codeOrUrl);\n return this.exchangeCode(code, codeVerifier, state, redirectUri);\n },\n };\n }\n\n /**\n * Extract an authorization code from user input.\n * Accepts a raw code string or a full redirect URL containing a `code` query parameter.\n *\n * @param input - Raw authorization code or redirect URL\n * @returns The extracted authorization code\n *\n * @example\n * ```ts\n * ClaudeAuth.extractCode(\"abc123\"); // \"abc123\"\n * ClaudeAuth.extractCode(\"https://platform.claude.com/oauth/code/callback?code=abc123&state=xyz\"); // \"abc123\"\n * ```\n */\n static extractCode(input: string): string {\n const trimmed = input.trim();\n try {\n const url = new URL(trimmed);\n const code = url.searchParams.get(\"code\");\n if (code) return code;\n } catch {\n // Not a URL — treat as raw code\n }\n // Handle code#state format from redirect page\n const hashIdx = trimmed.indexOf(\"#\");\n if (hashIdx > 0) {\n return trimmed.substring(0, hashIdx);\n }\n return trimmed;\n }\n\n /**\n * Refresh an expired Claude token.\n *\n * @param refreshToken - The refresh token from a previous authentication\n * @returns New auth token with refreshed access token\n * @throws {TokenExchangeError} If the refresh request fails\n *\n * @example\n * ```ts\n * const auth = new ClaudeAuth();\n * const newToken = await auth.refreshToken(oldToken.refreshToken);\n * ```\n */\n async refreshToken(refreshToken: string): Promise<ClaudeAuthToken> {\n const response = await this.fetchFn(TOKEN_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: CLIENT_ID,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new TokenExchangeError(\n `Token refresh failed: ${response.status} ${text}`,\n );\n }\n\n const data = (await response.json()) as TokenResponse;\n return this.mapTokenResponse(data);\n }\n\n private generateCodeVerifier(): string {\n const bytes = this.randomBytes(96);\n return base64Encode(bytes)\n .replace(/\\+/g, \"~\")\n .replace(/=/g, \"_\")\n .replace(/\\//g, \"-\");\n }\n\n private generateState(): string {\n const bytes = this.randomBytes(16);\n return hexEncode(bytes);\n }\n\n private buildAuthorizeUrl(\n redirectUri: string,\n scopes: string,\n codeVerifier: string,\n state: string,\n ): string {\n const codeChallenge = this.generateCodeChallengeSync(codeVerifier);\n\n const url = new URL(AUTHORIZE_URL);\n url.searchParams.set(\"code\", \"true\");\n url.searchParams.set(\"client_id\", CLIENT_ID);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", redirectUri);\n url.searchParams.set(\"scope\", scopes);\n url.searchParams.set(\"code_challenge\", codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n url.searchParams.set(\"state\", state);\n\n return url.toString();\n }\n\n private generateCodeChallengeSync(verifier: string): string {\n const hash = createHash(\"sha256\").update(verifier).digest(\"base64\");\n return hash.split(\"=\")[0].replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n }\n\n private async exchangeCode(\n code: string,\n codeVerifier: string,\n state: string,\n redirectUri: string,\n ): Promise<ClaudeAuthToken> {\n const response = await this.fetchFn(TOKEN_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: CLIENT_ID,\n code_verifier: codeVerifier,\n state,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new TokenExchangeError(\n `Token exchange failed: ${response.status} ${text}`,\n );\n }\n\n const data = (await response.json()) as TokenResponse;\n return this.mapTokenResponse(data);\n }\n\n private mapTokenResponse(data: TokenResponse): ClaudeAuthToken {\n return {\n accessToken: data.access_token,\n tokenType: data.token_type ?? \"bearer\",\n expiresIn: data.expires_in,\n obtainedAt: Date.now(),\n refreshToken: data.refresh_token,\n scopes: data.scope?.split(\" \") ?? [],\n };\n }\n}\n\n// ─── Internal Types ───────────────────────────────────────────\n\ninterface TokenResponse {\n access_token: string;\n token_type?: string;\n expires_in?: number;\n scope?: string;\n refresh_token: string;\n}\n\n// ─── Utility Functions ────────────────────────────────────────\n\nfunction defaultRandomBytes(size: number): Uint8Array {\n return new Uint8Array(nodeRandomBytes(size));\n}\n\nfunction base64Encode(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString(\"base64\");\n}\n\nfunction hexEncode(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString(\"hex\");\n}\n","/**\n * Automatic background token refresh manager.\n *\n * Schedules token refresh at a configurable threshold before expiry\n * (default 80% of token lifetime). Emits events on refresh, failure,\n * and token expiry. Handles retry on failure and clean disposal.\n *\n * When all retries are exhausted but the token hasn't expired yet,\n * the manager waits until the token's expiry time and then starts\n * a fresh retry cycle. This continues until refresh succeeds or\n * the token expires.\n *\n * @example Basic usage\n * ```ts\n * import { TokenRefreshManager } from \"@witqq/agent-sdk/auth\";\n *\n * const manager = new TokenRefreshManager({\n * token: claudeToken,\n * refresh: (rt) => claudeAuth.refreshToken(rt),\n * });\n * manager.on(\"refreshed\", (newToken) => { tokenStore.save(\"claude\", newToken); });\n * manager.on(\"error\", (err) => { console.error(\"Refresh failed:\", err); });\n * manager.start();\n * // ...later\n * manager.dispose();\n * ```\n *\n * @example Integration with createAuthHandler\n * ```ts\n * import { TokenRefreshManager } from \"@witqq/agent-sdk/auth\";\n * import { createAuthHandler } from \"@witqq/agent-sdk/chat/server\";\n * import type { ClaudeAuthToken } from \"@witqq/agent-sdk/auth\";\n *\n * let refreshManager: TokenRefreshManager | undefined;\n *\n * const authHandler = createAuthHandler({\n * tokenStore,\n * onAuth: (provider, token) => {\n * // Clean up previous manager\n * refreshManager?.dispose();\n * refreshManager = undefined;\n *\n * if (provider === \"claude\" && token.expiresIn) {\n * refreshManager = new TokenRefreshManager({\n * token,\n * refresh: (t) =>\n * claudeAuth.refreshToken((t as ClaudeAuthToken).refreshToken),\n * });\n * refreshManager.on(\"refreshed\", (newToken) => {\n * tokenStore.save(\"claude\", newToken);\n * });\n * refreshManager.on(\"expired\", () => {\n * console.warn(\"Claude token expired — re-authentication required\");\n * });\n * refreshManager.start();\n * }\n * },\n * });\n * ```\n */\n\nimport type { AuthToken } from \"./types.js\";\n\n// ─── Types ─────────────────────────────────────────────────────\n\n/** Events emitted by TokenRefreshManager */\nexport interface TokenRefreshEvents {\n /** Emitted when token was successfully refreshed */\n refreshed: (token: AuthToken) => void;\n /** Emitted when refresh attempt failed (may retry) */\n error: (error: Error, attempt: number) => void;\n /** Emitted when token expired and could not be refreshed */\n expired: () => void;\n /** Emitted when manager is disposed */\n disposed: () => void;\n}\n\n/** Configuration for TokenRefreshManager */\nexport interface TokenRefreshOptions {\n /** Current token with expiresIn and obtainedAt */\n token: AuthToken;\n /**\n * Function that performs the actual token refresh.\n * Receives the current token and returns a new one.\n */\n refresh: (token: AuthToken) => Promise<AuthToken>;\n /**\n * Fraction of token lifetime at which to trigger refresh (0-1).\n * Default: 0.8 (refresh at 80% of lifetime, i.e. with 20% remaining)\n */\n refreshThreshold?: number;\n /**\n * Maximum retry attempts on refresh failure. Default: 3\n */\n maxRetries?: number;\n /**\n * Base delay between retries in ms. Exponential backoff applied. Default: 1000\n */\n retryDelayMs?: number;\n /**\n * Minimum schedule delay in ms (prevents scheduling in the past). Default: 1000\n */\n minDelayMs?: number;\n}\n\ntype EventName = keyof TokenRefreshEvents;\ntype ListenerMap = { [K in EventName]: Set<TokenRefreshEvents[K]> };\n\n// ─── Manager ───────────────────────────────────────────────────\n\n/**\n * Background token refresh manager with event emission and retry logic.\n *\n * Lifecycle: `new` → `start()` → (auto-refreshes) → `stop()` or `dispose()`\n */\nexport class TokenRefreshManager {\n private currentToken: AuthToken;\n private readonly refreshFn: (token: AuthToken) => Promise<AuthToken>;\n private readonly threshold: number;\n private readonly maxRetries: number;\n private readonly retryDelayMs: number;\n private readonly minDelayMs: number;\n\n private timerId: ReturnType<typeof setTimeout> | null = null;\n private running = false;\n private disposed = false;\n\n private readonly listeners: ListenerMap = {\n refreshed: new Set(),\n error: new Set(),\n expired: new Set(),\n disposed: new Set(),\n };\n\n constructor(options: TokenRefreshOptions) {\n this.currentToken = { ...options.token };\n this.refreshFn = options.refresh;\n this.threshold = options.refreshThreshold ?? 0.8;\n this.maxRetries = options.maxRetries ?? 3;\n this.retryDelayMs = options.retryDelayMs ?? 1000;\n this.minDelayMs = options.minDelayMs ?? 1000;\n }\n\n /** Register an event listener */\n on<K extends EventName>(event: K, listener: TokenRefreshEvents[K]): this {\n // TypeScript can't narrow Set type from generic key — safe because ListenerMap enforces per-event types\n this.listeners[event].add(listener as never);\n return this;\n }\n\n /** Remove an event listener */\n off<K extends EventName>(event: K, listener: TokenRefreshEvents[K]): this {\n // TypeScript can't narrow Set type from generic key — safe because ListenerMap enforces per-event types\n this.listeners[event].delete(listener as never);\n return this;\n }\n\n /** Current token managed by this instance */\n get token(): AuthToken {\n return { ...this.currentToken };\n }\n\n /** Whether the manager is currently running */\n get isRunning(): boolean {\n return this.running;\n }\n\n /** Whether the manager has been disposed */\n get isDisposed(): boolean {\n return this.disposed;\n }\n\n /**\n * Start automatic refresh scheduling.\n * If the token is already expired, emits \"expired\" immediately.\n * If the token has no expiresIn, does nothing (long-lived token).\n */\n start(): void {\n if (this.disposed) return;\n if (this.running) return;\n this.running = true;\n this.schedule();\n }\n\n /** Stop automatic refresh (can be restarted with start()) */\n stop(): void {\n this.running = false;\n this.clearTimer();\n }\n\n /**\n * Update the managed token (e.g. after manual refresh).\n * Reschedules automatic refresh if running.\n */\n updateToken(token: AuthToken): void {\n if (this.disposed) return;\n this.currentToken = { ...token };\n if (this.running) {\n this.clearTimer();\n this.schedule();\n }\n }\n\n /** Stop and clean up all resources */\n dispose(): void {\n if (this.disposed) return;\n this.stop();\n this.disposed = true;\n this.emit(\"disposed\");\n // Clear all listeners\n for (const set of Object.values(this.listeners)) {\n (set as Set<unknown>).clear();\n }\n }\n\n // ─── Private ──────────────────────────────────────────────────\n\n private schedule(): void {\n if (!this.running || this.disposed) return;\n\n const delayMs = this.computeRefreshDelay();\n\n if (delayMs === null) {\n // No expiresIn → long-lived token, nothing to schedule\n return;\n }\n\n if (delayMs <= 0) {\n // Past refresh point (or expired) — attempt refresh via timer to keep async chain clean\n this.timerId = setTimeout(() => {\n this.timerId = null;\n if (!this.running || this.disposed) return;\n void this.performRefresh();\n }, 0);\n return;\n }\n\n this.timerId = setTimeout(() => {\n this.timerId = null;\n if (!this.running || this.disposed) return;\n void this.performRefresh();\n }, Math.max(delayMs, this.minDelayMs));\n }\n\n private async performRefresh(attempt = 1): Promise<void> {\n if (!this.running || this.disposed) return;\n\n try {\n const newToken = await this.refreshFn(this.currentToken);\n if (!this.running || this.disposed) return;\n this.currentToken = { ...newToken };\n this.emit(\"refreshed\", newToken);\n this.schedule();\n } catch (err) {\n if (!this.running || this.disposed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit(\"error\", error, attempt);\n\n if (attempt < this.maxRetries) {\n const delay = this.retryDelayMs * Math.pow(2, attempt - 1);\n this.timerId = setTimeout(() => {\n this.timerId = null;\n if (!this.running || this.disposed) return;\n void this.performRefresh(attempt + 1);\n }, delay);\n } else {\n // All retries exhausted\n if (this.isTokenExpired()) {\n this.running = false;\n this.emit(\"expired\");\n } else {\n // Token not yet expired — wait until expiry time and start fresh retry cycle\n const expiresIn = this.currentToken.expiresIn;\n if (expiresIn == null) return; // invariant: unreachable from schedule() which checks expiresIn\n const expiresAt = this.currentToken.obtainedAt + expiresIn * 1000;\n const waitMs = Math.max(expiresAt - Date.now(), this.minDelayMs);\n this.timerId = setTimeout(() => {\n this.timerId = null;\n if (!this.running || this.disposed) return;\n void this.performRefresh();\n }, waitMs);\n }\n }\n }\n }\n\n private computeRefreshDelay(): number | null {\n if (this.currentToken.expiresIn == null) return null;\n\n const lifetimeMs = this.currentToken.expiresIn * 1000;\n const refreshAtMs = this.currentToken.obtainedAt + lifetimeMs * this.threshold;\n const now = Date.now();\n const delay = refreshAtMs - now;\n\n // Return raw delay — caller decides whether to clamp or treat as immediate\n return delay;\n }\n\n private isTokenExpired(): boolean {\n if (this.currentToken.expiresIn == null) return false;\n const expiresAt = this.currentToken.obtainedAt + this.currentToken.expiresIn * 1000;\n return Date.now() >= expiresAt;\n }\n\n private clearTimer(): void {\n if (this.timerId !== null) {\n clearTimeout(this.timerId);\n this.timerId = null;\n }\n }\n\n private emit<K extends EventName>(event: K, ...args: Parameters<TokenRefreshEvents[K]>): void {\n for (const listener of this.listeners[event]) {\n try {\n (listener as (...a: unknown[]) => void)(...args);\n } catch {\n // Listener errors should not crash the manager\n }\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/errors.ts","../../src/auth/types.ts","../../src/auth/copilot-auth.ts","../../src/auth/claude-auth.ts","../../src/auth/refresh-manager.ts"],"names":["CLIENT_ID","DEFAULT_SCOPES","nodeRandomBytes"],"mappings":"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","file":"index.js","sourcesContent":["import { ErrorCode } from \"./types/errors.js\";\n\n/** Options for constructing an AgentSDKError */\nexport interface AgentSDKErrorOptions extends ErrorOptions {\n /** Machine-readable error code */\n code?: string;\n /** Whether this error is retryable (default: false) */\n retryable?: boolean;\n /** HTTP status code hint (e.g. 401, 429, 500) */\n httpStatus?: number;\n}\n\n/** Base error class for agent-sdk.\n *\n * Use `AgentSDKError.is(err)` for reliable cross-module `instanceof` checks\n * (works across separately bundled entry points where `instanceof` may fail). */\nexport class AgentSDKError extends Error {\n /** @internal Marker for cross-bundle identity checks */\n readonly _agentSDKError = true as const;\n /** Machine-readable error code. Prefer values from the ErrorCode enum. */\n readonly code?: string;\n /** Whether this error is safe to retry */\n readonly retryable: boolean;\n /** HTTP status code hint for error classification */\n readonly httpStatus?: number;\n\n constructor(message: string, options?: AgentSDKErrorOptions) {\n super(message, options);\n this.name = \"AgentSDKError\";\n this.code = options?.code;\n this.retryable = options?.retryable ?? false;\n this.httpStatus = options?.httpStatus;\n }\n\n /** Check if an error is an AgentSDKError (works across bundled copies) */\n static is(error: unknown): error is AgentSDKError {\n return (\n error instanceof Error &&\n \"_agentSDKError\" in error &&\n (error as AgentSDKError)._agentSDKError === true\n );\n }\n}\n\n/** Thrown when agent.run() is called while already running (M8 re-entrancy guard) */\nexport class ReentrancyError extends AgentSDKError {\n constructor() {\n super(\"Agent is already running. Await the current run before starting another.\", {\n code: ErrorCode.REENTRANCY,\n });\n this.name = \"ReentrancyError\";\n }\n}\n\n/** Thrown when an operation is attempted on a disposed agent/service */\nexport class DisposedError extends AgentSDKError {\n constructor(entity: string) {\n super(`${entity} has been disposed and cannot be used.`, {\n code: ErrorCode.DISPOSED,\n });\n this.name = \"DisposedError\";\n }\n}\n\n/** Thrown when a backend is not found in the registry */\nexport class BackendNotFoundError extends AgentSDKError {\n constructor(backend: string) {\n super(\n `Unknown backend: \"${backend}\". ` +\n `Built-in: copilot, claude, vercel-ai. ` +\n `Custom: use registerBackend() first.`,\n { code: ErrorCode.BACKEND_NOT_INSTALLED },\n );\n this.name = \"BackendNotFoundError\";\n }\n}\n\n/** Thrown when a backend is already registered */\nexport class BackendAlreadyRegisteredError extends AgentSDKError {\n constructor(backend: string) {\n super(`Backend \"${backend}\" is already registered. Use a different name or unregister first.`);\n this.name = \"BackendAlreadyRegisteredError\";\n }\n}\n\n/** Thrown when subprocess management fails */\nexport class SubprocessError extends AgentSDKError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, { ...options, code: ErrorCode.DEPENDENCY_MISSING });\n this.name = \"SubprocessError\";\n }\n}\n\n/** Thrown when a required peer dependency is not installed */\nexport class DependencyError extends AgentSDKError {\n public readonly packageName: string;\n\n constructor(packageName: string) {\n super(`${packageName} is not installed. Install it: npm install ${packageName}`, {\n code: ErrorCode.DEPENDENCY_MISSING,\n });\n this.name = \"DependencyError\";\n this.packageName = packageName;\n }\n}\n\n/** Thrown when an agent run is aborted */\nexport class AbortError extends AgentSDKError {\n constructor() {\n super(\"Agent run was aborted.\", { code: ErrorCode.ABORTED });\n this.name = \"AbortError\";\n }\n}\n\n/** Thrown when a tool execution fails */\nexport class ToolExecutionError extends AgentSDKError {\n public readonly toolName: string;\n\n constructor(toolName: string, message: string, options?: ErrorOptions) {\n super(`Tool \"${toolName}\" failed: ${message}`, { ...options, code: ErrorCode.TOOL_EXECUTION });\n this.name = \"ToolExecutionError\";\n this.toolName = toolName;\n }\n}\n\n/** Thrown when a stream has no activity within the configured timeout */\nexport class ActivityTimeoutError extends AgentSDKError {\n constructor(timeoutMs: number) {\n super(`Stream activity timeout: no event received within ${timeoutMs}ms.`, {\n code: ErrorCode.TIMEOUT,\n retryable: true,\n });\n this.name = \"ActivityTimeoutError\";\n }\n}\n\n/** Thrown when structured output parsing fails */\nexport class StructuredOutputError extends AgentSDKError {\n constructor(message: string, options?: ErrorOptions) {\n super(`Structured output error: ${message}`, { ...options, code: ErrorCode.INVALID_RESPONSE });\n this.name = \"StructuredOutputError\";\n }\n}\n","// ─── Auth Token Types ──────────────────────────────────────────\n\nimport { AgentSDKError } from \"../errors.js\";\nimport { ErrorCode } from \"../types/errors.js\";\n\n/**\n * Base auth token returned by all auth providers.\n *\n * @example\n * ```ts\n * import type { AuthToken } from \"@witqq/agent-sdk/auth\";\n *\n * const token: AuthToken = {\n * accessToken: \"gho_abc123...\",\n * tokenType: \"bearer\",\n * obtainedAt: Date.now(),\n * };\n * ```\n */\nexport interface AuthToken {\n /** The access token string */\n accessToken: string;\n /** Token type (e.g. \"bearer\") */\n tokenType: string;\n /** Seconds until token expires (undefined = long-lived) */\n expiresIn?: number;\n /** Timestamp when the token was obtained */\n obtainedAt: number;\n}\n\n/**\n * Copilot-specific token (GitHub OAuth, long-lived).\n *\n * @example\n * ```ts\n * import type { CopilotAuthToken } from \"@witqq/agent-sdk/auth\";\n *\n * const token: CopilotAuthToken = {\n * accessToken: \"gho_abc123...\",\n * tokenType: \"bearer\",\n * obtainedAt: Date.now(),\n * login: \"octocat\",\n * };\n * ```\n */\nexport interface CopilotAuthToken extends AuthToken {\n /** GitHub user login associated with the token */\n login?: string;\n /** Refresh token for obtaining new access tokens (present when GitHub App has expiring tokens) */\n refreshToken?: string;\n}\n\n/**\n * Claude-specific token (OAuth+PKCE, expires in 8h).\n *\n * @example\n * ```ts\n * import type { ClaudeAuthToken } from \"@witqq/agent-sdk/auth\";\n *\n * const token: ClaudeAuthToken = {\n * accessToken: \"sk-ant-oat01-...\",\n * tokenType: \"bearer\",\n * expiresIn: 28800,\n * obtainedAt: Date.now(),\n * refreshToken: \"sk-ant-rt01-...\",\n * scopes: [\"user:inference\", \"user:profile\"],\n * };\n * ```\n */\nexport interface ClaudeAuthToken extends AuthToken {\n /** Refresh token for obtaining new access tokens */\n refreshToken: string;\n /** OAuth scopes granted */\n scopes: string[];\n}\n\n// ─── Device Flow Types (Copilot) ──────────────────────────────\n\n/**\n * Result of initiating a GitHub Device Flow.\n *\n * @example\n * ```ts\n * import { CopilotAuth } from \"@witqq/agent-sdk/auth\";\n *\n * const auth = new CopilotAuth();\n * const { userCode, verificationUrl, waitForToken } = await auth.startDeviceFlow();\n * console.log(`Open ${verificationUrl} and enter code: ${userCode}`);\n * const token = await waitForToken();\n * ```\n */\nexport interface DeviceFlowResult {\n /** The code the user must enter at the verification URL */\n userCode: string;\n /** URL where the user enters the code */\n verificationUrl: string;\n /** Polls GitHub until user authorizes; resolves with token */\n waitForToken: (signal?: AbortSignal) => Promise<CopilotAuthToken>;\n}\n\n// ─── OAuth Flow Types (Claude) ────────────────────────────────\n\n/** Options for starting a Claude OAuth flow */\nexport interface OAuthFlowOptions {\n /** The redirect URI registered with the OAuth app */\n redirectUri?: string;\n /** OAuth scopes to request (defaults to user:profile user:inference) */\n scopes?: string;\n}\n\n/**\n * Result of initiating a Claude OAuth flow.\n *\n * @example\n * ```ts\n * import type { OAuthFlowResult } from \"@witqq/agent-sdk/auth\";\n *\n * const result: OAuthFlowResult = {\n * authorizeUrl: \"https://claude.ai/oauth/authorize?...\",\n * completeAuth: async (code) => ({ ... }),\n * };\n * // Open result.authorizeUrl in browser, get code from redirect\n * const token = await result.completeAuth(code);\n * ```\n */\nexport interface OAuthFlowResult {\n /** URL to open in browser for user authorization */\n authorizeUrl: string;\n /** Exchange the authorization code (or full redirect URL) for tokens */\n completeAuth: (codeOrUrl: string) => Promise<ClaudeAuthToken>;\n}\n\n// ─── Auth Errors ──────────────────────────────────────────────\n\n/** Base error for auth operations.\n * @param message - Error description\n * @param options - Standard ErrorOptions (e.g. cause)\n */\nexport class AuthError extends AgentSDKError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, { ...options, code: ErrorCode.AUTH_EXPIRED });\n this.name = \"AuthError\";\n }\n}\n\n/** Device code expired before user authorized */\nexport class DeviceCodeExpiredError extends AuthError {\n constructor() {\n super(\"Device code expired. Please restart the auth flow.\");\n this.name = \"DeviceCodeExpiredError\";\n }\n}\n\n/** User denied access during OAuth flow */\nexport class AccessDeniedError extends AuthError {\n constructor() {\n super(\"Access was denied by the user.\");\n this.name = \"AccessDeniedError\";\n }\n}\n\n/** Token exchange or refresh failed.\n * @param message - Error description\n * @param options - Standard ErrorOptions (e.g. cause)\n */\nexport class TokenExchangeError extends AuthError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"TokenExchangeError\";\n }\n}\n","import type { CopilotAuthToken, DeviceFlowResult } from \"./types.js\";\nimport {\n AuthError,\n DeviceCodeExpiredError,\n AccessDeniedError,\n TokenExchangeError,\n} from \"./types.js\";\n\nconst CLIENT_ID = \"Ov23ctDVkRmgkPke0Mmm\";\nconst DEVICE_CODE_URL = \"https://github.com/login/device/code\";\nconst ACCESS_TOKEN_URL = \"https://github.com/login/oauth/access_token\";\nconst USER_API_URL = \"https://api.github.com/user\";\nconst DEFAULT_SCOPES = \"read:user,read:org,repo,gist\";\nconst GRANT_TYPE = \"urn:ietf:params:oauth:grant-type:device_code\";\n\ninterface DeviceCodeResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n expires_in: number;\n interval: number;\n}\n\ninterface TokenPollResponse {\n access_token?: string;\n token_type?: string;\n scope?: string;\n refresh_token?: string;\n expires_in?: number;\n error?: string;\n error_description?: string;\n interval?: number;\n}\n\ninterface GitHubUser {\n login: string;\n}\n\n/** Fetch function type for dependency injection in tests */\ntype FetchFn = typeof globalThis.fetch;\n\n/**\n * Programmatic GitHub Device Flow authentication for Copilot SDK.\n *\n * @example\n * ```ts\n * const auth = new CopilotAuth();\n * const flow = await auth.startDeviceFlow();\n * console.log(`Open ${flow.verificationUrl} and enter ${flow.userCode}`);\n * const token = await flow.waitForToken();\n * // Use token.accessToken with CopilotBackendOptions.githubToken\n * ```\n */\nexport class CopilotAuth {\n private readonly fetchFn: FetchFn;\n\n /** @param options - Optional configuration with custom fetch for testing */\n constructor(options?: { fetch?: FetchFn }) {\n this.fetchFn = options?.fetch ?? globalThis.fetch;\n }\n\n /**\n * Start the GitHub Device Flow.\n * Returns a device code result with user code, verification URL,\n * and a `waitForToken()` function that polls until the user authorizes.\n *\n * @param options - Optional scopes and abort signal\n * @returns Device flow result with user code, verification URL, and waitForToken poller\n * @throws {AuthError} If the device code request fails\n * @throws {DeviceCodeExpiredError} If the device code expires before user authorizes\n * @throws {AccessDeniedError} If the user denies access\n *\n * @example\n * ```ts\n * const auth = new CopilotAuth();\n * const { userCode, verificationUrl, waitForToken } = await auth.startDeviceFlow();\n * console.log(`Open ${verificationUrl} and enter code: ${userCode}`);\n * const token = await waitForToken();\n * ```\n */\n async startDeviceFlow(options?: {\n scopes?: string;\n signal?: AbortSignal;\n }): Promise<DeviceFlowResult> {\n const scopes = options?.scopes ?? DEFAULT_SCOPES;\n const response = await this.fetchFn(DEVICE_CODE_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n scope: scopes,\n }),\n signal: options?.signal,\n });\n\n if (!response.ok) {\n throw new AuthError(\n `Failed to request device code: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as DeviceCodeResponse;\n\n return {\n userCode: data.user_code,\n verificationUrl: data.verification_uri,\n waitForToken: (signal?: AbortSignal) =>\n this.pollForToken(data.device_code, data.interval, signal),\n };\n }\n\n private async pollForToken(\n deviceCode: string,\n interval: number,\n signal?: AbortSignal,\n ): Promise<CopilotAuthToken> {\n let pollIntervalMs = interval * 1000;\n\n while (true) {\n if (signal?.aborted) {\n throw new AuthError(\"Authentication was aborted.\");\n }\n\n await this.delay(pollIntervalMs, signal);\n\n const response = await this.fetchFn(ACCESS_TOKEN_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n device_code: deviceCode,\n grant_type: GRANT_TYPE,\n }),\n signal,\n });\n\n if (!response.ok) {\n throw new AuthError(\n `Token poll failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as TokenPollResponse;\n\n if (data.access_token) {\n const token: CopilotAuthToken = {\n accessToken: data.access_token,\n tokenType: data.token_type ?? \"bearer\",\n obtainedAt: Date.now(),\n };\n\n if (data.refresh_token) {\n token.refreshToken = data.refresh_token;\n }\n if (data.expires_in) {\n token.expiresIn = data.expires_in;\n }\n\n // Try to fetch user login\n try {\n const login = await this.fetchUserLogin(data.access_token, signal);\n if (login) token.login = login;\n } catch {\n // Non-critical: login is optional\n }\n\n return token;\n }\n\n if (data.error === \"authorization_pending\") {\n continue;\n }\n\n if (data.error === \"slow_down\") {\n pollIntervalMs = (data.interval ?? interval + 5) * 1000;\n continue;\n }\n\n if (data.error === \"expired_token\") {\n throw new DeviceCodeExpiredError();\n }\n\n if (data.error === \"access_denied\") {\n throw new AccessDeniedError();\n }\n\n throw new AuthError(\n data.error_description ?? `Unexpected error: ${data.error}`,\n );\n }\n }\n\n private async fetchUserLogin(\n token: string,\n signal?: AbortSignal,\n ): Promise<string | undefined> {\n const response = await this.fetchFn(USER_API_URL, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n },\n signal,\n });\n\n if (!response.ok) return undefined;\n\n const user = (await response.json()) as GitHubUser;\n return user.login;\n }\n\n /**\n * Refresh an expired Copilot token using a refresh token.\n * Only works for GitHub App tokens that include a refresh_token.\n *\n * @param refreshToken - The refresh token from the original auth flow\n * @param signal - Optional abort signal\n * @returns Fresh CopilotAuthToken with new access and refresh tokens\n * @throws {TokenExchangeError} If the refresh request fails\n *\n * @example\n * ```ts\n * const auth = new CopilotAuth();\n * const newToken = await auth.refreshToken(oldToken.refreshToken!);\n * ```\n */\n async refreshToken(\n refreshToken: string,\n signal?: AbortSignal,\n ): Promise<CopilotAuthToken> {\n const response = await this.fetchFn(ACCESS_TOKEN_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n }),\n signal,\n });\n\n if (!response.ok) {\n throw new TokenExchangeError(\n `Token refresh failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as TokenPollResponse;\n\n if (data.error) {\n throw new TokenExchangeError(\n data.error_description ?? `Token refresh error: ${data.error}`,\n );\n }\n\n if (!data.access_token) {\n throw new TokenExchangeError(\"Token refresh response missing access_token\");\n }\n\n const token: CopilotAuthToken = {\n accessToken: data.access_token,\n tokenType: data.token_type ?? \"bearer\",\n obtainedAt: Date.now(),\n };\n\n if (data.refresh_token) {\n token.refreshToken = data.refresh_token;\n }\n if (data.expires_in) {\n token.expiresIn = data.expires_in;\n }\n\n return token;\n }\n\n private delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n reject(new AuthError(\"Authentication was aborted.\"));\n },\n { once: true },\n );\n });\n }\n}\n","import type { ClaudeAuthToken, OAuthFlowResult, OAuthFlowOptions } from \"./types.js\";\nimport { TokenExchangeError } from \"./types.js\";\nimport { createHash, randomBytes as nodeRandomBytes } from \"node:crypto\";\n\nconst CLIENT_ID = \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\";\nconst AUTHORIZE_URL = \"https://claude.ai/oauth/authorize\";\nconst TOKEN_URL = \"https://platform.claude.com/v1/oauth/token\";\nconst DEFAULT_REDIRECT_URI =\n \"https://platform.claude.com/oauth/code/callback\";\nconst DEFAULT_SCOPES =\n \"user:profile user:inference user:sessions:claude_code user:mcp_servers\";\n\n/** Fetch function type for dependency injection in tests */\ntype FetchFn = typeof globalThis.fetch;\n\n/** Random bytes generator for dependency injection in tests */\ntype RandomBytesFn = (size: number) => Uint8Array;\n\n/**\n * Programmatic OAuth+PKCE authentication for Claude SDK.\n *\n * @example\n * ```ts\n * const auth = new ClaudeAuth();\n * const { authorizeUrl, completeAuth } = auth.startOAuthFlow({\n * redirectUri: \"https://platform.claude.com/oauth/code/callback\",\n * });\n * // Open authorizeUrl in browser, get code from redirect\n * const token = await completeAuth(code);\n * // Use token with ClaudeBackendOptions: env.CLAUDE_CODE_OAUTH_TOKEN\n * ```\n */\nexport class ClaudeAuth {\n private readonly fetchFn: FetchFn;\n private readonly randomBytes: RandomBytesFn;\n\n /**\n * @param options - Optional configuration with custom fetch and random bytes for testing\n */\n constructor(options?: {\n fetch?: FetchFn;\n randomBytes?: RandomBytesFn;\n }) {\n this.fetchFn = options?.fetch ?? globalThis.fetch;\n this.randomBytes = options?.randomBytes ?? defaultRandomBytes;\n }\n\n /**\n * Start the Claude OAuth+PKCE flow.\n * Generates PKCE code verifier/challenge and returns an authorize URL\n * plus a `completeAuth(code)` function for token exchange.\n *\n * @param options - Redirect URI and optional scopes\n * @returns OAuth flow result with authorize URL and completeAuth function\n * @throws {AuthError} If PKCE generation fails\n *\n * @example\n * ```ts\n * const auth = new ClaudeAuth();\n * const { authorizeUrl, completeAuth } = auth.startOAuthFlow({\n * redirectUri: \"https://platform.claude.com/oauth/code/callback\",\n * });\n * console.log(`Open: ${authorizeUrl}`);\n * const token = await completeAuth(authorizationCode);\n * ```\n */\n startOAuthFlow(options?: OAuthFlowOptions): OAuthFlowResult {\n const redirectUri = options?.redirectUri ?? DEFAULT_REDIRECT_URI;\n const scopes = options?.scopes ?? DEFAULT_SCOPES;\n\n const codeVerifier = this.generateCodeVerifier();\n const state = this.generateState();\n\n const authorizeUrl = this.buildAuthorizeUrl(\n redirectUri,\n scopes,\n codeVerifier,\n state,\n );\n\n return {\n authorizeUrl,\n completeAuth: (codeOrUrl: string) => {\n const code = ClaudeAuth.extractCode(codeOrUrl);\n return this.exchangeCode(code, codeVerifier, state, redirectUri);\n },\n };\n }\n\n /**\n * Extract an authorization code from user input.\n * Accepts a raw code string or a full redirect URL containing a `code` query parameter.\n *\n * @param input - Raw authorization code or redirect URL\n * @returns The extracted authorization code\n *\n * @example\n * ```ts\n * ClaudeAuth.extractCode(\"abc123\"); // \"abc123\"\n * ClaudeAuth.extractCode(\"https://platform.claude.com/oauth/code/callback?code=abc123&state=xyz\"); // \"abc123\"\n * ```\n */\n static extractCode(input: string): string {\n const trimmed = input.trim();\n try {\n const url = new URL(trimmed);\n const code = url.searchParams.get(\"code\");\n if (code) return code;\n } catch {\n // Not a URL — treat as raw code\n }\n // Handle code#state format from redirect page\n const hashIdx = trimmed.indexOf(\"#\");\n if (hashIdx > 0) {\n return trimmed.substring(0, hashIdx);\n }\n return trimmed;\n }\n\n /**\n * Refresh an expired Claude token.\n *\n * @param refreshToken - The refresh token from a previous authentication\n * @returns New auth token with refreshed access token\n * @throws {TokenExchangeError} If the refresh request fails\n *\n * @example\n * ```ts\n * const auth = new ClaudeAuth();\n * const newToken = await auth.refreshToken(oldToken.refreshToken);\n * ```\n */\n async refreshToken(refreshToken: string): Promise<ClaudeAuthToken> {\n const response = await this.fetchFn(TOKEN_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: CLIENT_ID,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new TokenExchangeError(\n `Token refresh failed: ${response.status} ${text}`,\n );\n }\n\n const data = (await response.json()) as TokenResponse;\n return this.mapTokenResponse(data);\n }\n\n private generateCodeVerifier(): string {\n const bytes = this.randomBytes(96);\n return base64Encode(bytes)\n .replace(/\\+/g, \"~\")\n .replace(/=/g, \"_\")\n .replace(/\\//g, \"-\");\n }\n\n private generateState(): string {\n const bytes = this.randomBytes(16);\n return hexEncode(bytes);\n }\n\n private buildAuthorizeUrl(\n redirectUri: string,\n scopes: string,\n codeVerifier: string,\n state: string,\n ): string {\n const codeChallenge = this.generateCodeChallengeSync(codeVerifier);\n\n const url = new URL(AUTHORIZE_URL);\n url.searchParams.set(\"code\", \"true\");\n url.searchParams.set(\"client_id\", CLIENT_ID);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", redirectUri);\n url.searchParams.set(\"scope\", scopes);\n url.searchParams.set(\"code_challenge\", codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n url.searchParams.set(\"state\", state);\n\n return url.toString();\n }\n\n private generateCodeChallengeSync(verifier: string): string {\n const hash = createHash(\"sha256\").update(verifier).digest(\"base64\");\n return hash.split(\"=\")[0].replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n }\n\n private async exchangeCode(\n code: string,\n codeVerifier: string,\n state: string,\n redirectUri: string,\n ): Promise<ClaudeAuthToken> {\n const response = await this.fetchFn(TOKEN_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: CLIENT_ID,\n code_verifier: codeVerifier,\n state,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new TokenExchangeError(\n `Token exchange failed: ${response.status} ${text}`,\n );\n }\n\n const data = (await response.json()) as TokenResponse;\n return this.mapTokenResponse(data);\n }\n\n private mapTokenResponse(data: TokenResponse): ClaudeAuthToken {\n return {\n accessToken: data.access_token,\n tokenType: data.token_type ?? \"bearer\",\n expiresIn: data.expires_in,\n obtainedAt: Date.now(),\n refreshToken: data.refresh_token,\n scopes: data.scope?.split(\" \") ?? [],\n };\n }\n}\n\n// ─── Internal Types ───────────────────────────────────────────\n\ninterface TokenResponse {\n access_token: string;\n token_type?: string;\n expires_in?: number;\n scope?: string;\n refresh_token: string;\n}\n\n// ─── Utility Functions ────────────────────────────────────────\n\nfunction defaultRandomBytes(size: number): Uint8Array {\n return new Uint8Array(nodeRandomBytes(size));\n}\n\nfunction base64Encode(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString(\"base64\");\n}\n\nfunction hexEncode(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString(\"hex\");\n}\n","/**\n * Automatic background token refresh manager.\n *\n * Schedules token refresh at a configurable threshold before expiry\n * (default 80% of token lifetime). Emits events on refresh, failure,\n * and token expiry. Handles retry on failure and clean disposal.\n *\n * When all retries are exhausted but the token hasn't expired yet,\n * the manager waits until the token's expiry time and then starts\n * a fresh retry cycle. This continues until refresh succeeds or\n * the token expires.\n *\n * @example Basic usage\n * ```ts\n * import { TokenRefreshManager } from \"@witqq/agent-sdk/auth\";\n *\n * const manager = new TokenRefreshManager({\n * token: claudeToken,\n * refresh: (rt) => claudeAuth.refreshToken(rt),\n * });\n * manager.on(\"refreshed\", (newToken) => { tokenStore.save(\"claude\", newToken); });\n * manager.on(\"error\", (err) => { console.error(\"Refresh failed:\", err); });\n * manager.start();\n * // ...later\n * manager.dispose();\n * ```\n *\n * @example Integration with createAuthHandler\n * ```ts\n * import { TokenRefreshManager } from \"@witqq/agent-sdk/auth\";\n * import { createAuthHandler } from \"@witqq/agent-sdk/chat/server\";\n * import type { ClaudeAuthToken } from \"@witqq/agent-sdk/auth\";\n *\n * let refreshManager: TokenRefreshManager | undefined;\n *\n * const authHandler = createAuthHandler({\n * tokenStore,\n * onAuth: (provider, token) => {\n * // Clean up previous manager\n * refreshManager?.dispose();\n * refreshManager = undefined;\n *\n * if (provider === \"claude\" && token.expiresIn) {\n * refreshManager = new TokenRefreshManager({\n * token,\n * refresh: (t) =>\n * claudeAuth.refreshToken((t as ClaudeAuthToken).refreshToken),\n * });\n * refreshManager.on(\"refreshed\", (newToken) => {\n * tokenStore.save(\"claude\", newToken);\n * });\n * refreshManager.on(\"expired\", () => {\n * console.warn(\"Claude token expired — re-authentication required\");\n * });\n * refreshManager.start();\n * }\n * },\n * });\n * ```\n */\n\nimport type { AuthToken } from \"./types.js\";\n\n// ─── Types ─────────────────────────────────────────────────────\n\n/** Events emitted by TokenRefreshManager */\nexport interface TokenRefreshEvents {\n /** Emitted when token was successfully refreshed */\n refreshed: (token: AuthToken) => void;\n /** Emitted when refresh attempt failed (may retry) */\n error: (error: Error, attempt: number) => void;\n /** Emitted when token expired and could not be refreshed */\n expired: () => void;\n /** Emitted when manager is disposed */\n disposed: () => void;\n}\n\n/** Configuration for TokenRefreshManager */\nexport interface TokenRefreshOptions {\n /** Current token with expiresIn and obtainedAt */\n token: AuthToken;\n /**\n * Function that performs the actual token refresh.\n * Receives the current token and returns a new one.\n */\n refresh: (token: AuthToken) => Promise<AuthToken>;\n /**\n * Fraction of token lifetime at which to trigger refresh (0-1).\n * Default: 0.8 (refresh at 80% of lifetime, i.e. with 20% remaining)\n */\n refreshThreshold?: number;\n /**\n * Maximum retry attempts on refresh failure. Default: 3\n */\n maxRetries?: number;\n /**\n * Base delay between retries in ms. Exponential backoff applied. Default: 1000\n */\n retryDelayMs?: number;\n /**\n * Minimum schedule delay in ms (prevents scheduling in the past). Default: 1000\n */\n minDelayMs?: number;\n}\n\ntype EventName = keyof TokenRefreshEvents;\ntype ListenerMap = { [K in EventName]: Set<TokenRefreshEvents[K]> };\n\n// ─── Manager ───────────────────────────────────────────────────\n\n/**\n * Background token refresh manager with event emission and retry logic.\n *\n * Lifecycle: `new` → `start()` → (auto-refreshes) → `stop()` or `dispose()`\n */\nexport class TokenRefreshManager {\n private currentToken: AuthToken;\n private readonly refreshFn: (token: AuthToken) => Promise<AuthToken>;\n private readonly threshold: number;\n private readonly maxRetries: number;\n private readonly retryDelayMs: number;\n private readonly minDelayMs: number;\n\n private timerId: ReturnType<typeof setTimeout> | null = null;\n private running = false;\n private disposed = false;\n\n private readonly listeners: ListenerMap = {\n refreshed: new Set(),\n error: new Set(),\n expired: new Set(),\n disposed: new Set(),\n };\n\n constructor(options: TokenRefreshOptions) {\n this.currentToken = { ...options.token };\n this.refreshFn = options.refresh;\n this.threshold = options.refreshThreshold ?? 0.8;\n this.maxRetries = options.maxRetries ?? 3;\n this.retryDelayMs = options.retryDelayMs ?? 1000;\n this.minDelayMs = options.minDelayMs ?? 1000;\n }\n\n /** Register an event listener */\n on<K extends EventName>(event: K, listener: TokenRefreshEvents[K]): this {\n // TypeScript can't narrow Set type from generic key — safe because ListenerMap enforces per-event types\n this.listeners[event].add(listener as never);\n return this;\n }\n\n /** Remove an event listener */\n off<K extends EventName>(event: K, listener: TokenRefreshEvents[K]): this {\n // TypeScript can't narrow Set type from generic key — safe because ListenerMap enforces per-event types\n this.listeners[event].delete(listener as never);\n return this;\n }\n\n /** Current token managed by this instance */\n get token(): AuthToken {\n return { ...this.currentToken };\n }\n\n /** Whether the manager is currently running */\n get isRunning(): boolean {\n return this.running;\n }\n\n /** Whether the manager has been disposed */\n get isDisposed(): boolean {\n return this.disposed;\n }\n\n /**\n * Start automatic refresh scheduling.\n * If the token is already expired, emits \"expired\" immediately.\n * If the token has no expiresIn, does nothing (long-lived token).\n */\n start(): void {\n if (this.disposed) return;\n if (this.running) return;\n this.running = true;\n this.schedule();\n }\n\n /** Stop automatic refresh (can be restarted with start()) */\n stop(): void {\n this.running = false;\n this.clearTimer();\n }\n\n /**\n * Update the managed token (e.g. after manual refresh).\n * Reschedules automatic refresh if running.\n */\n updateToken(token: AuthToken): void {\n if (this.disposed) return;\n this.currentToken = { ...token };\n if (this.running) {\n this.clearTimer();\n this.schedule();\n }\n }\n\n /** Stop and clean up all resources */\n dispose(): void {\n if (this.disposed) return;\n this.stop();\n this.disposed = true;\n this.emit(\"disposed\");\n // Clear all listeners\n for (const set of Object.values(this.listeners)) {\n (set as Set<unknown>).clear();\n }\n }\n\n // ─── Private ──────────────────────────────────────────────────\n\n private schedule(): void {\n if (!this.running || this.disposed) return;\n\n const delayMs = this.computeRefreshDelay();\n\n if (delayMs === null) {\n // No expiresIn → long-lived token, nothing to schedule\n return;\n }\n\n if (delayMs <= 0) {\n // Past refresh point (or expired) — attempt refresh via timer to keep async chain clean\n this.timerId = setTimeout(() => {\n this.timerId = null;\n if (!this.running || this.disposed) return;\n void this.performRefresh();\n }, 0);\n return;\n }\n\n this.timerId = setTimeout(() => {\n this.timerId = null;\n if (!this.running || this.disposed) return;\n void this.performRefresh();\n }, Math.max(delayMs, this.minDelayMs));\n }\n\n private async performRefresh(attempt = 1): Promise<void> {\n if (!this.running || this.disposed) return;\n\n try {\n const newToken = await this.refreshFn(this.currentToken);\n if (!this.running || this.disposed) return;\n this.currentToken = { ...newToken };\n this.emit(\"refreshed\", newToken);\n this.schedule();\n } catch (err) {\n if (!this.running || this.disposed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit(\"error\", error, attempt);\n\n if (attempt < this.maxRetries) {\n const delay = this.retryDelayMs * Math.pow(2, attempt - 1);\n this.timerId = setTimeout(() => {\n this.timerId = null;\n if (!this.running || this.disposed) return;\n void this.performRefresh(attempt + 1);\n }, delay);\n } else {\n // All retries exhausted\n if (this.isTokenExpired()) {\n this.running = false;\n this.emit(\"expired\");\n } else {\n // Token not yet expired — wait until expiry time and start fresh retry cycle\n const expiresIn = this.currentToken.expiresIn;\n if (expiresIn == null) return; // invariant: unreachable from schedule() which checks expiresIn\n const expiresAt = this.currentToken.obtainedAt + expiresIn * 1000;\n const waitMs = Math.max(expiresAt - Date.now(), this.minDelayMs);\n this.timerId = setTimeout(() => {\n this.timerId = null;\n if (!this.running || this.disposed) return;\n void this.performRefresh();\n }, waitMs);\n }\n }\n }\n }\n\n private computeRefreshDelay(): number | null {\n if (this.currentToken.expiresIn == null) return null;\n\n const lifetimeMs = this.currentToken.expiresIn * 1000;\n const refreshAtMs = this.currentToken.obtainedAt + lifetimeMs * this.threshold;\n const now = Date.now();\n const delay = refreshAtMs - now;\n\n // Return raw delay — caller decides whether to clamp or treat as immediate\n return delay;\n }\n\n private isTokenExpired(): boolean {\n if (this.currentToken.expiresIn == null) return false;\n const expiresAt = this.currentToken.obtainedAt + this.currentToken.expiresIn * 1000;\n return Date.now() >= expiresAt;\n }\n\n private clearTimer(): void {\n if (this.timerId !== null) {\n clearTimeout(this.timerId);\n this.timerId = null;\n }\n }\n\n private emit<K extends EventName>(event: K, ...args: Parameters<TokenRefreshEvents[K]>): void {\n for (const listener of this.listeners[event]) {\n try {\n (listener as (...a: unknown[]) => void)(...args);\n } catch {\n // Listener errors should not crash the manager\n }\n }\n }\n}\n"]}