@langchain/langgraph-sdk 1.7.0 → 1.7.2

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 (165) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +7 -13
  2. package/dist/auth/error.cjs +1 -2
  3. package/dist/auth/error.cjs.map +1 -1
  4. package/dist/auth/error.js +1 -1
  5. package/dist/auth/index.cjs +3 -4
  6. package/dist/auth/index.cjs.map +1 -1
  7. package/dist/auth/index.js +1 -2
  8. package/dist/auth/index.js.map +1 -1
  9. package/dist/client.cjs +7 -8
  10. package/dist/client.cjs.map +1 -1
  11. package/dist/client.js +1 -2
  12. package/dist/client.js.map +1 -1
  13. package/dist/index.cjs +5 -6
  14. package/dist/index.js +1 -2
  15. package/dist/logging/index.cjs +2 -3
  16. package/dist/logging/index.cjs.map +1 -1
  17. package/dist/logging/index.js +1 -1
  18. package/dist/react/index.cjs +11 -48
  19. package/dist/react/index.d.cts +11 -14
  20. package/dist/react/index.d.ts +11 -14
  21. package/dist/react/index.js +3 -14
  22. package/dist/react/stream.cjs +17 -0
  23. package/dist/react/stream.cjs.map +1 -0
  24. package/dist/react/stream.custom.cjs +162 -0
  25. package/dist/react/stream.custom.cjs.map +1 -0
  26. package/dist/react/stream.custom.d.cts +40 -0
  27. package/dist/react/stream.custom.d.cts.map +1 -0
  28. package/dist/react/stream.custom.d.ts +39 -0
  29. package/dist/react/stream.custom.d.ts.map +1 -0
  30. package/dist/react/stream.custom.js +160 -0
  31. package/dist/react/stream.custom.js.map +1 -0
  32. package/dist/react/stream.d.cts +10 -0
  33. package/dist/react/stream.d.cts.map +1 -0
  34. package/dist/react/stream.d.ts +9 -0
  35. package/dist/react/stream.d.ts.map +1 -0
  36. package/dist/react/stream.js +16 -0
  37. package/dist/react/stream.js.map +1 -0
  38. package/dist/react/stream.lgp.cjs +550 -0
  39. package/dist/react/stream.lgp.cjs.map +1 -0
  40. package/dist/react/stream.lgp.js +549 -0
  41. package/dist/react/stream.lgp.js.map +1 -0
  42. package/dist/react/thread.cjs +19 -0
  43. package/dist/react/thread.cjs.map +1 -0
  44. package/dist/react/thread.js +18 -0
  45. package/dist/react/thread.js.map +1 -0
  46. package/dist/react/types.d.cts +79 -0
  47. package/dist/react/types.d.cts.map +1 -0
  48. package/dist/react/types.d.ts +79 -0
  49. package/dist/react/types.d.ts.map +1 -0
  50. package/dist/react-ui/client.cjs +136 -0
  51. package/dist/react-ui/client.cjs.map +1 -0
  52. package/dist/react-ui/client.d.cts +67 -0
  53. package/dist/react-ui/client.d.cts.map +1 -0
  54. package/dist/react-ui/client.d.ts +67 -0
  55. package/dist/react-ui/client.d.ts.map +1 -0
  56. package/dist/react-ui/client.js +130 -0
  57. package/dist/react-ui/client.js.map +1 -0
  58. package/dist/react-ui/index.cjs +13 -39
  59. package/dist/react-ui/index.cjs.map +1 -0
  60. package/dist/react-ui/index.d.cts +2 -1
  61. package/dist/react-ui/index.d.ts +2 -1
  62. package/dist/react-ui/index.js +7 -2
  63. package/dist/react-ui/index.js.map +1 -0
  64. package/dist/react-ui/server/index.cjs +5 -16
  65. package/dist/react-ui/server/index.d.cts +2 -1
  66. package/dist/react-ui/server/index.d.ts +2 -1
  67. package/dist/react-ui/server/index.js +3 -3
  68. package/dist/react-ui/server/server.cjs +56 -0
  69. package/dist/react-ui/server/server.cjs.map +1 -0
  70. package/dist/react-ui/server/server.d.cts +54 -0
  71. package/dist/react-ui/server/server.d.cts.map +1 -0
  72. package/dist/react-ui/server/server.d.ts +54 -0
  73. package/dist/react-ui/server/server.d.ts.map +1 -0
  74. package/dist/react-ui/server/server.js +55 -0
  75. package/dist/react-ui/server/server.js.map +1 -0
  76. package/dist/react-ui/types.cjs +37 -0
  77. package/dist/react-ui/types.cjs.map +1 -0
  78. package/dist/react-ui/types.d.cts +25 -0
  79. package/dist/react-ui/types.d.cts.map +1 -0
  80. package/dist/react-ui/types.d.ts +25 -0
  81. package/dist/react-ui/types.d.ts.map +1 -0
  82. package/dist/react-ui/types.js +35 -0
  83. package/dist/react-ui/types.js.map +1 -0
  84. package/dist/singletons/fetch.cjs +1 -2
  85. package/dist/singletons/fetch.cjs.map +1 -1
  86. package/dist/singletons/fetch.js +1 -1
  87. package/dist/singletons/fetch.js.map +1 -1
  88. package/dist/ui/branching.cjs +2 -3
  89. package/dist/ui/branching.cjs.map +1 -1
  90. package/dist/ui/branching.js +1 -2
  91. package/dist/ui/branching.js.map +1 -1
  92. package/dist/ui/errors.cjs +1 -2
  93. package/dist/ui/errors.cjs.map +1 -1
  94. package/dist/ui/errors.js +1 -1
  95. package/dist/ui/index.cjs +12 -12
  96. package/dist/ui/index.d.cts +3 -3
  97. package/dist/ui/index.d.ts +3 -3
  98. package/dist/ui/index.js +2 -3
  99. package/dist/ui/interrupts.cjs +1 -2
  100. package/dist/ui/interrupts.cjs.map +1 -1
  101. package/dist/ui/interrupts.js +1 -1
  102. package/dist/ui/interrupts.js.map +1 -1
  103. package/dist/ui/manager.cjs +5 -12
  104. package/dist/ui/manager.cjs.map +1 -1
  105. package/dist/ui/manager.js +2 -9
  106. package/dist/ui/manager.js.map +1 -1
  107. package/dist/ui/messages.cjs +21 -3
  108. package/dist/ui/messages.cjs.map +1 -1
  109. package/dist/ui/messages.d.cts +21 -1
  110. package/dist/ui/messages.d.cts.map +1 -1
  111. package/dist/ui/messages.d.ts +21 -1
  112. package/dist/ui/messages.d.ts.map +1 -1
  113. package/dist/ui/messages.js +20 -3
  114. package/dist/ui/messages.js.map +1 -1
  115. package/dist/ui/queue.cjs +1 -2
  116. package/dist/ui/queue.cjs.map +1 -1
  117. package/dist/ui/queue.js +1 -1
  118. package/dist/ui/queue.js.map +1 -1
  119. package/dist/ui/subagents.cjs +3 -4
  120. package/dist/ui/subagents.cjs.map +1 -1
  121. package/dist/ui/subagents.js +1 -2
  122. package/dist/ui/subagents.js.map +1 -1
  123. package/dist/ui/transport.cjs +3 -4
  124. package/dist/ui/transport.cjs.map +1 -1
  125. package/dist/ui/transport.js +1 -2
  126. package/dist/ui/transport.js.map +1 -1
  127. package/dist/ui/types.d.cts +1 -1
  128. package/dist/ui/types.d.ts +1 -1
  129. package/dist/ui/utils.cjs +1 -2
  130. package/dist/ui/utils.cjs.map +1 -1
  131. package/dist/ui/utils.js +1 -1
  132. package/dist/utils/async_caller.cjs +3 -4
  133. package/dist/utils/async_caller.cjs.map +1 -1
  134. package/dist/utils/async_caller.js +1 -2
  135. package/dist/utils/async_caller.js.map +1 -1
  136. package/dist/utils/env.cjs +1 -2
  137. package/dist/utils/env.cjs.map +1 -1
  138. package/dist/utils/env.js +1 -1
  139. package/dist/utils/env.js.map +1 -1
  140. package/dist/utils/error.cjs +1 -2
  141. package/dist/utils/error.cjs.map +1 -1
  142. package/dist/utils/error.js +1 -1
  143. package/dist/utils/index.cjs +5 -6
  144. package/dist/utils/index.js +1 -2
  145. package/dist/utils/signals.cjs +1 -2
  146. package/dist/utils/signals.cjs.map +1 -1
  147. package/dist/utils/signals.js +1 -1
  148. package/dist/utils/signals.js.map +1 -1
  149. package/dist/utils/sse.cjs +1 -2
  150. package/dist/utils/sse.cjs.map +1 -1
  151. package/dist/utils/sse.js +1 -1
  152. package/dist/utils/sse.js.map +1 -1
  153. package/dist/utils/stream.cjs +2 -3
  154. package/dist/utils/stream.cjs.map +1 -1
  155. package/dist/utils/stream.js +1 -2
  156. package/dist/utils/stream.js.map +1 -1
  157. package/dist/utils/tools.cjs +1 -2
  158. package/dist/utils/tools.cjs.map +1 -1
  159. package/dist/utils/tools.js +1 -1
  160. package/dist/utils/tools.js.map +1 -1
  161. package/package.json +11 -3
  162. package/dist/react/index.cjs.map +0 -1
  163. package/dist/react/index.d.cts.map +0 -1
  164. package/dist/react/index.d.ts.map +0 -1
  165. package/dist/react/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"async_caller.cjs","names":["PQueueMod","_getFetchImplementation"],"sources":["../../src/utils/async_caller.ts"],"sourcesContent":["import pRetry from \"p-retry\";\nimport PQueueMod from \"p-queue\";\nimport { _getFetchImplementation } from \"../singletons/fetch.js\";\n\nconst STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 408, // Request Timeout\n 409, // Conflict\n 422, // Unprocessable Entity\n];\n\ntype ResponseCallback = (response?: Response) => Promise<boolean>;\n\nexport interface AsyncCallerParams {\n /**\n * The maximum number of concurrent calls that can be made.\n * Defaults to `Infinity`, which means no limit.\n */\n maxConcurrency?: number;\n /**\n * The maximum number of retries that can be made for a single call,\n * with an exponential backoff between each attempt. Defaults to 6.\n */\n maxRetries?: number;\n\n onFailedResponseHook?: ResponseCallback;\n\n /**\n * Specify a custom fetch implementation.\n *\n * By default we expect the `fetch` is available in the global scope.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\nexport interface AsyncCallerCallOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Do not rely on globalThis.Response, rather just\n * do duck typing\n */\nfunction isResponse(x: unknown): x is Response {\n if (x == null || typeof x !== \"object\") return false;\n return \"status\" in x && \"statusText\" in x && \"text\" in x;\n}\n\n/**\n * Utility error to properly handle failed requests\n */\nclass HTTPError extends Error {\n status: number;\n\n text: string;\n\n response?: Response;\n\n constructor(status: number, message: string, response?: Response) {\n super(`HTTP ${status}: ${message}`);\n this.status = status;\n this.text = message;\n this.response = response;\n }\n\n static async fromResponse(\n response: Response,\n options?: { includeResponse?: boolean }\n ): Promise<HTTPError> {\n try {\n return new HTTPError(\n response.status,\n await response.text(),\n options?.includeResponse ? response : undefined\n );\n } catch {\n return new HTTPError(\n response.status,\n response.statusText,\n options?.includeResponse ? response : undefined\n );\n }\n }\n}\n\n/**\n * A class that can be used to make async calls with concurrency and retry logic.\n *\n * This is useful for making calls to any kind of \"expensive\" external resource,\n * be it because it's rate-limited, subject to network issues, etc.\n *\n * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults\n * to `Infinity`. This means that by default, all calls will be made in parallel.\n *\n * Retries are limited by the `maxRetries` parameter, which defaults to 5. This\n * means that by default, each call will be retried up to 5 times, with an\n * exponential backoff between each attempt.\n */\nexport class AsyncCaller {\n protected maxConcurrency: AsyncCallerParams[\"maxConcurrency\"];\n\n protected maxRetries: AsyncCallerParams[\"maxRetries\"];\n\n private queue: typeof import(\"p-queue\")[\"default\"][\"prototype\"];\n\n private onFailedResponseHook?: ResponseCallback;\n\n private customFetch?: typeof fetch;\n\n constructor(params: AsyncCallerParams) {\n this.maxConcurrency = params.maxConcurrency ?? Infinity;\n this.maxRetries = params.maxRetries ?? 4;\n\n if (\"default\" in PQueueMod) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.queue = new (PQueueMod.default as any)({\n concurrency: this.maxConcurrency,\n });\n } else {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.queue = new (PQueueMod as any)({ concurrency: this.maxConcurrency });\n }\n this.onFailedResponseHook = params?.onFailedResponseHook;\n this.customFetch = params.fetch;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n call<A extends any[], T extends (...args: A) => Promise<any>>(\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n const { onFailedResponseHook } = this;\n return this.queue.add(\n () =>\n pRetry(\n () =>\n callable(...(args as Parameters<T>)).catch(async (error) => {\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof Error) {\n throw error;\n } else if (isResponse(error)) {\n throw await HTTPError.fromResponse(error, {\n includeResponse: !!onFailedResponseHook,\n });\n } else {\n throw new Error(error);\n }\n }),\n {\n async onFailedAttempt({ error }) {\n const errorMessage = error.message ?? \"\";\n if (\n errorMessage.startsWith(\"Cancel\") ||\n errorMessage.startsWith(\"TimeoutError\") ||\n errorMessage.startsWith(\"AbortError\")\n ) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n throw error;\n }\n\n // Check for connection refused errors (server not running)\n if (\n errorMessage.includes(\"ECONNREFUSED\") ||\n errorMessage.includes(\"fetch failed\") ||\n errorMessage.includes(\"Failed to fetch\") ||\n errorMessage.includes(\"NetworkError\")\n ) {\n const connectionError = new Error(\n `Unable to connect to LangGraph server. Please ensure the server is running and accessible. Original error: ${errorMessage}`\n );\n connectionError.name = \"ConnectionError\";\n throw connectionError;\n }\n\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof HTTPError) {\n if (STATUS_NO_RETRY.includes(error.status)) {\n throw error;\n }\n if (onFailedResponseHook && error.response) {\n await onFailedResponseHook(error.response);\n }\n }\n },\n // If needed we can change some of the defaults here,\n // but they're quite sensible.\n retries: this.maxRetries,\n randomize: true,\n }\n ),\n { throwOnTimeout: true }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(\n options: AsyncCallerCallOptions,\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n // Note this doesn't cancel the underlying request,\n // when available prefer to use the signal option of the underlying call\n if (options.signal) {\n return Promise.race([\n this.call<A, T>(callable, ...args),\n new Promise<never>((_, reject) => {\n options.signal?.addEventListener(\"abort\", () => {\n reject(new Error(\"AbortError\"));\n });\n }),\n ]);\n }\n return this.call<A, T>(callable, ...args);\n }\n\n fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {\n const fetchFn =\n this.customFetch ?? (_getFetchImplementation() as typeof fetch);\n return this.call(() =>\n fetchFn(...args).then((res) => (res.ok ? res : Promise.reject(res)))\n );\n }\n}\n"],"mappings":";;;;;;;;AAIA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;AAkCD,SAAS,WAAW,GAA2B;AAC7C,KAAI,KAAK,QAAQ,OAAO,MAAM,SAAU,QAAO;AAC/C,QAAO,YAAY,KAAK,gBAAgB,KAAK,UAAU;;;;;AAMzD,IAAM,YAAN,MAAM,kBAAkB,MAAM;CAC5B;CAEA;CAEA;CAEA,YAAY,QAAgB,SAAiB,UAAqB;AAChE,QAAM,QAAQ,OAAO,IAAI,UAAU;AACnC,OAAK,SAAS;AACd,OAAK,OAAO;AACZ,OAAK,WAAW;;CAGlB,aAAa,aACX,UACA,SACoB;AACpB,MAAI;AACF,UAAO,IAAI,UACT,SAAS,QACT,MAAM,SAAS,MAAM,EACrB,SAAS,kBAAkB,WAAW,OACvC;UACK;AACN,UAAO,IAAI,UACT,SAAS,QACT,SAAS,YACT,SAAS,kBAAkB,WAAW,OACvC;;;;;;;;;;;;;;;;;AAkBP,IAAa,cAAb,MAAyB;CACvB,AAAU;CAEV,AAAU;CAEV,AAAQ;CAER,AAAQ;CAER,AAAQ;CAER,YAAY,QAA2B;AACrC,OAAK,iBAAiB,OAAO,kBAAkB;AAC/C,OAAK,aAAa,OAAO,cAAc;AAEvC,MAAI,aAAaA,gBAEf,MAAK,QAAQ,IAAKA,gBAAU,QAAgB,EAC1C,aAAa,KAAK,gBACnB,CAAC;MAGF,MAAK,QAAQ,IAAKA,gBAAkB,EAAE,aAAa,KAAK,gBAAgB,CAAC;AAE3E,OAAK,uBAAuB,QAAQ;AACpC,OAAK,cAAc,OAAO;;CAI5B,KACE,UACA,GAAG,MAC8B;EACjC,MAAM,EAAE,yBAAyB;AACjC,SAAO,KAAK,MAAM,qCAIV,SAAS,GAAI,KAAuB,CAAC,MAAM,OAAO,UAAU;AAE1D,OAAI,iBAAiB,MACnB,OAAM;YACG,WAAW,MAAM,CAC1B,OAAM,MAAM,UAAU,aAAa,OAAO,EACxC,iBAAiB,CAAC,CAAC,sBACpB,CAAC;OAEF,OAAM,IAAI,MAAM,MAAM;IAExB,EACJ;GACE,MAAM,gBAAgB,EAAE,SAAS;IAC/B,MAAM,eAAe,MAAM,WAAW;AACtC,QACE,aAAa,WAAW,SAAS,IACjC,aAAa,WAAW,eAAe,IACvC,aAAa,WAAW,aAAa,CAErC,OAAM;AAGR,QAAK,OAAe,SAAS,eAC3B,OAAM;AAIR,QACE,aAAa,SAAS,eAAe,IACrC,aAAa,SAAS,eAAe,IACrC,aAAa,SAAS,kBAAkB,IACxC,aAAa,SAAS,eAAe,EACrC;KACA,MAAM,kCAAkB,IAAI,MAC1B,8GAA8G,eAC/G;AACD,qBAAgB,OAAO;AACvB,WAAM;;AAIR,QAAI,iBAAiB,WAAW;AAC9B,SAAI,gBAAgB,SAAS,MAAM,OAAO,CACxC,OAAM;AAER,SAAI,wBAAwB,MAAM,SAChC,OAAM,qBAAqB,MAAM,SAAS;;;GAMhD,SAAS,KAAK;GACd,WAAW;GACZ,CACF,EACH,EAAE,gBAAgB,MAAM,CACzB;;CAIH,gBACE,SACA,UACA,GAAG,MAC8B;AAGjC,MAAI,QAAQ,OACV,QAAO,QAAQ,KAAK,CAClB,KAAK,KAAW,UAAU,GAAG,KAAK,EAClC,IAAI,SAAgB,GAAG,WAAW;AAChC,WAAQ,QAAQ,iBAAiB,eAAe;AAC9C,2BAAO,IAAI,MAAM,aAAa,CAAC;KAC/B;IACF,CACH,CAAC;AAEJ,SAAO,KAAK,KAAW,UAAU,GAAG,KAAK;;CAG3C,MAAM,GAAG,MAA0D;EACjE,MAAM,UACJ,KAAK,eAAgBC,uCAAyB;AAChD,SAAO,KAAK,WACV,QAAQ,GAAG,KAAK,CAAC,MAAM,QAAS,IAAI,KAAK,MAAM,QAAQ,OAAO,IAAI,CAAE,CACrE"}
1
+ {"version":3,"file":"async_caller.cjs","names":["PQueueMod","_getFetchImplementation"],"sources":["../../src/utils/async_caller.ts"],"sourcesContent":["import pRetry from \"p-retry\";\nimport PQueueMod from \"p-queue\";\nimport { _getFetchImplementation } from \"../singletons/fetch.js\";\n\nconst STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 408, // Request Timeout\n 409, // Conflict\n 422, // Unprocessable Entity\n];\n\ntype ResponseCallback = (response?: Response) => Promise<boolean>;\n\nexport interface AsyncCallerParams {\n /**\n * The maximum number of concurrent calls that can be made.\n * Defaults to `Infinity`, which means no limit.\n */\n maxConcurrency?: number;\n /**\n * The maximum number of retries that can be made for a single call,\n * with an exponential backoff between each attempt. Defaults to 6.\n */\n maxRetries?: number;\n\n onFailedResponseHook?: ResponseCallback;\n\n /**\n * Specify a custom fetch implementation.\n *\n * By default we expect the `fetch` is available in the global scope.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\nexport interface AsyncCallerCallOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Do not rely on globalThis.Response, rather just\n * do duck typing\n */\nfunction isResponse(x: unknown): x is Response {\n if (x == null || typeof x !== \"object\") return false;\n return \"status\" in x && \"statusText\" in x && \"text\" in x;\n}\n\n/**\n * Utility error to properly handle failed requests\n */\nclass HTTPError extends Error {\n status: number;\n\n text: string;\n\n response?: Response;\n\n constructor(status: number, message: string, response?: Response) {\n super(`HTTP ${status}: ${message}`);\n this.status = status;\n this.text = message;\n this.response = response;\n }\n\n static async fromResponse(\n response: Response,\n options?: { includeResponse?: boolean }\n ): Promise<HTTPError> {\n try {\n return new HTTPError(\n response.status,\n await response.text(),\n options?.includeResponse ? response : undefined\n );\n } catch {\n return new HTTPError(\n response.status,\n response.statusText,\n options?.includeResponse ? response : undefined\n );\n }\n }\n}\n\n/**\n * A class that can be used to make async calls with concurrency and retry logic.\n *\n * This is useful for making calls to any kind of \"expensive\" external resource,\n * be it because it's rate-limited, subject to network issues, etc.\n *\n * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults\n * to `Infinity`. This means that by default, all calls will be made in parallel.\n *\n * Retries are limited by the `maxRetries` parameter, which defaults to 5. This\n * means that by default, each call will be retried up to 5 times, with an\n * exponential backoff between each attempt.\n */\nexport class AsyncCaller {\n protected maxConcurrency: AsyncCallerParams[\"maxConcurrency\"];\n\n protected maxRetries: AsyncCallerParams[\"maxRetries\"];\n\n private queue: typeof import(\"p-queue\")[\"default\"][\"prototype\"];\n\n private onFailedResponseHook?: ResponseCallback;\n\n private customFetch?: typeof fetch;\n\n constructor(params: AsyncCallerParams) {\n this.maxConcurrency = params.maxConcurrency ?? Infinity;\n this.maxRetries = params.maxRetries ?? 4;\n\n if (\"default\" in PQueueMod) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.queue = new (PQueueMod.default as any)({\n concurrency: this.maxConcurrency,\n });\n } else {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.queue = new (PQueueMod as any)({ concurrency: this.maxConcurrency });\n }\n this.onFailedResponseHook = params?.onFailedResponseHook;\n this.customFetch = params.fetch;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n call<A extends any[], T extends (...args: A) => Promise<any>>(\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n const { onFailedResponseHook } = this;\n return this.queue.add(\n () =>\n pRetry(\n () =>\n callable(...(args as Parameters<T>)).catch(async (error) => {\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof Error) {\n throw error;\n } else if (isResponse(error)) {\n throw await HTTPError.fromResponse(error, {\n includeResponse: !!onFailedResponseHook,\n });\n } else {\n throw new Error(error);\n }\n }),\n {\n async onFailedAttempt({ error }) {\n const errorMessage = error.message ?? \"\";\n if (\n errorMessage.startsWith(\"Cancel\") ||\n errorMessage.startsWith(\"TimeoutError\") ||\n errorMessage.startsWith(\"AbortError\")\n ) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n throw error;\n }\n\n // Check for connection refused errors (server not running)\n if (\n errorMessage.includes(\"ECONNREFUSED\") ||\n errorMessage.includes(\"fetch failed\") ||\n errorMessage.includes(\"Failed to fetch\") ||\n errorMessage.includes(\"NetworkError\")\n ) {\n const connectionError = new Error(\n `Unable to connect to LangGraph server. Please ensure the server is running and accessible. Original error: ${errorMessage}`\n );\n connectionError.name = \"ConnectionError\";\n throw connectionError;\n }\n\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof HTTPError) {\n if (STATUS_NO_RETRY.includes(error.status)) {\n throw error;\n }\n if (onFailedResponseHook && error.response) {\n await onFailedResponseHook(error.response);\n }\n }\n },\n // If needed we can change some of the defaults here,\n // but they're quite sensible.\n retries: this.maxRetries,\n randomize: true,\n }\n ),\n { throwOnTimeout: true }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(\n options: AsyncCallerCallOptions,\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n // Note this doesn't cancel the underlying request,\n // when available prefer to use the signal option of the underlying call\n if (options.signal) {\n return Promise.race([\n this.call<A, T>(callable, ...args),\n new Promise<never>((_, reject) => {\n options.signal?.addEventListener(\"abort\", () => {\n reject(new Error(\"AbortError\"));\n });\n }),\n ]);\n }\n return this.call<A, T>(callable, ...args);\n }\n\n fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {\n const fetchFn =\n this.customFetch ?? (_getFetchImplementation() as typeof fetch);\n return this.call(() =>\n fetchFn(...args).then((res) => (res.ok ? res : Promise.reject(res)))\n );\n }\n}\n"],"mappings":";;;;;;;AAIA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;AAkCD,SAAS,WAAW,GAA2B;AAC7C,KAAI,KAAK,QAAQ,OAAO,MAAM,SAAU,QAAO;AAC/C,QAAO,YAAY,KAAK,gBAAgB,KAAK,UAAU;;;;;AAMzD,IAAM,YAAN,MAAM,kBAAkB,MAAM;CAC5B;CAEA;CAEA;CAEA,YAAY,QAAgB,SAAiB,UAAqB;AAChE,QAAM,QAAQ,OAAO,IAAI,UAAU;AACnC,OAAK,SAAS;AACd,OAAK,OAAO;AACZ,OAAK,WAAW;;CAGlB,aAAa,aACX,UACA,SACoB;AACpB,MAAI;AACF,UAAO,IAAI,UACT,SAAS,QACT,MAAM,SAAS,MAAM,EACrB,SAAS,kBAAkB,WAAW,KAAA,EACvC;UACK;AACN,UAAO,IAAI,UACT,SAAS,QACT,SAAS,YACT,SAAS,kBAAkB,WAAW,KAAA,EACvC;;;;;;;;;;;;;;;;;AAkBP,IAAa,cAAb,MAAyB;CACvB;CAEA;CAEA;CAEA;CAEA;CAEA,YAAY,QAA2B;AACrC,OAAK,iBAAiB,OAAO,kBAAkB;AAC/C,OAAK,aAAa,OAAO,cAAc;AAEvC,MAAI,aAAaA,QAAAA,QAEf,MAAK,QAAQ,IAAKA,QAAAA,QAAU,QAAgB,EAC1C,aAAa,KAAK,gBACnB,CAAC;MAGF,MAAK,QAAQ,IAAKA,QAAAA,QAAkB,EAAE,aAAa,KAAK,gBAAgB,CAAC;AAE3E,OAAK,uBAAuB,QAAQ;AACpC,OAAK,cAAc,OAAO;;CAI5B,KACE,UACA,GAAG,MAC8B;EACjC,MAAM,EAAE,yBAAyB;AACjC,SAAO,KAAK,MAAM,WAAA,GAAA,QAAA,eAIV,SAAS,GAAI,KAAuB,CAAC,MAAM,OAAO,UAAU;AAE1D,OAAI,iBAAiB,MACnB,OAAM;YACG,WAAW,MAAM,CAC1B,OAAM,MAAM,UAAU,aAAa,OAAO,EACxC,iBAAiB,CAAC,CAAC,sBACpB,CAAC;OAEF,OAAM,IAAI,MAAM,MAAM;IAExB,EACJ;GACE,MAAM,gBAAgB,EAAE,SAAS;IAC/B,MAAM,eAAe,MAAM,WAAW;AACtC,QACE,aAAa,WAAW,SAAS,IACjC,aAAa,WAAW,eAAe,IACvC,aAAa,WAAW,aAAa,CAErC,OAAM;AAGR,QAAK,OAAe,SAAS,eAC3B,OAAM;AAIR,QACE,aAAa,SAAS,eAAe,IACrC,aAAa,SAAS,eAAe,IACrC,aAAa,SAAS,kBAAkB,IACxC,aAAa,SAAS,eAAe,EACrC;KACA,MAAM,kCAAkB,IAAI,MAC1B,8GAA8G,eAC/G;AACD,qBAAgB,OAAO;AACvB,WAAM;;AAIR,QAAI,iBAAiB,WAAW;AAC9B,SAAI,gBAAgB,SAAS,MAAM,OAAO,CACxC,OAAM;AAER,SAAI,wBAAwB,MAAM,SAChC,OAAM,qBAAqB,MAAM,SAAS;;;GAMhD,SAAS,KAAK;GACd,WAAW;GACZ,CACF,EACH,EAAE,gBAAgB,MAAM,CACzB;;CAIH,gBACE,SACA,UACA,GAAG,MAC8B;AAGjC,MAAI,QAAQ,OACV,QAAO,QAAQ,KAAK,CAClB,KAAK,KAAW,UAAU,GAAG,KAAK,EAClC,IAAI,SAAgB,GAAG,WAAW;AAChC,WAAQ,QAAQ,iBAAiB,eAAe;AAC9C,2BAAO,IAAI,MAAM,aAAa,CAAC;KAC/B;IACF,CACH,CAAC;AAEJ,SAAO,KAAK,KAAW,UAAU,GAAG,KAAK;;CAG3C,MAAM,GAAG,MAA0D;EACjE,MAAM,UACJ,KAAK,eAAgBC,cAAAA,yBAAyB;AAChD,SAAO,KAAK,WACV,QAAQ,GAAG,KAAK,CAAC,MAAM,QAAS,IAAI,KAAK,MAAM,QAAQ,OAAO,IAAI,CAAE,CACrE"}
@@ -1,7 +1,6 @@
1
1
  import { _getFetchImplementation } from "../singletons/fetch.js";
2
2
  import pRetry from "p-retry";
3
3
  import PQueueMod from "p-queue";
4
-
5
4
  //#region src/utils/async_caller.ts
6
5
  const STATUS_NO_RETRY = [
7
6
  400,
@@ -110,7 +109,7 @@ var AsyncCaller = class {
110
109
  return this.call(() => fetchFn(...args).then((res) => res.ok ? res : Promise.reject(res)));
111
110
  }
112
111
  };
113
-
114
112
  //#endregion
115
113
  export { AsyncCaller };
114
+
116
115
  //# sourceMappingURL=async_caller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"async_caller.js","names":[],"sources":["../../src/utils/async_caller.ts"],"sourcesContent":["import pRetry from \"p-retry\";\nimport PQueueMod from \"p-queue\";\nimport { _getFetchImplementation } from \"../singletons/fetch.js\";\n\nconst STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 408, // Request Timeout\n 409, // Conflict\n 422, // Unprocessable Entity\n];\n\ntype ResponseCallback = (response?: Response) => Promise<boolean>;\n\nexport interface AsyncCallerParams {\n /**\n * The maximum number of concurrent calls that can be made.\n * Defaults to `Infinity`, which means no limit.\n */\n maxConcurrency?: number;\n /**\n * The maximum number of retries that can be made for a single call,\n * with an exponential backoff between each attempt. Defaults to 6.\n */\n maxRetries?: number;\n\n onFailedResponseHook?: ResponseCallback;\n\n /**\n * Specify a custom fetch implementation.\n *\n * By default we expect the `fetch` is available in the global scope.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\nexport interface AsyncCallerCallOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Do not rely on globalThis.Response, rather just\n * do duck typing\n */\nfunction isResponse(x: unknown): x is Response {\n if (x == null || typeof x !== \"object\") return false;\n return \"status\" in x && \"statusText\" in x && \"text\" in x;\n}\n\n/**\n * Utility error to properly handle failed requests\n */\nclass HTTPError extends Error {\n status: number;\n\n text: string;\n\n response?: Response;\n\n constructor(status: number, message: string, response?: Response) {\n super(`HTTP ${status}: ${message}`);\n this.status = status;\n this.text = message;\n this.response = response;\n }\n\n static async fromResponse(\n response: Response,\n options?: { includeResponse?: boolean }\n ): Promise<HTTPError> {\n try {\n return new HTTPError(\n response.status,\n await response.text(),\n options?.includeResponse ? response : undefined\n );\n } catch {\n return new HTTPError(\n response.status,\n response.statusText,\n options?.includeResponse ? response : undefined\n );\n }\n }\n}\n\n/**\n * A class that can be used to make async calls with concurrency and retry logic.\n *\n * This is useful for making calls to any kind of \"expensive\" external resource,\n * be it because it's rate-limited, subject to network issues, etc.\n *\n * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults\n * to `Infinity`. This means that by default, all calls will be made in parallel.\n *\n * Retries are limited by the `maxRetries` parameter, which defaults to 5. This\n * means that by default, each call will be retried up to 5 times, with an\n * exponential backoff between each attempt.\n */\nexport class AsyncCaller {\n protected maxConcurrency: AsyncCallerParams[\"maxConcurrency\"];\n\n protected maxRetries: AsyncCallerParams[\"maxRetries\"];\n\n private queue: typeof import(\"p-queue\")[\"default\"][\"prototype\"];\n\n private onFailedResponseHook?: ResponseCallback;\n\n private customFetch?: typeof fetch;\n\n constructor(params: AsyncCallerParams) {\n this.maxConcurrency = params.maxConcurrency ?? Infinity;\n this.maxRetries = params.maxRetries ?? 4;\n\n if (\"default\" in PQueueMod) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.queue = new (PQueueMod.default as any)({\n concurrency: this.maxConcurrency,\n });\n } else {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.queue = new (PQueueMod as any)({ concurrency: this.maxConcurrency });\n }\n this.onFailedResponseHook = params?.onFailedResponseHook;\n this.customFetch = params.fetch;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n call<A extends any[], T extends (...args: A) => Promise<any>>(\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n const { onFailedResponseHook } = this;\n return this.queue.add(\n () =>\n pRetry(\n () =>\n callable(...(args as Parameters<T>)).catch(async (error) => {\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof Error) {\n throw error;\n } else if (isResponse(error)) {\n throw await HTTPError.fromResponse(error, {\n includeResponse: !!onFailedResponseHook,\n });\n } else {\n throw new Error(error);\n }\n }),\n {\n async onFailedAttempt({ error }) {\n const errorMessage = error.message ?? \"\";\n if (\n errorMessage.startsWith(\"Cancel\") ||\n errorMessage.startsWith(\"TimeoutError\") ||\n errorMessage.startsWith(\"AbortError\")\n ) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n throw error;\n }\n\n // Check for connection refused errors (server not running)\n if (\n errorMessage.includes(\"ECONNREFUSED\") ||\n errorMessage.includes(\"fetch failed\") ||\n errorMessage.includes(\"Failed to fetch\") ||\n errorMessage.includes(\"NetworkError\")\n ) {\n const connectionError = new Error(\n `Unable to connect to LangGraph server. Please ensure the server is running and accessible. Original error: ${errorMessage}`\n );\n connectionError.name = \"ConnectionError\";\n throw connectionError;\n }\n\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof HTTPError) {\n if (STATUS_NO_RETRY.includes(error.status)) {\n throw error;\n }\n if (onFailedResponseHook && error.response) {\n await onFailedResponseHook(error.response);\n }\n }\n },\n // If needed we can change some of the defaults here,\n // but they're quite sensible.\n retries: this.maxRetries,\n randomize: true,\n }\n ),\n { throwOnTimeout: true }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(\n options: AsyncCallerCallOptions,\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n // Note this doesn't cancel the underlying request,\n // when available prefer to use the signal option of the underlying call\n if (options.signal) {\n return Promise.race([\n this.call<A, T>(callable, ...args),\n new Promise<never>((_, reject) => {\n options.signal?.addEventListener(\"abort\", () => {\n reject(new Error(\"AbortError\"));\n });\n }),\n ]);\n }\n return this.call<A, T>(callable, ...args);\n }\n\n fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {\n const fetchFn =\n this.customFetch ?? (_getFetchImplementation() as typeof fetch);\n return this.call(() =>\n fetchFn(...args).then((res) => (res.ok ? res : Promise.reject(res)))\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"async_caller.js","names":[],"sources":["../../src/utils/async_caller.ts"],"sourcesContent":["import pRetry from \"p-retry\";\nimport PQueueMod from \"p-queue\";\nimport { _getFetchImplementation } from \"../singletons/fetch.js\";\n\nconst STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 408, // Request Timeout\n 409, // Conflict\n 422, // Unprocessable Entity\n];\n\ntype ResponseCallback = (response?: Response) => Promise<boolean>;\n\nexport interface AsyncCallerParams {\n /**\n * The maximum number of concurrent calls that can be made.\n * Defaults to `Infinity`, which means no limit.\n */\n maxConcurrency?: number;\n /**\n * The maximum number of retries that can be made for a single call,\n * with an exponential backoff between each attempt. Defaults to 6.\n */\n maxRetries?: number;\n\n onFailedResponseHook?: ResponseCallback;\n\n /**\n * Specify a custom fetch implementation.\n *\n * By default we expect the `fetch` is available in the global scope.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\nexport interface AsyncCallerCallOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Do not rely on globalThis.Response, rather just\n * do duck typing\n */\nfunction isResponse(x: unknown): x is Response {\n if (x == null || typeof x !== \"object\") return false;\n return \"status\" in x && \"statusText\" in x && \"text\" in x;\n}\n\n/**\n * Utility error to properly handle failed requests\n */\nclass HTTPError extends Error {\n status: number;\n\n text: string;\n\n response?: Response;\n\n constructor(status: number, message: string, response?: Response) {\n super(`HTTP ${status}: ${message}`);\n this.status = status;\n this.text = message;\n this.response = response;\n }\n\n static async fromResponse(\n response: Response,\n options?: { includeResponse?: boolean }\n ): Promise<HTTPError> {\n try {\n return new HTTPError(\n response.status,\n await response.text(),\n options?.includeResponse ? response : undefined\n );\n } catch {\n return new HTTPError(\n response.status,\n response.statusText,\n options?.includeResponse ? response : undefined\n );\n }\n }\n}\n\n/**\n * A class that can be used to make async calls with concurrency and retry logic.\n *\n * This is useful for making calls to any kind of \"expensive\" external resource,\n * be it because it's rate-limited, subject to network issues, etc.\n *\n * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults\n * to `Infinity`. This means that by default, all calls will be made in parallel.\n *\n * Retries are limited by the `maxRetries` parameter, which defaults to 5. This\n * means that by default, each call will be retried up to 5 times, with an\n * exponential backoff between each attempt.\n */\nexport class AsyncCaller {\n protected maxConcurrency: AsyncCallerParams[\"maxConcurrency\"];\n\n protected maxRetries: AsyncCallerParams[\"maxRetries\"];\n\n private queue: typeof import(\"p-queue\")[\"default\"][\"prototype\"];\n\n private onFailedResponseHook?: ResponseCallback;\n\n private customFetch?: typeof fetch;\n\n constructor(params: AsyncCallerParams) {\n this.maxConcurrency = params.maxConcurrency ?? Infinity;\n this.maxRetries = params.maxRetries ?? 4;\n\n if (\"default\" in PQueueMod) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.queue = new (PQueueMod.default as any)({\n concurrency: this.maxConcurrency,\n });\n } else {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.queue = new (PQueueMod as any)({ concurrency: this.maxConcurrency });\n }\n this.onFailedResponseHook = params?.onFailedResponseHook;\n this.customFetch = params.fetch;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n call<A extends any[], T extends (...args: A) => Promise<any>>(\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n const { onFailedResponseHook } = this;\n return this.queue.add(\n () =>\n pRetry(\n () =>\n callable(...(args as Parameters<T>)).catch(async (error) => {\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof Error) {\n throw error;\n } else if (isResponse(error)) {\n throw await HTTPError.fromResponse(error, {\n includeResponse: !!onFailedResponseHook,\n });\n } else {\n throw new Error(error);\n }\n }),\n {\n async onFailedAttempt({ error }) {\n const errorMessage = error.message ?? \"\";\n if (\n errorMessage.startsWith(\"Cancel\") ||\n errorMessage.startsWith(\"TimeoutError\") ||\n errorMessage.startsWith(\"AbortError\")\n ) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n throw error;\n }\n\n // Check for connection refused errors (server not running)\n if (\n errorMessage.includes(\"ECONNREFUSED\") ||\n errorMessage.includes(\"fetch failed\") ||\n errorMessage.includes(\"Failed to fetch\") ||\n errorMessage.includes(\"NetworkError\")\n ) {\n const connectionError = new Error(\n `Unable to connect to LangGraph server. Please ensure the server is running and accessible. Original error: ${errorMessage}`\n );\n connectionError.name = \"ConnectionError\";\n throw connectionError;\n }\n\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof HTTPError) {\n if (STATUS_NO_RETRY.includes(error.status)) {\n throw error;\n }\n if (onFailedResponseHook && error.response) {\n await onFailedResponseHook(error.response);\n }\n }\n },\n // If needed we can change some of the defaults here,\n // but they're quite sensible.\n retries: this.maxRetries,\n randomize: true,\n }\n ),\n { throwOnTimeout: true }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(\n options: AsyncCallerCallOptions,\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n // Note this doesn't cancel the underlying request,\n // when available prefer to use the signal option of the underlying call\n if (options.signal) {\n return Promise.race([\n this.call<A, T>(callable, ...args),\n new Promise<never>((_, reject) => {\n options.signal?.addEventListener(\"abort\", () => {\n reject(new Error(\"AbortError\"));\n });\n }),\n ]);\n }\n return this.call<A, T>(callable, ...args);\n }\n\n fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {\n const fetchFn =\n this.customFetch ?? (_getFetchImplementation() as typeof fetch);\n return this.call(() =>\n fetchFn(...args).then((res) => (res.ok ? res : Promise.reject(res)))\n );\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
-
2
1
  //#region src/utils/env.ts
3
2
  function getEnvironmentVariable(name) {
4
3
  try {
@@ -7,7 +6,7 @@ function getEnvironmentVariable(name) {
7
6
  return;
8
7
  }
9
8
  }
10
-
11
9
  //#endregion
12
10
  exports.getEnvironmentVariable = getEnvironmentVariable;
11
+
13
12
  //# sourceMappingURL=env.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.cjs","names":[],"sources":["../../src/utils/env.ts"],"sourcesContent":["export function getEnvironmentVariable(name: string): string | undefined {\n // Certain setups (Deno, frontend) will throw an error if you try to access environment variables\n try {\n return typeof process !== \"undefined\"\n ? // eslint-disable-next-line no-process-env\n process.env?.[name]\n : undefined;\n } catch (e) {\n return undefined;\n }\n}\n"],"mappings":";;AAAA,SAAgB,uBAAuB,MAAkC;AAEvE,KAAI;AACF,SAAO,OAAO,YAAY,cAEtB,QAAQ,MAAM,QACd;UACG,GAAG;AACV"}
1
+ {"version":3,"file":"env.cjs","names":[],"sources":["../../src/utils/env.ts"],"sourcesContent":["export function getEnvironmentVariable(name: string): string | undefined {\n // Certain setups (Deno, frontend) will throw an error if you try to access environment variables\n try {\n return typeof process !== \"undefined\"\n ? // eslint-disable-next-line no-process-env\n process.env?.[name]\n : undefined;\n } catch (e) {\n return undefined;\n }\n}\n"],"mappings":";AAAA,SAAgB,uBAAuB,MAAkC;AAEvE,KAAI;AACF,SAAO,OAAO,YAAY,cAEtB,QAAQ,MAAM,QACd,KAAA;UACG,GAAG;AACV"}
package/dist/utils/env.js CHANGED
@@ -6,7 +6,7 @@ function getEnvironmentVariable(name) {
6
6
  return;
7
7
  }
8
8
  }
9
-
10
9
  //#endregion
11
10
  export { getEnvironmentVariable };
11
+
12
12
  //# sourceMappingURL=env.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","names":[],"sources":["../../src/utils/env.ts"],"sourcesContent":["export function getEnvironmentVariable(name: string): string | undefined {\n // Certain setups (Deno, frontend) will throw an error if you try to access environment variables\n try {\n return typeof process !== \"undefined\"\n ? // eslint-disable-next-line no-process-env\n process.env?.[name]\n : undefined;\n } catch (e) {\n return undefined;\n }\n}\n"],"mappings":";AAAA,SAAgB,uBAAuB,MAAkC;AAEvE,KAAI;AACF,SAAO,OAAO,YAAY,cAEtB,QAAQ,MAAM,QACd;UACG,GAAG;AACV"}
1
+ {"version":3,"file":"env.js","names":[],"sources":["../../src/utils/env.ts"],"sourcesContent":["export function getEnvironmentVariable(name: string): string | undefined {\n // Certain setups (Deno, frontend) will throw an error if you try to access environment variables\n try {\n return typeof process !== \"undefined\"\n ? // eslint-disable-next-line no-process-env\n process.env?.[name]\n : undefined;\n } catch (e) {\n return undefined;\n }\n}\n"],"mappings":";AAAA,SAAgB,uBAAuB,MAAkC;AAEvE,KAAI;AACF,SAAO,OAAO,YAAY,cAEtB,QAAQ,MAAM,QACd,KAAA;UACG,GAAG;AACV"}
@@ -1,4 +1,3 @@
1
-
2
1
  //#region src/utils/error.ts
3
2
  const isError = (error) => {
4
3
  if ("isError" in Error && typeof Error.isError === "function") return Error.isError(error);
@@ -18,7 +17,7 @@ const isNetworkError = (error) => {
18
17
  const causeMsg = getCauseError(error)?.message?.toLowerCase() ?? "";
19
18
  return msg.includes("fetch") || msg.includes("network") || msg.includes("connection") || msg.includes("error sending request") || msg.includes("load failed") || msg.includes("terminated") || causeMsg.includes("other side closed") || causeMsg.includes("socket");
20
19
  };
21
-
22
20
  //#endregion
23
21
  exports.isNetworkError = isNetworkError;
22
+
24
23
  //# sourceMappingURL=error.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.cjs","names":[],"sources":["../../src/utils/error.ts"],"sourcesContent":["export const isError = (error: unknown): error is Error => {\n // check for presence of `Error.isError` for newer browsers\n if (\"isError\" in Error && typeof Error.isError === \"function\") {\n return Error.isError(error);\n }\n\n // Resort to checking string tag\n const stringTag = Object.prototype.toString.call(error);\n return (\n stringTag === \"[object Error]\" ||\n stringTag === \"[object DOMException]\" ||\n stringTag === \"[object DOMError]\" ||\n stringTag === \"[object Exception]\"\n );\n};\n\nconst getCauseError = (error: Error): Error | null => {\n const { cause } = error;\n if (typeof cause !== \"object\" || cause == null) return null;\n\n if (!isError(cause)) return null;\n return cause;\n};\n\nexport const isNetworkError = (error: unknown): error is Error => {\n if (!isError(error)) return false;\n if (error.name !== \"TypeError\" || typeof error.message !== \"string\") {\n return false;\n }\n const msg = error.message.toLowerCase();\n const causeMsg = getCauseError(error)?.message?.toLowerCase() ?? \"\";\n return (\n msg.includes(\"fetch\") ||\n msg.includes(\"network\") ||\n msg.includes(\"connection\") ||\n msg.includes(\"error sending request\") ||\n msg.includes(\"load failed\") ||\n msg.includes(\"terminated\") ||\n causeMsg.includes(\"other side closed\") ||\n causeMsg.includes(\"socket\")\n );\n};\n"],"mappings":";;AAAA,MAAa,WAAW,UAAmC;AAEzD,KAAI,aAAa,SAAS,OAAO,MAAM,YAAY,WACjD,QAAO,MAAM,QAAQ,MAAM;CAI7B,MAAM,YAAY,OAAO,UAAU,SAAS,KAAK,MAAM;AACvD,QACE,cAAc,oBACd,cAAc,2BACd,cAAc,uBACd,cAAc;;AAIlB,MAAM,iBAAiB,UAA+B;CACpD,MAAM,EAAE,UAAU;AAClB,KAAI,OAAO,UAAU,YAAY,SAAS,KAAM,QAAO;AAEvD,KAAI,CAAC,QAAQ,MAAM,CAAE,QAAO;AAC5B,QAAO;;AAGT,MAAa,kBAAkB,UAAmC;AAChE,KAAI,CAAC,QAAQ,MAAM,CAAE,QAAO;AAC5B,KAAI,MAAM,SAAS,eAAe,OAAO,MAAM,YAAY,SACzD,QAAO;CAET,MAAM,MAAM,MAAM,QAAQ,aAAa;CACvC,MAAM,WAAW,cAAc,MAAM,EAAE,SAAS,aAAa,IAAI;AACjE,QACE,IAAI,SAAS,QAAQ,IACrB,IAAI,SAAS,UAAU,IACvB,IAAI,SAAS,aAAa,IAC1B,IAAI,SAAS,wBAAwB,IACrC,IAAI,SAAS,cAAc,IAC3B,IAAI,SAAS,aAAa,IAC1B,SAAS,SAAS,oBAAoB,IACtC,SAAS,SAAS,SAAS"}
1
+ {"version":3,"file":"error.cjs","names":[],"sources":["../../src/utils/error.ts"],"sourcesContent":["export const isError = (error: unknown): error is Error => {\n // check for presence of `Error.isError` for newer browsers\n if (\"isError\" in Error && typeof Error.isError === \"function\") {\n return Error.isError(error);\n }\n\n // Resort to checking string tag\n const stringTag = Object.prototype.toString.call(error);\n return (\n stringTag === \"[object Error]\" ||\n stringTag === \"[object DOMException]\" ||\n stringTag === \"[object DOMError]\" ||\n stringTag === \"[object Exception]\"\n );\n};\n\nconst getCauseError = (error: Error): Error | null => {\n const { cause } = error;\n if (typeof cause !== \"object\" || cause == null) return null;\n\n if (!isError(cause)) return null;\n return cause;\n};\n\nexport const isNetworkError = (error: unknown): error is Error => {\n if (!isError(error)) return false;\n if (error.name !== \"TypeError\" || typeof error.message !== \"string\") {\n return false;\n }\n const msg = error.message.toLowerCase();\n const causeMsg = getCauseError(error)?.message?.toLowerCase() ?? \"\";\n return (\n msg.includes(\"fetch\") ||\n msg.includes(\"network\") ||\n msg.includes(\"connection\") ||\n msg.includes(\"error sending request\") ||\n msg.includes(\"load failed\") ||\n msg.includes(\"terminated\") ||\n causeMsg.includes(\"other side closed\") ||\n causeMsg.includes(\"socket\")\n );\n};\n"],"mappings":";AAAA,MAAa,WAAW,UAAmC;AAEzD,KAAI,aAAa,SAAS,OAAO,MAAM,YAAY,WACjD,QAAO,MAAM,QAAQ,MAAM;CAI7B,MAAM,YAAY,OAAO,UAAU,SAAS,KAAK,MAAM;AACvD,QACE,cAAc,oBACd,cAAc,2BACd,cAAc,uBACd,cAAc;;AAIlB,MAAM,iBAAiB,UAA+B;CACpD,MAAM,EAAE,UAAU;AAClB,KAAI,OAAO,UAAU,YAAY,SAAS,KAAM,QAAO;AAEvD,KAAI,CAAC,QAAQ,MAAM,CAAE,QAAO;AAC5B,QAAO;;AAGT,MAAa,kBAAkB,UAAmC;AAChE,KAAI,CAAC,QAAQ,MAAM,CAAE,QAAO;AAC5B,KAAI,MAAM,SAAS,eAAe,OAAO,MAAM,YAAY,SACzD,QAAO;CAET,MAAM,MAAM,MAAM,QAAQ,aAAa;CACvC,MAAM,WAAW,cAAc,MAAM,EAAE,SAAS,aAAa,IAAI;AACjE,QACE,IAAI,SAAS,QAAQ,IACrB,IAAI,SAAS,UAAU,IACvB,IAAI,SAAS,aAAa,IAC1B,IAAI,SAAS,wBAAwB,IACrC,IAAI,SAAS,cAAc,IAC3B,IAAI,SAAS,aAAa,IAC1B,SAAS,SAAS,oBAAoB,IACtC,SAAS,SAAS,SAAS"}
@@ -17,7 +17,7 @@ const isNetworkError = (error) => {
17
17
  const causeMsg = getCauseError(error)?.message?.toLowerCase() ?? "";
18
18
  return msg.includes("fetch") || msg.includes("network") || msg.includes("connection") || msg.includes("error sending request") || msg.includes("load failed") || msg.includes("terminated") || causeMsg.includes("other side closed") || causeMsg.includes("socket");
19
19
  };
20
-
21
20
  //#endregion
22
21
  export { isNetworkError };
22
+
23
23
  //# sourceMappingURL=error.js.map
@@ -1,9 +1,8 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_sse = require('./sse.cjs');
3
- const require_stream = require('./stream.cjs');
4
- const require_tools = require('./tools.cjs');
5
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_sse = require("./sse.cjs");
3
+ const require_stream = require("./stream.cjs");
4
+ const require_tools = require("./tools.cjs");
6
5
  exports.BytesLineDecoder = require_sse.BytesLineDecoder;
7
6
  exports.IterableReadableStream = require_stream.IterableReadableStream;
8
7
  exports.SSEDecoder = require_sse.SSEDecoder;
9
- exports.getToolCallsWithResults = require_tools.getToolCallsWithResults;
8
+ exports.getToolCallsWithResults = require_tools.getToolCallsWithResults;
@@ -1,5 +1,4 @@
1
1
  import { BytesLineDecoder, SSEDecoder } from "./sse.js";
2
2
  import { IterableReadableStream } from "./stream.js";
3
3
  import { getToolCallsWithResults } from "./tools.js";
4
-
5
- export { BytesLineDecoder, IterableReadableStream, SSEDecoder, getToolCallsWithResults };
4
+ export { BytesLineDecoder, IterableReadableStream, SSEDecoder, getToolCallsWithResults };
@@ -1,4 +1,3 @@
1
-
2
1
  //#region src/utils/signals.ts
3
2
  function mergeSignals(...signals) {
4
3
  const nonZeroSignals = signals.filter((signal) => signal != null);
@@ -14,7 +13,7 @@ function mergeSignals(...signals) {
14
13
  }
15
14
  return controller.signal;
16
15
  }
17
-
18
16
  //#endregion
19
17
  exports.mergeSignals = mergeSignals;
18
+
20
19
  //# sourceMappingURL=signals.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.cjs","names":[],"sources":["../../src/utils/signals.ts"],"sourcesContent":["export function mergeSignals(...signals: (AbortSignal | null | undefined)[]) {\n const nonZeroSignals = signals.filter(\n (signal): signal is AbortSignal => signal != null\n );\n\n if (nonZeroSignals.length === 0) return undefined;\n if (nonZeroSignals.length === 1) return nonZeroSignals[0];\n\n const controller = new AbortController();\n for (const signal of signals) {\n if (signal?.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n\n signal?.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n\n return controller.signal;\n}\n"],"mappings":";;AAAA,SAAgB,aAAa,GAAG,SAA6C;CAC3E,MAAM,iBAAiB,QAAQ,QAC5B,WAAkC,UAAU,KAC9C;AAED,KAAI,eAAe,WAAW,EAAG,QAAO;AACxC,KAAI,eAAe,WAAW,EAAG,QAAO,eAAe;CAEvD,MAAM,aAAa,IAAI,iBAAiB;AACxC,MAAK,MAAM,UAAU,SAAS;AAC5B,MAAI,QAAQ,SAAS;AACnB,cAAW,MAAM,OAAO,OAAO;AAC/B,UAAO,WAAW;;AAGpB,UAAQ,iBAAiB,eAAe,WAAW,MAAM,OAAO,OAAO,EAAE,EACvE,MAAM,MACP,CAAC;;AAGJ,QAAO,WAAW"}
1
+ {"version":3,"file":"signals.cjs","names":[],"sources":["../../src/utils/signals.ts"],"sourcesContent":["export function mergeSignals(...signals: (AbortSignal | null | undefined)[]) {\n const nonZeroSignals = signals.filter(\n (signal): signal is AbortSignal => signal != null\n );\n\n if (nonZeroSignals.length === 0) return undefined;\n if (nonZeroSignals.length === 1) return nonZeroSignals[0];\n\n const controller = new AbortController();\n for (const signal of signals) {\n if (signal?.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n\n signal?.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n\n return controller.signal;\n}\n"],"mappings":";AAAA,SAAgB,aAAa,GAAG,SAA6C;CAC3E,MAAM,iBAAiB,QAAQ,QAC5B,WAAkC,UAAU,KAC9C;AAED,KAAI,eAAe,WAAW,EAAG,QAAO,KAAA;AACxC,KAAI,eAAe,WAAW,EAAG,QAAO,eAAe;CAEvD,MAAM,aAAa,IAAI,iBAAiB;AACxC,MAAK,MAAM,UAAU,SAAS;AAC5B,MAAI,QAAQ,SAAS;AACnB,cAAW,MAAM,OAAO,OAAO;AAC/B,UAAO,WAAW;;AAGpB,UAAQ,iBAAiB,eAAe,WAAW,MAAM,OAAO,OAAO,EAAE,EACvE,MAAM,MACP,CAAC;;AAGJ,QAAO,WAAW"}
@@ -13,7 +13,7 @@ function mergeSignals(...signals) {
13
13
  }
14
14
  return controller.signal;
15
15
  }
16
-
17
16
  //#endregion
18
17
  export { mergeSignals };
18
+
19
19
  //# sourceMappingURL=signals.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.js","names":[],"sources":["../../src/utils/signals.ts"],"sourcesContent":["export function mergeSignals(...signals: (AbortSignal | null | undefined)[]) {\n const nonZeroSignals = signals.filter(\n (signal): signal is AbortSignal => signal != null\n );\n\n if (nonZeroSignals.length === 0) return undefined;\n if (nonZeroSignals.length === 1) return nonZeroSignals[0];\n\n const controller = new AbortController();\n for (const signal of signals) {\n if (signal?.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n\n signal?.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n\n return controller.signal;\n}\n"],"mappings":";AAAA,SAAgB,aAAa,GAAG,SAA6C;CAC3E,MAAM,iBAAiB,QAAQ,QAC5B,WAAkC,UAAU,KAC9C;AAED,KAAI,eAAe,WAAW,EAAG,QAAO;AACxC,KAAI,eAAe,WAAW,EAAG,QAAO,eAAe;CAEvD,MAAM,aAAa,IAAI,iBAAiB;AACxC,MAAK,MAAM,UAAU,SAAS;AAC5B,MAAI,QAAQ,SAAS;AACnB,cAAW,MAAM,OAAO,OAAO;AAC/B,UAAO,WAAW;;AAGpB,UAAQ,iBAAiB,eAAe,WAAW,MAAM,OAAO,OAAO,EAAE,EACvE,MAAM,MACP,CAAC;;AAGJ,QAAO,WAAW"}
1
+ {"version":3,"file":"signals.js","names":[],"sources":["../../src/utils/signals.ts"],"sourcesContent":["export function mergeSignals(...signals: (AbortSignal | null | undefined)[]) {\n const nonZeroSignals = signals.filter(\n (signal): signal is AbortSignal => signal != null\n );\n\n if (nonZeroSignals.length === 0) return undefined;\n if (nonZeroSignals.length === 1) return nonZeroSignals[0];\n\n const controller = new AbortController();\n for (const signal of signals) {\n if (signal?.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n\n signal?.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n\n return controller.signal;\n}\n"],"mappings":";AAAA,SAAgB,aAAa,GAAG,SAA6C;CAC3E,MAAM,iBAAiB,QAAQ,QAC5B,WAAkC,UAAU,KAC9C;AAED,KAAI,eAAe,WAAW,EAAG,QAAO,KAAA;AACxC,KAAI,eAAe,WAAW,EAAG,QAAO,eAAe;CAEvD,MAAM,aAAa,IAAI,iBAAiB;AACxC,MAAK,MAAM,UAAU,SAAS;AAC5B,MAAI,QAAQ,SAAS;AACnB,cAAW,MAAM,OAAO,OAAO;AAC/B,UAAO,WAAW;;AAGpB,UAAQ,iBAAiB,eAAe,WAAW,MAAM,OAAO,OAAO,EAAE,EACvE,MAAM,MACP,CAAC;;AAGJ,QAAO,WAAW"}
@@ -1,4 +1,3 @@
1
-
2
1
  //#region src/utils/sse.ts
3
2
  const CR = "\r".charCodeAt(0);
4
3
  const LF = "\n".charCodeAt(0);
@@ -117,8 +116,8 @@ function joinArrays(data) {
117
116
  function decodeArraysToJson(decoder, data) {
118
117
  return JSON.parse(decoder.decode(joinArrays(data)));
119
118
  }
120
-
121
119
  //#endregion
122
120
  exports.BytesLineDecoder = BytesLineDecoder;
123
121
  exports.SSEDecoder = SSEDecoder;
122
+
124
123
  //# sourceMappingURL=sse.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sse.cjs","names":[],"sources":["../../src/utils/sse.ts"],"sourcesContent":["const CR = \"\\r\".charCodeAt(0);\nconst LF = \"\\n\".charCodeAt(0);\nconst NULL = \"\\0\".charCodeAt(0);\nconst COLON = \":\".charCodeAt(0);\nconst SPACE = \" \".charCodeAt(0);\n\nconst TRAILING_NEWLINE = [CR, LF];\n\nexport function BytesLineDecoder() {\n let buffer: Uint8Array[] = [];\n let trailingCr = false;\n\n return new TransformStream<Uint8Array, Uint8Array>({\n start() {\n buffer = [];\n trailingCr = false;\n },\n\n transform(chunk, controller) {\n // See https://docs.python.org/3/glossary.html#term-universal-newlines\n let text = chunk;\n\n // Handle trailing CR from previous chunk\n if (trailingCr) {\n text = joinArrays([[CR], text]);\n trailingCr = false;\n }\n\n // Check for trailing CR in current chunk\n if (text.length > 0 && text.at(-1) === CR) {\n trailingCr = true;\n text = text.subarray(0, -1);\n }\n\n if (!text.length) return;\n const trailingNewline = TRAILING_NEWLINE.includes(text.at(-1)!);\n\n const lastIdx = text.length - 1;\n const { lines } = text.reduce<{ lines: Uint8Array[]; from: number }>(\n (acc, cur, idx) => {\n if (acc.from > idx) return acc;\n\n if (cur === CR || cur === LF) {\n acc.lines.push(text.subarray(acc.from, idx));\n if (cur === CR && text[idx + 1] === LF) {\n acc.from = idx + 2;\n } else {\n acc.from = idx + 1;\n }\n }\n\n if (idx === lastIdx && acc.from <= lastIdx) {\n acc.lines.push(text.subarray(acc.from));\n }\n\n return acc;\n },\n { lines: [], from: 0 }\n );\n\n if (lines.length === 1 && !trailingNewline) {\n buffer.push(lines[0]);\n return;\n }\n\n if (buffer.length) {\n // Include existing buffer in first line\n buffer.push(lines[0]);\n lines[0] = joinArrays(buffer);\n buffer = [];\n }\n\n if (!trailingNewline) {\n // If the last segment is not newline terminated,\n // buffer it for the next chunk\n if (lines.length) buffer = [lines.pop()!];\n }\n\n // Enqueue complete lines\n for (const line of lines) {\n controller.enqueue(line);\n }\n },\n\n flush(controller) {\n if (buffer.length) {\n controller.enqueue(joinArrays(buffer));\n }\n },\n });\n}\n\ninterface StreamPart {\n id: string | undefined;\n event: string;\n data: unknown;\n}\n\nexport function SSEDecoder() {\n let event = \"\";\n let data: Uint8Array[] = [];\n let lastEventId = \"\";\n let retry: number | null = null;\n\n const decoder = new TextDecoder();\n\n return new TransformStream<Uint8Array, StreamPart>({\n transform(chunk, controller) {\n // Handle empty line case\n if (!chunk.length) {\n if (!event && !data.length && !lastEventId && retry == null) return;\n\n const sse = {\n id: lastEventId || undefined,\n event,\n data: data.length ? decodeArraysToJson(decoder, data) : null,\n };\n\n // NOTE: as per the SSE spec, do not reset lastEventId\n event = \"\";\n data = [];\n retry = null;\n\n controller.enqueue(sse);\n return;\n }\n\n // Ignore comments\n if (chunk[0] === COLON) return;\n\n const sepIdx = chunk.indexOf(COLON);\n if (sepIdx === -1) return;\n\n const fieldName = decoder.decode(chunk.subarray(0, sepIdx));\n let value = chunk.subarray(sepIdx + 1);\n if (value[0] === SPACE) value = value.subarray(1);\n\n if (fieldName === \"event\") {\n event = decoder.decode(value);\n } else if (fieldName === \"data\") {\n data.push(value);\n } else if (fieldName === \"id\") {\n if (value.indexOf(NULL) === -1) lastEventId = decoder.decode(value);\n } else if (fieldName === \"retry\") {\n const retryNum = Number.parseInt(decoder.decode(value), 10);\n if (!Number.isNaN(retryNum)) retry = retryNum;\n }\n },\n\n flush(controller) {\n if (event) {\n controller.enqueue({\n id: lastEventId || undefined,\n event,\n data: data.length ? decodeArraysToJson(decoder, data) : null,\n });\n }\n },\n });\n}\n\nfunction joinArrays(data: ArrayLike<number>[]) {\n const totalLength = data.reduce((acc, curr) => acc + curr.length, 0);\n const merged = new Uint8Array(totalLength);\n let offset = 0;\n for (const c of data) {\n merged.set(c, offset);\n offset += c.length;\n }\n return merged;\n}\n\nfunction decodeArraysToJson(decoder: TextDecoder, data: ArrayLike<number>[]) {\n return JSON.parse(decoder.decode(joinArrays(data)));\n}\n"],"mappings":";;AAAA,MAAM,KAAK,KAAK,WAAW,EAAE;AAC7B,MAAM,KAAK,KAAK,WAAW,EAAE;AAC7B,MAAM,OAAO,KAAK,WAAW,EAAE;AAC/B,MAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,MAAM,QAAQ,IAAI,WAAW,EAAE;AAE/B,MAAM,mBAAmB,CAAC,IAAI,GAAG;AAEjC,SAAgB,mBAAmB;CACjC,IAAI,SAAuB,EAAE;CAC7B,IAAI,aAAa;AAEjB,QAAO,IAAI,gBAAwC;EACjD,QAAQ;AACN,YAAS,EAAE;AACX,gBAAa;;EAGf,UAAU,OAAO,YAAY;GAE3B,IAAI,OAAO;AAGX,OAAI,YAAY;AACd,WAAO,WAAW,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC;AAC/B,iBAAa;;AAIf,OAAI,KAAK,SAAS,KAAK,KAAK,GAAG,GAAG,KAAK,IAAI;AACzC,iBAAa;AACb,WAAO,KAAK,SAAS,GAAG,GAAG;;AAG7B,OAAI,CAAC,KAAK,OAAQ;GAClB,MAAM,kBAAkB,iBAAiB,SAAS,KAAK,GAAG,GAAG,CAAE;GAE/D,MAAM,UAAU,KAAK,SAAS;GAC9B,MAAM,EAAE,UAAU,KAAK,QACpB,KAAK,KAAK,QAAQ;AACjB,QAAI,IAAI,OAAO,IAAK,QAAO;AAE3B,QAAI,QAAQ,MAAM,QAAQ,IAAI;AAC5B,SAAI,MAAM,KAAK,KAAK,SAAS,IAAI,MAAM,IAAI,CAAC;AAC5C,SAAI,QAAQ,MAAM,KAAK,MAAM,OAAO,GAClC,KAAI,OAAO,MAAM;SAEjB,KAAI,OAAO,MAAM;;AAIrB,QAAI,QAAQ,WAAW,IAAI,QAAQ,QACjC,KAAI,MAAM,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC;AAGzC,WAAO;MAET;IAAE,OAAO,EAAE;IAAE,MAAM;IAAG,CACvB;AAED,OAAI,MAAM,WAAW,KAAK,CAAC,iBAAiB;AAC1C,WAAO,KAAK,MAAM,GAAG;AACrB;;AAGF,OAAI,OAAO,QAAQ;AAEjB,WAAO,KAAK,MAAM,GAAG;AACrB,UAAM,KAAK,WAAW,OAAO;AAC7B,aAAS,EAAE;;AAGb,OAAI,CAAC,iBAGH;QAAI,MAAM,OAAQ,UAAS,CAAC,MAAM,KAAK,CAAE;;AAI3C,QAAK,MAAM,QAAQ,MACjB,YAAW,QAAQ,KAAK;;EAI5B,MAAM,YAAY;AAChB,OAAI,OAAO,OACT,YAAW,QAAQ,WAAW,OAAO,CAAC;;EAG3C,CAAC;;AASJ,SAAgB,aAAa;CAC3B,IAAI,QAAQ;CACZ,IAAI,OAAqB,EAAE;CAC3B,IAAI,cAAc;CAClB,IAAI,QAAuB;CAE3B,MAAM,UAAU,IAAI,aAAa;AAEjC,QAAO,IAAI,gBAAwC;EACjD,UAAU,OAAO,YAAY;AAE3B,OAAI,CAAC,MAAM,QAAQ;AACjB,QAAI,CAAC,SAAS,CAAC,KAAK,UAAU,CAAC,eAAe,SAAS,KAAM;IAE7D,MAAM,MAAM;KACV,IAAI,eAAe;KACnB;KACA,MAAM,KAAK,SAAS,mBAAmB,SAAS,KAAK,GAAG;KACzD;AAGD,YAAQ;AACR,WAAO,EAAE;AACT,YAAQ;AAER,eAAW,QAAQ,IAAI;AACvB;;AAIF,OAAI,MAAM,OAAO,MAAO;GAExB,MAAM,SAAS,MAAM,QAAQ,MAAM;AACnC,OAAI,WAAW,GAAI;GAEnB,MAAM,YAAY,QAAQ,OAAO,MAAM,SAAS,GAAG,OAAO,CAAC;GAC3D,IAAI,QAAQ,MAAM,SAAS,SAAS,EAAE;AACtC,OAAI,MAAM,OAAO,MAAO,SAAQ,MAAM,SAAS,EAAE;AAEjD,OAAI,cAAc,QAChB,SAAQ,QAAQ,OAAO,MAAM;YACpB,cAAc,OACvB,MAAK,KAAK,MAAM;YACP,cAAc,MACvB;QAAI,MAAM,QAAQ,KAAK,KAAK,GAAI,eAAc,QAAQ,OAAO,MAAM;cAC1D,cAAc,SAAS;IAChC,MAAM,WAAW,OAAO,SAAS,QAAQ,OAAO,MAAM,EAAE,GAAG;AAC3D,QAAI,CAAC,OAAO,MAAM,SAAS,CAAE,SAAQ;;;EAIzC,MAAM,YAAY;AAChB,OAAI,MACF,YAAW,QAAQ;IACjB,IAAI,eAAe;IACnB;IACA,MAAM,KAAK,SAAS,mBAAmB,SAAS,KAAK,GAAG;IACzD,CAAC;;EAGP,CAAC;;AAGJ,SAAS,WAAW,MAA2B;CAC7C,MAAM,cAAc,KAAK,QAAQ,KAAK,SAAS,MAAM,KAAK,QAAQ,EAAE;CACpE,MAAM,SAAS,IAAI,WAAW,YAAY;CAC1C,IAAI,SAAS;AACb,MAAK,MAAM,KAAK,MAAM;AACpB,SAAO,IAAI,GAAG,OAAO;AACrB,YAAU,EAAE;;AAEd,QAAO;;AAGT,SAAS,mBAAmB,SAAsB,MAA2B;AAC3E,QAAO,KAAK,MAAM,QAAQ,OAAO,WAAW,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"sse.cjs","names":[],"sources":["../../src/utils/sse.ts"],"sourcesContent":["const CR = \"\\r\".charCodeAt(0);\nconst LF = \"\\n\".charCodeAt(0);\nconst NULL = \"\\0\".charCodeAt(0);\nconst COLON = \":\".charCodeAt(0);\nconst SPACE = \" \".charCodeAt(0);\n\nconst TRAILING_NEWLINE = [CR, LF];\n\nexport function BytesLineDecoder() {\n let buffer: Uint8Array[] = [];\n let trailingCr = false;\n\n return new TransformStream<Uint8Array, Uint8Array>({\n start() {\n buffer = [];\n trailingCr = false;\n },\n\n transform(chunk, controller) {\n // See https://docs.python.org/3/glossary.html#term-universal-newlines\n let text = chunk;\n\n // Handle trailing CR from previous chunk\n if (trailingCr) {\n text = joinArrays([[CR], text]);\n trailingCr = false;\n }\n\n // Check for trailing CR in current chunk\n if (text.length > 0 && text.at(-1) === CR) {\n trailingCr = true;\n text = text.subarray(0, -1);\n }\n\n if (!text.length) return;\n const trailingNewline = TRAILING_NEWLINE.includes(text.at(-1)!);\n\n const lastIdx = text.length - 1;\n const { lines } = text.reduce<{ lines: Uint8Array[]; from: number }>(\n (acc, cur, idx) => {\n if (acc.from > idx) return acc;\n\n if (cur === CR || cur === LF) {\n acc.lines.push(text.subarray(acc.from, idx));\n if (cur === CR && text[idx + 1] === LF) {\n acc.from = idx + 2;\n } else {\n acc.from = idx + 1;\n }\n }\n\n if (idx === lastIdx && acc.from <= lastIdx) {\n acc.lines.push(text.subarray(acc.from));\n }\n\n return acc;\n },\n { lines: [], from: 0 }\n );\n\n if (lines.length === 1 && !trailingNewline) {\n buffer.push(lines[0]);\n return;\n }\n\n if (buffer.length) {\n // Include existing buffer in first line\n buffer.push(lines[0]);\n lines[0] = joinArrays(buffer);\n buffer = [];\n }\n\n if (!trailingNewline) {\n // If the last segment is not newline terminated,\n // buffer it for the next chunk\n if (lines.length) buffer = [lines.pop()!];\n }\n\n // Enqueue complete lines\n for (const line of lines) {\n controller.enqueue(line);\n }\n },\n\n flush(controller) {\n if (buffer.length) {\n controller.enqueue(joinArrays(buffer));\n }\n },\n });\n}\n\ninterface StreamPart {\n id: string | undefined;\n event: string;\n data: unknown;\n}\n\nexport function SSEDecoder() {\n let event = \"\";\n let data: Uint8Array[] = [];\n let lastEventId = \"\";\n let retry: number | null = null;\n\n const decoder = new TextDecoder();\n\n return new TransformStream<Uint8Array, StreamPart>({\n transform(chunk, controller) {\n // Handle empty line case\n if (!chunk.length) {\n if (!event && !data.length && !lastEventId && retry == null) return;\n\n const sse = {\n id: lastEventId || undefined,\n event,\n data: data.length ? decodeArraysToJson(decoder, data) : null,\n };\n\n // NOTE: as per the SSE spec, do not reset lastEventId\n event = \"\";\n data = [];\n retry = null;\n\n controller.enqueue(sse);\n return;\n }\n\n // Ignore comments\n if (chunk[0] === COLON) return;\n\n const sepIdx = chunk.indexOf(COLON);\n if (sepIdx === -1) return;\n\n const fieldName = decoder.decode(chunk.subarray(0, sepIdx));\n let value = chunk.subarray(sepIdx + 1);\n if (value[0] === SPACE) value = value.subarray(1);\n\n if (fieldName === \"event\") {\n event = decoder.decode(value);\n } else if (fieldName === \"data\") {\n data.push(value);\n } else if (fieldName === \"id\") {\n if (value.indexOf(NULL) === -1) lastEventId = decoder.decode(value);\n } else if (fieldName === \"retry\") {\n const retryNum = Number.parseInt(decoder.decode(value), 10);\n if (!Number.isNaN(retryNum)) retry = retryNum;\n }\n },\n\n flush(controller) {\n if (event) {\n controller.enqueue({\n id: lastEventId || undefined,\n event,\n data: data.length ? decodeArraysToJson(decoder, data) : null,\n });\n }\n },\n });\n}\n\nfunction joinArrays(data: ArrayLike<number>[]) {\n const totalLength = data.reduce((acc, curr) => acc + curr.length, 0);\n const merged = new Uint8Array(totalLength);\n let offset = 0;\n for (const c of data) {\n merged.set(c, offset);\n offset += c.length;\n }\n return merged;\n}\n\nfunction decodeArraysToJson(decoder: TextDecoder, data: ArrayLike<number>[]) {\n return JSON.parse(decoder.decode(joinArrays(data)));\n}\n"],"mappings":"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"}
package/dist/utils/sse.js CHANGED
@@ -116,7 +116,7 @@ function joinArrays(data) {
116
116
  function decodeArraysToJson(decoder, data) {
117
117
  return JSON.parse(decoder.decode(joinArrays(data)));
118
118
  }
119
-
120
119
  //#endregion
121
120
  export { BytesLineDecoder, SSEDecoder };
121
+
122
122
  //# sourceMappingURL=sse.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sse.js","names":[],"sources":["../../src/utils/sse.ts"],"sourcesContent":["const CR = \"\\r\".charCodeAt(0);\nconst LF = \"\\n\".charCodeAt(0);\nconst NULL = \"\\0\".charCodeAt(0);\nconst COLON = \":\".charCodeAt(0);\nconst SPACE = \" \".charCodeAt(0);\n\nconst TRAILING_NEWLINE = [CR, LF];\n\nexport function BytesLineDecoder() {\n let buffer: Uint8Array[] = [];\n let trailingCr = false;\n\n return new TransformStream<Uint8Array, Uint8Array>({\n start() {\n buffer = [];\n trailingCr = false;\n },\n\n transform(chunk, controller) {\n // See https://docs.python.org/3/glossary.html#term-universal-newlines\n let text = chunk;\n\n // Handle trailing CR from previous chunk\n if (trailingCr) {\n text = joinArrays([[CR], text]);\n trailingCr = false;\n }\n\n // Check for trailing CR in current chunk\n if (text.length > 0 && text.at(-1) === CR) {\n trailingCr = true;\n text = text.subarray(0, -1);\n }\n\n if (!text.length) return;\n const trailingNewline = TRAILING_NEWLINE.includes(text.at(-1)!);\n\n const lastIdx = text.length - 1;\n const { lines } = text.reduce<{ lines: Uint8Array[]; from: number }>(\n (acc, cur, idx) => {\n if (acc.from > idx) return acc;\n\n if (cur === CR || cur === LF) {\n acc.lines.push(text.subarray(acc.from, idx));\n if (cur === CR && text[idx + 1] === LF) {\n acc.from = idx + 2;\n } else {\n acc.from = idx + 1;\n }\n }\n\n if (idx === lastIdx && acc.from <= lastIdx) {\n acc.lines.push(text.subarray(acc.from));\n }\n\n return acc;\n },\n { lines: [], from: 0 }\n );\n\n if (lines.length === 1 && !trailingNewline) {\n buffer.push(lines[0]);\n return;\n }\n\n if (buffer.length) {\n // Include existing buffer in first line\n buffer.push(lines[0]);\n lines[0] = joinArrays(buffer);\n buffer = [];\n }\n\n if (!trailingNewline) {\n // If the last segment is not newline terminated,\n // buffer it for the next chunk\n if (lines.length) buffer = [lines.pop()!];\n }\n\n // Enqueue complete lines\n for (const line of lines) {\n controller.enqueue(line);\n }\n },\n\n flush(controller) {\n if (buffer.length) {\n controller.enqueue(joinArrays(buffer));\n }\n },\n });\n}\n\ninterface StreamPart {\n id: string | undefined;\n event: string;\n data: unknown;\n}\n\nexport function SSEDecoder() {\n let event = \"\";\n let data: Uint8Array[] = [];\n let lastEventId = \"\";\n let retry: number | null = null;\n\n const decoder = new TextDecoder();\n\n return new TransformStream<Uint8Array, StreamPart>({\n transform(chunk, controller) {\n // Handle empty line case\n if (!chunk.length) {\n if (!event && !data.length && !lastEventId && retry == null) return;\n\n const sse = {\n id: lastEventId || undefined,\n event,\n data: data.length ? decodeArraysToJson(decoder, data) : null,\n };\n\n // NOTE: as per the SSE spec, do not reset lastEventId\n event = \"\";\n data = [];\n retry = null;\n\n controller.enqueue(sse);\n return;\n }\n\n // Ignore comments\n if (chunk[0] === COLON) return;\n\n const sepIdx = chunk.indexOf(COLON);\n if (sepIdx === -1) return;\n\n const fieldName = decoder.decode(chunk.subarray(0, sepIdx));\n let value = chunk.subarray(sepIdx + 1);\n if (value[0] === SPACE) value = value.subarray(1);\n\n if (fieldName === \"event\") {\n event = decoder.decode(value);\n } else if (fieldName === \"data\") {\n data.push(value);\n } else if (fieldName === \"id\") {\n if (value.indexOf(NULL) === -1) lastEventId = decoder.decode(value);\n } else if (fieldName === \"retry\") {\n const retryNum = Number.parseInt(decoder.decode(value), 10);\n if (!Number.isNaN(retryNum)) retry = retryNum;\n }\n },\n\n flush(controller) {\n if (event) {\n controller.enqueue({\n id: lastEventId || undefined,\n event,\n data: data.length ? decodeArraysToJson(decoder, data) : null,\n });\n }\n },\n });\n}\n\nfunction joinArrays(data: ArrayLike<number>[]) {\n const totalLength = data.reduce((acc, curr) => acc + curr.length, 0);\n const merged = new Uint8Array(totalLength);\n let offset = 0;\n for (const c of data) {\n merged.set(c, offset);\n offset += c.length;\n }\n return merged;\n}\n\nfunction decodeArraysToJson(decoder: TextDecoder, data: ArrayLike<number>[]) {\n return JSON.parse(decoder.decode(joinArrays(data)));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sse.js","names":[],"sources":["../../src/utils/sse.ts"],"sourcesContent":["const CR = \"\\r\".charCodeAt(0);\nconst LF = \"\\n\".charCodeAt(0);\nconst NULL = \"\\0\".charCodeAt(0);\nconst COLON = \":\".charCodeAt(0);\nconst SPACE = \" \".charCodeAt(0);\n\nconst TRAILING_NEWLINE = [CR, LF];\n\nexport function BytesLineDecoder() {\n let buffer: Uint8Array[] = [];\n let trailingCr = false;\n\n return new TransformStream<Uint8Array, Uint8Array>({\n start() {\n buffer = [];\n trailingCr = false;\n },\n\n transform(chunk, controller) {\n // See https://docs.python.org/3/glossary.html#term-universal-newlines\n let text = chunk;\n\n // Handle trailing CR from previous chunk\n if (trailingCr) {\n text = joinArrays([[CR], text]);\n trailingCr = false;\n }\n\n // Check for trailing CR in current chunk\n if (text.length > 0 && text.at(-1) === CR) {\n trailingCr = true;\n text = text.subarray(0, -1);\n }\n\n if (!text.length) return;\n const trailingNewline = TRAILING_NEWLINE.includes(text.at(-1)!);\n\n const lastIdx = text.length - 1;\n const { lines } = text.reduce<{ lines: Uint8Array[]; from: number }>(\n (acc, cur, idx) => {\n if (acc.from > idx) return acc;\n\n if (cur === CR || cur === LF) {\n acc.lines.push(text.subarray(acc.from, idx));\n if (cur === CR && text[idx + 1] === LF) {\n acc.from = idx + 2;\n } else {\n acc.from = idx + 1;\n }\n }\n\n if (idx === lastIdx && acc.from <= lastIdx) {\n acc.lines.push(text.subarray(acc.from));\n }\n\n return acc;\n },\n { lines: [], from: 0 }\n );\n\n if (lines.length === 1 && !trailingNewline) {\n buffer.push(lines[0]);\n return;\n }\n\n if (buffer.length) {\n // Include existing buffer in first line\n buffer.push(lines[0]);\n lines[0] = joinArrays(buffer);\n buffer = [];\n }\n\n if (!trailingNewline) {\n // If the last segment is not newline terminated,\n // buffer it for the next chunk\n if (lines.length) buffer = [lines.pop()!];\n }\n\n // Enqueue complete lines\n for (const line of lines) {\n controller.enqueue(line);\n }\n },\n\n flush(controller) {\n if (buffer.length) {\n controller.enqueue(joinArrays(buffer));\n }\n },\n });\n}\n\ninterface StreamPart {\n id: string | undefined;\n event: string;\n data: unknown;\n}\n\nexport function SSEDecoder() {\n let event = \"\";\n let data: Uint8Array[] = [];\n let lastEventId = \"\";\n let retry: number | null = null;\n\n const decoder = new TextDecoder();\n\n return new TransformStream<Uint8Array, StreamPart>({\n transform(chunk, controller) {\n // Handle empty line case\n if (!chunk.length) {\n if (!event && !data.length && !lastEventId && retry == null) return;\n\n const sse = {\n id: lastEventId || undefined,\n event,\n data: data.length ? decodeArraysToJson(decoder, data) : null,\n };\n\n // NOTE: as per the SSE spec, do not reset lastEventId\n event = \"\";\n data = [];\n retry = null;\n\n controller.enqueue(sse);\n return;\n }\n\n // Ignore comments\n if (chunk[0] === COLON) return;\n\n const sepIdx = chunk.indexOf(COLON);\n if (sepIdx === -1) return;\n\n const fieldName = decoder.decode(chunk.subarray(0, sepIdx));\n let value = chunk.subarray(sepIdx + 1);\n if (value[0] === SPACE) value = value.subarray(1);\n\n if (fieldName === \"event\") {\n event = decoder.decode(value);\n } else if (fieldName === \"data\") {\n data.push(value);\n } else if (fieldName === \"id\") {\n if (value.indexOf(NULL) === -1) lastEventId = decoder.decode(value);\n } else if (fieldName === \"retry\") {\n const retryNum = Number.parseInt(decoder.decode(value), 10);\n if (!Number.isNaN(retryNum)) retry = retryNum;\n }\n },\n\n flush(controller) {\n if (event) {\n controller.enqueue({\n id: lastEventId || undefined,\n event,\n data: data.length ? decodeArraysToJson(decoder, data) : null,\n });\n }\n },\n });\n}\n\nfunction joinArrays(data: ArrayLike<number>[]) {\n const totalLength = data.reduce((acc, curr) => acc + curr.length, 0);\n const merged = new Uint8Array(totalLength);\n let offset = 0;\n for (const c of data) {\n merged.set(c, offset);\n offset += c.length;\n }\n return merged;\n}\n\nfunction decodeArraysToJson(decoder: TextDecoder, data: ArrayLike<number>[]) {\n return JSON.parse(decoder.decode(joinArrays(data)));\n}\n"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- const require_error = require('./error.cjs');
2
-
1
+ const require_error = require("./error.cjs");
3
2
  //#region src/utils/stream.ts
4
3
  /**
5
4
  * Error thrown when maximum reconnection attempts are exceeded.
@@ -167,8 +166,8 @@ var IterableReadableStream = class IterableReadableStream extends ReadableStream
167
166
  });
168
167
  }
169
168
  };
170
-
171
169
  //#endregion
172
170
  exports.IterableReadableStream = IterableReadableStream;
173
171
  exports.streamWithRetry = streamWithRetry;
172
+
174
173
  //# sourceMappingURL=stream.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.cjs","names":["isNetworkError"],"sources":["../../src/utils/stream.ts"],"sourcesContent":["import { isNetworkError } from \"./error.js\";\n\n// in this case don't quite match.\ntype IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;\n\n/**\n * Options for streaming with automatic retry logic.\n */\nexport interface StreamWithRetryOptions {\n /**\n * Maximum number of reconnection attempts. Default is 5.\n */\n maxRetries?: number;\n\n /**\n * AbortSignal to cancel the stream.\n */\n signal?: AbortSignal;\n\n /**\n * Callback invoked when a reconnection attempt is made.\n */\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n}\n\n/**\n * Parameters for making a stream request\n */\nexport interface StreamRequestParams {\n /**\n * Last event ID to resume from, if available\n */\n lastEventId?: string;\n\n /**\n * Optional reconnection path from the Location header\n */\n reconnectPath?: string;\n}\n\n/**\n * Error thrown when maximum reconnection attempts are exceeded.\n */\nexport class MaxReconnectAttemptsError extends Error {\n constructor(maxAttempts: number, cause: unknown) {\n super(`Exceeded maximum SSE reconnection attempts (${maxAttempts})`);\n this.name = \"MaxReconnectAttemptsError\";\n this.cause = cause;\n }\n}\n\n/**\n * Stream with automatic retry logic for SSE connections.\n * Implements reconnection behavior similar to the Python SDK.\n *\n * @param makeRequest Function to make requests. When `params` is undefined/empty, it's the initial request.\n * When `params.reconnectPath` is provided, it's a reconnection request.\n * @param options Configuration options\n * @returns AsyncGenerator yielding stream events\n */\nexport async function* streamWithRetry<T extends { id?: string }>(\n makeRequest: (params?: StreamRequestParams) => Promise<{\n response: Response;\n stream: ReadableStream<T>;\n }>,\n options: StreamWithRetryOptions = {}\n): AsyncGenerator<T> {\n const maxRetries = options.maxRetries ?? 5;\n let attempt = 0;\n let lastEventId: string | undefined;\n let reconnectPath: string | undefined;\n\n while (true) {\n let shouldRetry = false;\n let lastError: unknown;\n let reader: ReadableStreamDefaultReader<T> | undefined;\n\n try {\n // Check if aborted before making request\n if (options.signal?.aborted) return;\n\n // Make request - initial if no reconnect path, reconnect otherwise\n const { response, stream } = await makeRequest(\n reconnectPath ? { lastEventId, reconnectPath } : undefined\n );\n\n // Check for Location header (server-provided reconnection path)\n const locationHeader = response.headers.get(\"location\");\n if (locationHeader) {\n reconnectPath = locationHeader;\n }\n\n // Verify content type\n const contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n if (contentType && !contentType.includes(\"text/event-stream\")) {\n throw new Error(\n `Expected response header Content-Type to contain 'text/event-stream', got '${contentType}'`\n );\n }\n\n reader = stream.getReader();\n\n try {\n while (true) {\n // Check abort signal before each read\n if (options.signal?.aborted) {\n await reader.cancel();\n return;\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream completed successfully\n break;\n }\n\n // Track last event ID for reconnection\n if (value.id) {\n lastEventId = value.id;\n }\n\n yield value;\n }\n\n // Stream completed successfully, exit retry loop\n break;\n } catch (error) {\n // Error during streaming - attempt reconnect if we have a location header\n if (reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore errors when releasing lock\n }\n }\n }\n } catch (error) {\n lastError = error;\n\n // Only retry if we have reconnection capability and it's a network error\n if (isNetworkError(error) && reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n }\n\n if (shouldRetry) {\n attempt += 1;\n if (attempt > maxRetries) {\n throw new MaxReconnectAttemptsError(maxRetries, lastError);\n }\n\n // Notify about reconnection attempt\n options.onReconnect?.({ attempt, lastEventId, cause: lastError });\n\n // Exponential backoff with jitter: min(1000 * 2^attempt, 5000) + random jitter\n const baseDelay = Math.min(1000 * 2 ** (attempt - 1), 5000);\n const jitter = Math.random() * 1000;\n const delay = baseDelay + jitter;\n\n await new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n\n continue;\n }\n\n // Successfully completed\n break;\n }\n}\n\n/*\n * Support async iterator syntax for ReadableStreams in all environments.\n * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490\n */\nexport class IterableReadableStream<T>\n extends ReadableStream<T>\n implements IterableReadableStreamInterface<T>\n{\n public reader: ReadableStreamDefaultReader<T>;\n\n ensureReader() {\n if (!this.reader) {\n this.reader = this.getReader();\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n this.ensureReader();\n try {\n const result = await this.reader.read();\n if (result.done) {\n this.reader.releaseLock(); // release lock when stream becomes closed\n return {\n done: true,\n value: undefined,\n };\n } else {\n return {\n done: false,\n value: result.value,\n };\n }\n } catch (e) {\n this.reader.releaseLock(); // release lock when stream becomes errored\n throw e;\n }\n }\n\n async return(): Promise<IteratorResult<T>> {\n this.ensureReader();\n // If wrapped in a Node stream, cancel is already called.\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n return { done: true, value: undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async throw(e: any): Promise<IteratorResult<T>> {\n this.ensureReader();\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n throw e;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not present in Node 18 types, required in latest Node 22\n async [Symbol.asyncDispose]() {\n await this.return();\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n\n static fromReadableStream<T>(stream: ReadableStream<T>) {\n // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream\n const reader = stream.getReader();\n return new IterableReadableStream<T>({\n start(controller) {\n return pump();\n function pump(): Promise<T | undefined> {\n return reader.read().then(({ done, value }) => {\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n return;\n }\n // Enqueue the next data chunk into our target stream\n controller.enqueue(value);\n return pump();\n });\n }\n },\n cancel() {\n reader.releaseLock();\n },\n });\n }\n\n static fromAsyncGenerator<T>(generator: AsyncGenerator<T>) {\n return new IterableReadableStream<T>({\n async pull(controller) {\n const { value, done } = await generator.next();\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n }\n // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled\n controller.enqueue(value);\n },\n async cancel(reason) {\n await generator.return(reason);\n },\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stream.cjs","names":["isNetworkError"],"sources":["../../src/utils/stream.ts"],"sourcesContent":["import { isNetworkError } from \"./error.js\";\n\n// in this case don't quite match.\ntype IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;\n\n/**\n * Options for streaming with automatic retry logic.\n */\nexport interface StreamWithRetryOptions {\n /**\n * Maximum number of reconnection attempts. Default is 5.\n */\n maxRetries?: number;\n\n /**\n * AbortSignal to cancel the stream.\n */\n signal?: AbortSignal;\n\n /**\n * Callback invoked when a reconnection attempt is made.\n */\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n}\n\n/**\n * Parameters for making a stream request\n */\nexport interface StreamRequestParams {\n /**\n * Last event ID to resume from, if available\n */\n lastEventId?: string;\n\n /**\n * Optional reconnection path from the Location header\n */\n reconnectPath?: string;\n}\n\n/**\n * Error thrown when maximum reconnection attempts are exceeded.\n */\nexport class MaxReconnectAttemptsError extends Error {\n constructor(maxAttempts: number, cause: unknown) {\n super(`Exceeded maximum SSE reconnection attempts (${maxAttempts})`);\n this.name = \"MaxReconnectAttemptsError\";\n this.cause = cause;\n }\n}\n\n/**\n * Stream with automatic retry logic for SSE connections.\n * Implements reconnection behavior similar to the Python SDK.\n *\n * @param makeRequest Function to make requests. When `params` is undefined/empty, it's the initial request.\n * When `params.reconnectPath` is provided, it's a reconnection request.\n * @param options Configuration options\n * @returns AsyncGenerator yielding stream events\n */\nexport async function* streamWithRetry<T extends { id?: string }>(\n makeRequest: (params?: StreamRequestParams) => Promise<{\n response: Response;\n stream: ReadableStream<T>;\n }>,\n options: StreamWithRetryOptions = {}\n): AsyncGenerator<T> {\n const maxRetries = options.maxRetries ?? 5;\n let attempt = 0;\n let lastEventId: string | undefined;\n let reconnectPath: string | undefined;\n\n while (true) {\n let shouldRetry = false;\n let lastError: unknown;\n let reader: ReadableStreamDefaultReader<T> | undefined;\n\n try {\n // Check if aborted before making request\n if (options.signal?.aborted) return;\n\n // Make request - initial if no reconnect path, reconnect otherwise\n const { response, stream } = await makeRequest(\n reconnectPath ? { lastEventId, reconnectPath } : undefined\n );\n\n // Check for Location header (server-provided reconnection path)\n const locationHeader = response.headers.get(\"location\");\n if (locationHeader) {\n reconnectPath = locationHeader;\n }\n\n // Verify content type\n const contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n if (contentType && !contentType.includes(\"text/event-stream\")) {\n throw new Error(\n `Expected response header Content-Type to contain 'text/event-stream', got '${contentType}'`\n );\n }\n\n reader = stream.getReader();\n\n try {\n while (true) {\n // Check abort signal before each read\n if (options.signal?.aborted) {\n await reader.cancel();\n return;\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream completed successfully\n break;\n }\n\n // Track last event ID for reconnection\n if (value.id) {\n lastEventId = value.id;\n }\n\n yield value;\n }\n\n // Stream completed successfully, exit retry loop\n break;\n } catch (error) {\n // Error during streaming - attempt reconnect if we have a location header\n if (reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore errors when releasing lock\n }\n }\n }\n } catch (error) {\n lastError = error;\n\n // Only retry if we have reconnection capability and it's a network error\n if (isNetworkError(error) && reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n }\n\n if (shouldRetry) {\n attempt += 1;\n if (attempt > maxRetries) {\n throw new MaxReconnectAttemptsError(maxRetries, lastError);\n }\n\n // Notify about reconnection attempt\n options.onReconnect?.({ attempt, lastEventId, cause: lastError });\n\n // Exponential backoff with jitter: min(1000 * 2^attempt, 5000) + random jitter\n const baseDelay = Math.min(1000 * 2 ** (attempt - 1), 5000);\n const jitter = Math.random() * 1000;\n const delay = baseDelay + jitter;\n\n await new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n\n continue;\n }\n\n // Successfully completed\n break;\n }\n}\n\n/*\n * Support async iterator syntax for ReadableStreams in all environments.\n * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490\n */\nexport class IterableReadableStream<T>\n extends ReadableStream<T>\n implements IterableReadableStreamInterface<T>\n{\n public reader: ReadableStreamDefaultReader<T>;\n\n ensureReader() {\n if (!this.reader) {\n this.reader = this.getReader();\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n this.ensureReader();\n try {\n const result = await this.reader.read();\n if (result.done) {\n this.reader.releaseLock(); // release lock when stream becomes closed\n return {\n done: true,\n value: undefined,\n };\n } else {\n return {\n done: false,\n value: result.value,\n };\n }\n } catch (e) {\n this.reader.releaseLock(); // release lock when stream becomes errored\n throw e;\n }\n }\n\n async return(): Promise<IteratorResult<T>> {\n this.ensureReader();\n // If wrapped in a Node stream, cancel is already called.\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n return { done: true, value: undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async throw(e: any): Promise<IteratorResult<T>> {\n this.ensureReader();\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n throw e;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not present in Node 18 types, required in latest Node 22\n async [Symbol.asyncDispose]() {\n await this.return();\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n\n static fromReadableStream<T>(stream: ReadableStream<T>) {\n // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream\n const reader = stream.getReader();\n return new IterableReadableStream<T>({\n start(controller) {\n return pump();\n function pump(): Promise<T | undefined> {\n return reader.read().then(({ done, value }) => {\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n return;\n }\n // Enqueue the next data chunk into our target stream\n controller.enqueue(value);\n return pump();\n });\n }\n },\n cancel() {\n reader.releaseLock();\n },\n });\n }\n\n static fromAsyncGenerator<T>(generator: AsyncGenerator<T>) {\n return new IterableReadableStream<T>({\n async pull(controller) {\n const { value, done } = await generator.next();\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n }\n // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled\n controller.enqueue(value);\n },\n async cancel(reason) {\n await generator.return(reason);\n },\n });\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { isNetworkError } from "./error.js";
2
-
3
2
  //#region src/utils/stream.ts
4
3
  /**
5
4
  * Error thrown when maximum reconnection attempts are exceeded.
@@ -167,7 +166,7 @@ var IterableReadableStream = class IterableReadableStream extends ReadableStream
167
166
  });
168
167
  }
169
168
  };
170
-
171
169
  //#endregion
172
170
  export { IterableReadableStream, streamWithRetry };
171
+
173
172
  //# sourceMappingURL=stream.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.js","names":[],"sources":["../../src/utils/stream.ts"],"sourcesContent":["import { isNetworkError } from \"./error.js\";\n\n// in this case don't quite match.\ntype IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;\n\n/**\n * Options for streaming with automatic retry logic.\n */\nexport interface StreamWithRetryOptions {\n /**\n * Maximum number of reconnection attempts. Default is 5.\n */\n maxRetries?: number;\n\n /**\n * AbortSignal to cancel the stream.\n */\n signal?: AbortSignal;\n\n /**\n * Callback invoked when a reconnection attempt is made.\n */\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n}\n\n/**\n * Parameters for making a stream request\n */\nexport interface StreamRequestParams {\n /**\n * Last event ID to resume from, if available\n */\n lastEventId?: string;\n\n /**\n * Optional reconnection path from the Location header\n */\n reconnectPath?: string;\n}\n\n/**\n * Error thrown when maximum reconnection attempts are exceeded.\n */\nexport class MaxReconnectAttemptsError extends Error {\n constructor(maxAttempts: number, cause: unknown) {\n super(`Exceeded maximum SSE reconnection attempts (${maxAttempts})`);\n this.name = \"MaxReconnectAttemptsError\";\n this.cause = cause;\n }\n}\n\n/**\n * Stream with automatic retry logic for SSE connections.\n * Implements reconnection behavior similar to the Python SDK.\n *\n * @param makeRequest Function to make requests. When `params` is undefined/empty, it's the initial request.\n * When `params.reconnectPath` is provided, it's a reconnection request.\n * @param options Configuration options\n * @returns AsyncGenerator yielding stream events\n */\nexport async function* streamWithRetry<T extends { id?: string }>(\n makeRequest: (params?: StreamRequestParams) => Promise<{\n response: Response;\n stream: ReadableStream<T>;\n }>,\n options: StreamWithRetryOptions = {}\n): AsyncGenerator<T> {\n const maxRetries = options.maxRetries ?? 5;\n let attempt = 0;\n let lastEventId: string | undefined;\n let reconnectPath: string | undefined;\n\n while (true) {\n let shouldRetry = false;\n let lastError: unknown;\n let reader: ReadableStreamDefaultReader<T> | undefined;\n\n try {\n // Check if aborted before making request\n if (options.signal?.aborted) return;\n\n // Make request - initial if no reconnect path, reconnect otherwise\n const { response, stream } = await makeRequest(\n reconnectPath ? { lastEventId, reconnectPath } : undefined\n );\n\n // Check for Location header (server-provided reconnection path)\n const locationHeader = response.headers.get(\"location\");\n if (locationHeader) {\n reconnectPath = locationHeader;\n }\n\n // Verify content type\n const contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n if (contentType && !contentType.includes(\"text/event-stream\")) {\n throw new Error(\n `Expected response header Content-Type to contain 'text/event-stream', got '${contentType}'`\n );\n }\n\n reader = stream.getReader();\n\n try {\n while (true) {\n // Check abort signal before each read\n if (options.signal?.aborted) {\n await reader.cancel();\n return;\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream completed successfully\n break;\n }\n\n // Track last event ID for reconnection\n if (value.id) {\n lastEventId = value.id;\n }\n\n yield value;\n }\n\n // Stream completed successfully, exit retry loop\n break;\n } catch (error) {\n // Error during streaming - attempt reconnect if we have a location header\n if (reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore errors when releasing lock\n }\n }\n }\n } catch (error) {\n lastError = error;\n\n // Only retry if we have reconnection capability and it's a network error\n if (isNetworkError(error) && reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n }\n\n if (shouldRetry) {\n attempt += 1;\n if (attempt > maxRetries) {\n throw new MaxReconnectAttemptsError(maxRetries, lastError);\n }\n\n // Notify about reconnection attempt\n options.onReconnect?.({ attempt, lastEventId, cause: lastError });\n\n // Exponential backoff with jitter: min(1000 * 2^attempt, 5000) + random jitter\n const baseDelay = Math.min(1000 * 2 ** (attempt - 1), 5000);\n const jitter = Math.random() * 1000;\n const delay = baseDelay + jitter;\n\n await new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n\n continue;\n }\n\n // Successfully completed\n break;\n }\n}\n\n/*\n * Support async iterator syntax for ReadableStreams in all environments.\n * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490\n */\nexport class IterableReadableStream<T>\n extends ReadableStream<T>\n implements IterableReadableStreamInterface<T>\n{\n public reader: ReadableStreamDefaultReader<T>;\n\n ensureReader() {\n if (!this.reader) {\n this.reader = this.getReader();\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n this.ensureReader();\n try {\n const result = await this.reader.read();\n if (result.done) {\n this.reader.releaseLock(); // release lock when stream becomes closed\n return {\n done: true,\n value: undefined,\n };\n } else {\n return {\n done: false,\n value: result.value,\n };\n }\n } catch (e) {\n this.reader.releaseLock(); // release lock when stream becomes errored\n throw e;\n }\n }\n\n async return(): Promise<IteratorResult<T>> {\n this.ensureReader();\n // If wrapped in a Node stream, cancel is already called.\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n return { done: true, value: undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async throw(e: any): Promise<IteratorResult<T>> {\n this.ensureReader();\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n throw e;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not present in Node 18 types, required in latest Node 22\n async [Symbol.asyncDispose]() {\n await this.return();\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n\n static fromReadableStream<T>(stream: ReadableStream<T>) {\n // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream\n const reader = stream.getReader();\n return new IterableReadableStream<T>({\n start(controller) {\n return pump();\n function pump(): Promise<T | undefined> {\n return reader.read().then(({ done, value }) => {\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n return;\n }\n // Enqueue the next data chunk into our target stream\n controller.enqueue(value);\n return pump();\n });\n }\n },\n cancel() {\n reader.releaseLock();\n },\n });\n }\n\n static fromAsyncGenerator<T>(generator: AsyncGenerator<T>) {\n return new IterableReadableStream<T>({\n async pull(controller) {\n const { value, done } = await generator.next();\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n }\n // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled\n controller.enqueue(value);\n },\n async cancel(reason) {\n await generator.return(reason);\n },\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stream.js","names":[],"sources":["../../src/utils/stream.ts"],"sourcesContent":["import { isNetworkError } from \"./error.js\";\n\n// in this case don't quite match.\ntype IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;\n\n/**\n * Options for streaming with automatic retry logic.\n */\nexport interface StreamWithRetryOptions {\n /**\n * Maximum number of reconnection attempts. Default is 5.\n */\n maxRetries?: number;\n\n /**\n * AbortSignal to cancel the stream.\n */\n signal?: AbortSignal;\n\n /**\n * Callback invoked when a reconnection attempt is made.\n */\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n}\n\n/**\n * Parameters for making a stream request\n */\nexport interface StreamRequestParams {\n /**\n * Last event ID to resume from, if available\n */\n lastEventId?: string;\n\n /**\n * Optional reconnection path from the Location header\n */\n reconnectPath?: string;\n}\n\n/**\n * Error thrown when maximum reconnection attempts are exceeded.\n */\nexport class MaxReconnectAttemptsError extends Error {\n constructor(maxAttempts: number, cause: unknown) {\n super(`Exceeded maximum SSE reconnection attempts (${maxAttempts})`);\n this.name = \"MaxReconnectAttemptsError\";\n this.cause = cause;\n }\n}\n\n/**\n * Stream with automatic retry logic for SSE connections.\n * Implements reconnection behavior similar to the Python SDK.\n *\n * @param makeRequest Function to make requests. When `params` is undefined/empty, it's the initial request.\n * When `params.reconnectPath` is provided, it's a reconnection request.\n * @param options Configuration options\n * @returns AsyncGenerator yielding stream events\n */\nexport async function* streamWithRetry<T extends { id?: string }>(\n makeRequest: (params?: StreamRequestParams) => Promise<{\n response: Response;\n stream: ReadableStream<T>;\n }>,\n options: StreamWithRetryOptions = {}\n): AsyncGenerator<T> {\n const maxRetries = options.maxRetries ?? 5;\n let attempt = 0;\n let lastEventId: string | undefined;\n let reconnectPath: string | undefined;\n\n while (true) {\n let shouldRetry = false;\n let lastError: unknown;\n let reader: ReadableStreamDefaultReader<T> | undefined;\n\n try {\n // Check if aborted before making request\n if (options.signal?.aborted) return;\n\n // Make request - initial if no reconnect path, reconnect otherwise\n const { response, stream } = await makeRequest(\n reconnectPath ? { lastEventId, reconnectPath } : undefined\n );\n\n // Check for Location header (server-provided reconnection path)\n const locationHeader = response.headers.get(\"location\");\n if (locationHeader) {\n reconnectPath = locationHeader;\n }\n\n // Verify content type\n const contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n if (contentType && !contentType.includes(\"text/event-stream\")) {\n throw new Error(\n `Expected response header Content-Type to contain 'text/event-stream', got '${contentType}'`\n );\n }\n\n reader = stream.getReader();\n\n try {\n while (true) {\n // Check abort signal before each read\n if (options.signal?.aborted) {\n await reader.cancel();\n return;\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream completed successfully\n break;\n }\n\n // Track last event ID for reconnection\n if (value.id) {\n lastEventId = value.id;\n }\n\n yield value;\n }\n\n // Stream completed successfully, exit retry loop\n break;\n } catch (error) {\n // Error during streaming - attempt reconnect if we have a location header\n if (reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore errors when releasing lock\n }\n }\n }\n } catch (error) {\n lastError = error;\n\n // Only retry if we have reconnection capability and it's a network error\n if (isNetworkError(error) && reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n }\n\n if (shouldRetry) {\n attempt += 1;\n if (attempt > maxRetries) {\n throw new MaxReconnectAttemptsError(maxRetries, lastError);\n }\n\n // Notify about reconnection attempt\n options.onReconnect?.({ attempt, lastEventId, cause: lastError });\n\n // Exponential backoff with jitter: min(1000 * 2^attempt, 5000) + random jitter\n const baseDelay = Math.min(1000 * 2 ** (attempt - 1), 5000);\n const jitter = Math.random() * 1000;\n const delay = baseDelay + jitter;\n\n await new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n\n continue;\n }\n\n // Successfully completed\n break;\n }\n}\n\n/*\n * Support async iterator syntax for ReadableStreams in all environments.\n * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490\n */\nexport class IterableReadableStream<T>\n extends ReadableStream<T>\n implements IterableReadableStreamInterface<T>\n{\n public reader: ReadableStreamDefaultReader<T>;\n\n ensureReader() {\n if (!this.reader) {\n this.reader = this.getReader();\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n this.ensureReader();\n try {\n const result = await this.reader.read();\n if (result.done) {\n this.reader.releaseLock(); // release lock when stream becomes closed\n return {\n done: true,\n value: undefined,\n };\n } else {\n return {\n done: false,\n value: result.value,\n };\n }\n } catch (e) {\n this.reader.releaseLock(); // release lock when stream becomes errored\n throw e;\n }\n }\n\n async return(): Promise<IteratorResult<T>> {\n this.ensureReader();\n // If wrapped in a Node stream, cancel is already called.\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n return { done: true, value: undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async throw(e: any): Promise<IteratorResult<T>> {\n this.ensureReader();\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n throw e;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not present in Node 18 types, required in latest Node 22\n async [Symbol.asyncDispose]() {\n await this.return();\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n\n static fromReadableStream<T>(stream: ReadableStream<T>) {\n // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream\n const reader = stream.getReader();\n return new IterableReadableStream<T>({\n start(controller) {\n return pump();\n function pump(): Promise<T | undefined> {\n return reader.read().then(({ done, value }) => {\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n return;\n }\n // Enqueue the next data chunk into our target stream\n controller.enqueue(value);\n return pump();\n });\n }\n },\n cancel() {\n reader.releaseLock();\n },\n });\n }\n\n static fromAsyncGenerator<T>(generator: AsyncGenerator<T>) {\n return new IterableReadableStream<T>({\n async pull(controller) {\n const { value, done } = await generator.next();\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n }\n // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled\n controller.enqueue(value);\n },\n async cancel(reason) {\n await generator.return(reason);\n },\n });\n }\n}\n"],"mappings":";;;;;AA+CA,IAAa,4BAAb,cAA+C,MAAM;CACnD,YAAY,aAAqB,OAAgB;AAC/C,QAAM,+CAA+C,YAAY,GAAG;AACpE,OAAK,OAAO;AACZ,OAAK,QAAQ;;;;;;;;;;;;AAajB,gBAAuB,gBACrB,aAIA,UAAkC,EAAE,EACjB;CACnB,MAAM,aAAa,QAAQ,cAAc;CACzC,IAAI,UAAU;CACd,IAAI;CACJ,IAAI;AAEJ,QAAO,MAAM;EACX,IAAI,cAAc;EAClB,IAAI;EACJ,IAAI;AAEJ,MAAI;AAEF,OAAI,QAAQ,QAAQ,QAAS;GAG7B,MAAM,EAAE,UAAU,WAAW,MAAM,YACjC,gBAAgB;IAAE;IAAa;IAAe,GAAG,KAAA,EAClD;GAGD,MAAM,iBAAiB,SAAS,QAAQ,IAAI,WAAW;AACvD,OAAI,eACF,iBAAgB;GAIlB,MAAM,cAAc,SAAS,QAAQ,IAAI,eAAe,EAAE,MAAM,IAAI,CAAC;AACrE,OAAI,eAAe,CAAC,YAAY,SAAS,oBAAoB,CAC3D,OAAM,IAAI,MACR,8EAA8E,YAAY,GAC3F;AAGH,YAAS,OAAO,WAAW;AAE3B,OAAI;AACF,WAAO,MAAM;AAEX,SAAI,QAAQ,QAAQ,SAAS;AAC3B,YAAM,OAAO,QAAQ;AACrB;;KAGF,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAE3C,SAAI,KAEF;AAIF,SAAI,MAAM,GACR,eAAc,MAAM;AAGtB,WAAM;;AAIR;YACO,OAAO;AAEd,QAAI,iBAAiB,CAAC,QAAQ,QAAQ,QACpC,eAAc;QAEd,OAAM;aAEA;AACR,QAAI,OACF,KAAI;AACF,YAAO,aAAa;YACd;;WAKL,OAAO;AACd,eAAY;AAGZ,OAAI,eAAe,MAAM,IAAI,iBAAiB,CAAC,QAAQ,QAAQ,QAC7D,eAAc;OAEd,OAAM;;AAIV,MAAI,aAAa;AACf,cAAW;AACX,OAAI,UAAU,WACZ,OAAM,IAAI,0BAA0B,YAAY,UAAU;AAI5D,WAAQ,cAAc;IAAE;IAAS;IAAa,OAAO;IAAW,CAAC;GAKjE,MAAM,QAFY,KAAK,IAAI,MAAO,MAAM,UAAU,IAAI,IAAK,GAC5C,KAAK,QAAQ,GAAG;AAG/B,SAAM,IAAI,SAAS,YAAY;AAC7B,eAAW,SAAS,MAAM;KAC1B;AAEF;;AAIF;;;AAQJ,IAAa,yBAAb,MAAa,+BACH,eAEV;CACE;CAEA,eAAe;AACb,MAAI,CAAC,KAAK,OACR,MAAK,SAAS,KAAK,WAAW;;CAIlC,MAAM,OAAmC;AACvC,OAAK,cAAc;AACnB,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,OAAO,MAAM;AACvC,OAAI,OAAO,MAAM;AACf,SAAK,OAAO,aAAa;AACzB,WAAO;KACL,MAAM;KACN,OAAO,KAAA;KACR;SAED,QAAO;IACL,MAAM;IACN,OAAO,OAAO;IACf;WAEI,GAAG;AACV,QAAK,OAAO,aAAa;AACzB,SAAM;;;CAIV,MAAM,SAAqC;AACzC,OAAK,cAAc;AAEnB,MAAI,KAAK,QAAQ;GACf,MAAM,gBAAgB,KAAK,OAAO,QAAQ;AAC1C,QAAK,OAAO,aAAa;AACzB,SAAM;;AAER,SAAO;GAAE,MAAM;GAAM,OAAO,KAAA;GAAW;;CAIzC,MAAM,MAAM,GAAoC;AAC9C,OAAK,cAAc;AACnB,MAAI,KAAK,QAAQ;GACf,MAAM,gBAAgB,KAAK,OAAO,QAAQ;AAC1C,QAAK,OAAO,aAAa;AACzB,SAAM;;AAER,QAAM;;CAKR,OAAO,OAAO,gBAAgB;AAC5B,QAAM,KAAK,QAAQ;;CAGrB,CAAC,OAAO,iBAAiB;AACvB,SAAO;;CAGT,OAAO,mBAAsB,QAA2B;EAEtD,MAAM,SAAS,OAAO,WAAW;AACjC,SAAO,IAAI,uBAA0B;GACnC,MAAM,YAAY;AAChB,WAAO,MAAM;IACb,SAAS,OAA+B;AACtC,YAAO,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,YAAY;AAE7C,UAAI,MAAM;AACR,kBAAW,OAAO;AAClB;;AAGF,iBAAW,QAAQ,MAAM;AACzB,aAAO,MAAM;OACb;;;GAGN,SAAS;AACP,WAAO,aAAa;;GAEvB,CAAC;;CAGJ,OAAO,mBAAsB,WAA8B;AACzD,SAAO,IAAI,uBAA0B;GACnC,MAAM,KAAK,YAAY;IACrB,MAAM,EAAE,OAAO,SAAS,MAAM,UAAU,MAAM;AAE9C,QAAI,KACF,YAAW,OAAO;AAGpB,eAAW,QAAQ,MAAM;;GAE3B,MAAM,OAAO,QAAQ;AACnB,UAAM,UAAU,OAAO,OAAO;;GAEjC,CAAC"}
@@ -1,4 +1,3 @@
1
-
2
1
  //#region src/utils/tools.ts
3
2
  /**
4
3
  * Extracts tool calls with their results from a list of messages.
@@ -55,7 +54,7 @@ function getToolCallsWithResults(messages) {
55
54
  }
56
55
  return results;
57
56
  }
58
-
59
57
  //#endregion
60
58
  exports.getToolCallsWithResults = getToolCallsWithResults;
59
+
61
60
  //# sourceMappingURL=tools.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.cjs","names":[],"sources":["../../src/utils/tools.ts"],"sourcesContent":["import type {\n Message,\n AIMessage,\n ToolMessage,\n ToolCallState,\n ToolCallWithResult,\n DefaultToolCall,\n} from \"../types.messages.js\";\n\n/**\n * Extracts tool calls with their results from a list of messages.\n *\n * @template ToolCall The type of tool calls.\n * @param messages The list of messages to extract tool calls from.\n * @returns An array of ToolCallWithResult objects.\n *\n * @example\n * ```ts\n * const toolCalls = getToolCallsWithResults(messages);\n * for (const { call, result } of toolCalls) {\n * if (call.name === \"get_weather\") {\n * console.log(`Weather for ${call.args.location}:`, result?.content);\n * }\n * }\n * ```\n */\n/**\n * Computes the lifecycle state of a tool call based on its result.\n */\nfunction computeToolCallState(\n result: ToolMessage | undefined,\n impliedCompleted: boolean\n): ToolCallState {\n if (result) return result.status === \"error\" ? \"error\" : \"completed\";\n if (impliedCompleted) return \"completed\";\n return \"pending\";\n}\n\nexport function getToolCallsWithResults<ToolCall = DefaultToolCall>(\n messages: Message<ToolCall>[]\n): ToolCallWithResult<ToolCall>[] {\n const results: ToolCallWithResult<ToolCall>[] = [];\n\n // Create a map of tool_call_id to ToolMessage for quick lookup\n const toolResultsById = new Map<string, ToolMessage>();\n for (const msg of messages) {\n if (msg.type === \"tool\") {\n toolResultsById.set(msg.tool_call_id, msg);\n }\n }\n\n // Find all AI messages with tool calls and pair them with results.\n // For each, independently check if there's a subsequent AI message,\n // which implies the tools completed (handles tools returning Commands\n // where ToolMessages are embedded in the state update rather than streamed).\n for (let msgIdx = 0; msgIdx < messages.length; msgIdx += 1) {\n const msg = messages[msgIdx];\n if (msg.type === \"ai\" && msg.tool_calls && msg.tool_calls.length > 0) {\n const aiMessage = msg as AIMessage<ToolCall>;\n\n let impliedCompleted = false;\n for (let j = msgIdx + 1; j < messages.length; j += 1) {\n if (messages[j].type === \"ai\") {\n impliedCompleted = true;\n break;\n }\n }\n\n for (let i = 0; i < aiMessage.tool_calls!.length; i += 1) {\n const call = aiMessage.tool_calls![i] as ToolCall & { id?: string };\n const callId = call.id as string | undefined;\n const result = callId ? toolResultsById.get(callId) : undefined;\n\n results.push({\n id: callId ?? `${aiMessage.id ?? \"unknown\"}-${i}`,\n call,\n result,\n aiMessage,\n index: i,\n state: computeToolCallState(result, impliedCompleted),\n });\n }\n }\n }\n\n return results;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAS,qBACP,QACA,kBACe;AACf,KAAI,OAAQ,QAAO,OAAO,WAAW,UAAU,UAAU;AACzD,KAAI,iBAAkB,QAAO;AAC7B,QAAO;;AAGT,SAAgB,wBACd,UACgC;CAChC,MAAM,UAA0C,EAAE;CAGlD,MAAM,kCAAkB,IAAI,KAA0B;AACtD,MAAK,MAAM,OAAO,SAChB,KAAI,IAAI,SAAS,OACf,iBAAgB,IAAI,IAAI,cAAc,IAAI;AAQ9C,MAAK,IAAI,SAAS,GAAG,SAAS,SAAS,QAAQ,UAAU,GAAG;EAC1D,MAAM,MAAM,SAAS;AACrB,MAAI,IAAI,SAAS,QAAQ,IAAI,cAAc,IAAI,WAAW,SAAS,GAAG;GACpE,MAAM,YAAY;GAElB,IAAI,mBAAmB;AACvB,QAAK,IAAI,IAAI,SAAS,GAAG,IAAI,SAAS,QAAQ,KAAK,EACjD,KAAI,SAAS,GAAG,SAAS,MAAM;AAC7B,uBAAmB;AACnB;;AAIJ,QAAK,IAAI,IAAI,GAAG,IAAI,UAAU,WAAY,QAAQ,KAAK,GAAG;IACxD,MAAM,OAAO,UAAU,WAAY;IACnC,MAAM,SAAS,KAAK;IACpB,MAAM,SAAS,SAAS,gBAAgB,IAAI,OAAO,GAAG;AAEtD,YAAQ,KAAK;KACX,IAAI,UAAU,GAAG,UAAU,MAAM,UAAU,GAAG;KAC9C;KACA;KACA;KACA,OAAO;KACP,OAAO,qBAAqB,QAAQ,iBAAiB;KACtD,CAAC;;;;AAKR,QAAO"}
1
+ {"version":3,"file":"tools.cjs","names":[],"sources":["../../src/utils/tools.ts"],"sourcesContent":["import type {\n Message,\n AIMessage,\n ToolMessage,\n ToolCallState,\n ToolCallWithResult,\n DefaultToolCall,\n} from \"../types.messages.js\";\n\n/**\n * Extracts tool calls with their results from a list of messages.\n *\n * @template ToolCall The type of tool calls.\n * @param messages The list of messages to extract tool calls from.\n * @returns An array of ToolCallWithResult objects.\n *\n * @example\n * ```ts\n * const toolCalls = getToolCallsWithResults(messages);\n * for (const { call, result } of toolCalls) {\n * if (call.name === \"get_weather\") {\n * console.log(`Weather for ${call.args.location}:`, result?.content);\n * }\n * }\n * ```\n */\n/**\n * Computes the lifecycle state of a tool call based on its result.\n */\nfunction computeToolCallState(\n result: ToolMessage | undefined,\n impliedCompleted: boolean\n): ToolCallState {\n if (result) return result.status === \"error\" ? \"error\" : \"completed\";\n if (impliedCompleted) return \"completed\";\n return \"pending\";\n}\n\nexport function getToolCallsWithResults<ToolCall = DefaultToolCall>(\n messages: Message<ToolCall>[]\n): ToolCallWithResult<ToolCall>[] {\n const results: ToolCallWithResult<ToolCall>[] = [];\n\n // Create a map of tool_call_id to ToolMessage for quick lookup\n const toolResultsById = new Map<string, ToolMessage>();\n for (const msg of messages) {\n if (msg.type === \"tool\") {\n toolResultsById.set(msg.tool_call_id, msg);\n }\n }\n\n // Find all AI messages with tool calls and pair them with results.\n // For each, independently check if there's a subsequent AI message,\n // which implies the tools completed (handles tools returning Commands\n // where ToolMessages are embedded in the state update rather than streamed).\n for (let msgIdx = 0; msgIdx < messages.length; msgIdx += 1) {\n const msg = messages[msgIdx];\n if (msg.type === \"ai\" && msg.tool_calls && msg.tool_calls.length > 0) {\n const aiMessage = msg as AIMessage<ToolCall>;\n\n let impliedCompleted = false;\n for (let j = msgIdx + 1; j < messages.length; j += 1) {\n if (messages[j].type === \"ai\") {\n impliedCompleted = true;\n break;\n }\n }\n\n for (let i = 0; i < aiMessage.tool_calls!.length; i += 1) {\n const call = aiMessage.tool_calls![i] as ToolCall & { id?: string };\n const callId = call.id as string | undefined;\n const result = callId ? toolResultsById.get(callId) : undefined;\n\n results.push({\n id: callId ?? `${aiMessage.id ?? \"unknown\"}-${i}`,\n call,\n result,\n aiMessage,\n index: i,\n state: computeToolCallState(result, impliedCompleted),\n });\n }\n }\n }\n\n return results;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,SAAS,qBACP,QACA,kBACe;AACf,KAAI,OAAQ,QAAO,OAAO,WAAW,UAAU,UAAU;AACzD,KAAI,iBAAkB,QAAO;AAC7B,QAAO;;AAGT,SAAgB,wBACd,UACgC;CAChC,MAAM,UAA0C,EAAE;CAGlD,MAAM,kCAAkB,IAAI,KAA0B;AACtD,MAAK,MAAM,OAAO,SAChB,KAAI,IAAI,SAAS,OACf,iBAAgB,IAAI,IAAI,cAAc,IAAI;AAQ9C,MAAK,IAAI,SAAS,GAAG,SAAS,SAAS,QAAQ,UAAU,GAAG;EAC1D,MAAM,MAAM,SAAS;AACrB,MAAI,IAAI,SAAS,QAAQ,IAAI,cAAc,IAAI,WAAW,SAAS,GAAG;GACpE,MAAM,YAAY;GAElB,IAAI,mBAAmB;AACvB,QAAK,IAAI,IAAI,SAAS,GAAG,IAAI,SAAS,QAAQ,KAAK,EACjD,KAAI,SAAS,GAAG,SAAS,MAAM;AAC7B,uBAAmB;AACnB;;AAIJ,QAAK,IAAI,IAAI,GAAG,IAAI,UAAU,WAAY,QAAQ,KAAK,GAAG;IACxD,MAAM,OAAO,UAAU,WAAY;IACnC,MAAM,SAAS,KAAK;IACpB,MAAM,SAAS,SAAS,gBAAgB,IAAI,OAAO,GAAG,KAAA;AAEtD,YAAQ,KAAK;KACX,IAAI,UAAU,GAAG,UAAU,MAAM,UAAU,GAAG;KAC9C;KACA;KACA;KACA,OAAO;KACP,OAAO,qBAAqB,QAAQ,iBAAiB;KACtD,CAAC;;;;AAKR,QAAO"}
@@ -54,7 +54,7 @@ function getToolCallsWithResults(messages) {
54
54
  }
55
55
  return results;
56
56
  }
57
-
58
57
  //#endregion
59
58
  export { getToolCallsWithResults };
59
+
60
60
  //# sourceMappingURL=tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","names":[],"sources":["../../src/utils/tools.ts"],"sourcesContent":["import type {\n Message,\n AIMessage,\n ToolMessage,\n ToolCallState,\n ToolCallWithResult,\n DefaultToolCall,\n} from \"../types.messages.js\";\n\n/**\n * Extracts tool calls with their results from a list of messages.\n *\n * @template ToolCall The type of tool calls.\n * @param messages The list of messages to extract tool calls from.\n * @returns An array of ToolCallWithResult objects.\n *\n * @example\n * ```ts\n * const toolCalls = getToolCallsWithResults(messages);\n * for (const { call, result } of toolCalls) {\n * if (call.name === \"get_weather\") {\n * console.log(`Weather for ${call.args.location}:`, result?.content);\n * }\n * }\n * ```\n */\n/**\n * Computes the lifecycle state of a tool call based on its result.\n */\nfunction computeToolCallState(\n result: ToolMessage | undefined,\n impliedCompleted: boolean\n): ToolCallState {\n if (result) return result.status === \"error\" ? \"error\" : \"completed\";\n if (impliedCompleted) return \"completed\";\n return \"pending\";\n}\n\nexport function getToolCallsWithResults<ToolCall = DefaultToolCall>(\n messages: Message<ToolCall>[]\n): ToolCallWithResult<ToolCall>[] {\n const results: ToolCallWithResult<ToolCall>[] = [];\n\n // Create a map of tool_call_id to ToolMessage for quick lookup\n const toolResultsById = new Map<string, ToolMessage>();\n for (const msg of messages) {\n if (msg.type === \"tool\") {\n toolResultsById.set(msg.tool_call_id, msg);\n }\n }\n\n // Find all AI messages with tool calls and pair them with results.\n // For each, independently check if there's a subsequent AI message,\n // which implies the tools completed (handles tools returning Commands\n // where ToolMessages are embedded in the state update rather than streamed).\n for (let msgIdx = 0; msgIdx < messages.length; msgIdx += 1) {\n const msg = messages[msgIdx];\n if (msg.type === \"ai\" && msg.tool_calls && msg.tool_calls.length > 0) {\n const aiMessage = msg as AIMessage<ToolCall>;\n\n let impliedCompleted = false;\n for (let j = msgIdx + 1; j < messages.length; j += 1) {\n if (messages[j].type === \"ai\") {\n impliedCompleted = true;\n break;\n }\n }\n\n for (let i = 0; i < aiMessage.tool_calls!.length; i += 1) {\n const call = aiMessage.tool_calls![i] as ToolCall & { id?: string };\n const callId = call.id as string | undefined;\n const result = callId ? toolResultsById.get(callId) : undefined;\n\n results.push({\n id: callId ?? `${aiMessage.id ?? \"unknown\"}-${i}`,\n call,\n result,\n aiMessage,\n index: i,\n state: computeToolCallState(result, impliedCompleted),\n });\n }\n }\n }\n\n return results;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,SAAS,qBACP,QACA,kBACe;AACf,KAAI,OAAQ,QAAO,OAAO,WAAW,UAAU,UAAU;AACzD,KAAI,iBAAkB,QAAO;AAC7B,QAAO;;AAGT,SAAgB,wBACd,UACgC;CAChC,MAAM,UAA0C,EAAE;CAGlD,MAAM,kCAAkB,IAAI,KAA0B;AACtD,MAAK,MAAM,OAAO,SAChB,KAAI,IAAI,SAAS,OACf,iBAAgB,IAAI,IAAI,cAAc,IAAI;AAQ9C,MAAK,IAAI,SAAS,GAAG,SAAS,SAAS,QAAQ,UAAU,GAAG;EAC1D,MAAM,MAAM,SAAS;AACrB,MAAI,IAAI,SAAS,QAAQ,IAAI,cAAc,IAAI,WAAW,SAAS,GAAG;GACpE,MAAM,YAAY;GAElB,IAAI,mBAAmB;AACvB,QAAK,IAAI,IAAI,SAAS,GAAG,IAAI,SAAS,QAAQ,KAAK,EACjD,KAAI,SAAS,GAAG,SAAS,MAAM;AAC7B,uBAAmB;AACnB;;AAIJ,QAAK,IAAI,IAAI,GAAG,IAAI,UAAU,WAAY,QAAQ,KAAK,GAAG;IACxD,MAAM,OAAO,UAAU,WAAY;IACnC,MAAM,SAAS,KAAK;IACpB,MAAM,SAAS,SAAS,gBAAgB,IAAI,OAAO,GAAG;AAEtD,YAAQ,KAAK;KACX,IAAI,UAAU,GAAG,UAAU,MAAM,UAAU,GAAG;KAC9C;KACA;KACA;KACA,OAAO;KACP,OAAO,qBAAqB,QAAQ,iBAAiB;KACtD,CAAC;;;;AAKR,QAAO"}
1
+ {"version":3,"file":"tools.js","names":[],"sources":["../../src/utils/tools.ts"],"sourcesContent":["import type {\n Message,\n AIMessage,\n ToolMessage,\n ToolCallState,\n ToolCallWithResult,\n DefaultToolCall,\n} from \"../types.messages.js\";\n\n/**\n * Extracts tool calls with their results from a list of messages.\n *\n * @template ToolCall The type of tool calls.\n * @param messages The list of messages to extract tool calls from.\n * @returns An array of ToolCallWithResult objects.\n *\n * @example\n * ```ts\n * const toolCalls = getToolCallsWithResults(messages);\n * for (const { call, result } of toolCalls) {\n * if (call.name === \"get_weather\") {\n * console.log(`Weather for ${call.args.location}:`, result?.content);\n * }\n * }\n * ```\n */\n/**\n * Computes the lifecycle state of a tool call based on its result.\n */\nfunction computeToolCallState(\n result: ToolMessage | undefined,\n impliedCompleted: boolean\n): ToolCallState {\n if (result) return result.status === \"error\" ? \"error\" : \"completed\";\n if (impliedCompleted) return \"completed\";\n return \"pending\";\n}\n\nexport function getToolCallsWithResults<ToolCall = DefaultToolCall>(\n messages: Message<ToolCall>[]\n): ToolCallWithResult<ToolCall>[] {\n const results: ToolCallWithResult<ToolCall>[] = [];\n\n // Create a map of tool_call_id to ToolMessage for quick lookup\n const toolResultsById = new Map<string, ToolMessage>();\n for (const msg of messages) {\n if (msg.type === \"tool\") {\n toolResultsById.set(msg.tool_call_id, msg);\n }\n }\n\n // Find all AI messages with tool calls and pair them with results.\n // For each, independently check if there's a subsequent AI message,\n // which implies the tools completed (handles tools returning Commands\n // where ToolMessages are embedded in the state update rather than streamed).\n for (let msgIdx = 0; msgIdx < messages.length; msgIdx += 1) {\n const msg = messages[msgIdx];\n if (msg.type === \"ai\" && msg.tool_calls && msg.tool_calls.length > 0) {\n const aiMessage = msg as AIMessage<ToolCall>;\n\n let impliedCompleted = false;\n for (let j = msgIdx + 1; j < messages.length; j += 1) {\n if (messages[j].type === \"ai\") {\n impliedCompleted = true;\n break;\n }\n }\n\n for (let i = 0; i < aiMessage.tool_calls!.length; i += 1) {\n const call = aiMessage.tool_calls![i] as ToolCall & { id?: string };\n const callId = call.id as string | undefined;\n const result = callId ? toolResultsById.get(callId) : undefined;\n\n results.push({\n id: callId ?? `${aiMessage.id ?? \"unknown\"}-${i}`,\n call,\n result,\n aiMessage,\n index: i,\n state: computeToolCallState(result, impliedCompleted),\n });\n }\n }\n }\n\n return results;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,SAAS,qBACP,QACA,kBACe;AACf,KAAI,OAAQ,QAAO,OAAO,WAAW,UAAU,UAAU;AACzD,KAAI,iBAAkB,QAAO;AAC7B,QAAO;;AAGT,SAAgB,wBACd,UACgC;CAChC,MAAM,UAA0C,EAAE;CAGlD,MAAM,kCAAkB,IAAI,KAA0B;AACtD,MAAK,MAAM,OAAO,SAChB,KAAI,IAAI,SAAS,OACf,iBAAgB,IAAI,IAAI,cAAc,IAAI;AAQ9C,MAAK,IAAI,SAAS,GAAG,SAAS,SAAS,QAAQ,UAAU,GAAG;EAC1D,MAAM,MAAM,SAAS;AACrB,MAAI,IAAI,SAAS,QAAQ,IAAI,cAAc,IAAI,WAAW,SAAS,GAAG;GACpE,MAAM,YAAY;GAElB,IAAI,mBAAmB;AACvB,QAAK,IAAI,IAAI,SAAS,GAAG,IAAI,SAAS,QAAQ,KAAK,EACjD,KAAI,SAAS,GAAG,SAAS,MAAM;AAC7B,uBAAmB;AACnB;;AAIJ,QAAK,IAAI,IAAI,GAAG,IAAI,UAAU,WAAY,QAAQ,KAAK,GAAG;IACxD,MAAM,OAAO,UAAU,WAAY;IACnC,MAAM,SAAS,KAAK;IACpB,MAAM,SAAS,SAAS,gBAAgB,IAAI,OAAO,GAAG,KAAA;AAEtD,YAAQ,KAAK;KACX,IAAI,UAAU,GAAG,UAAU,MAAM,UAAU,GAAG;KAC9C;KACA;KACA;KACA,OAAO;KACP,OAAO,qBAAqB,QAAQ,iBAAiB;KACtD,CAAC;;;;AAKR,QAAO"}