@clinebot/llms 0.0.18 → 0.0.21

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 (319) hide show
  1. package/dist/config-browser.d.ts +1 -0
  2. package/dist/config-browser.d.ts.map +1 -0
  3. package/dist/config.d.ts +1 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/index.browser.d.ts +1 -0
  6. package/dist/index.browser.d.ts.map +1 -0
  7. package/dist/index.browser.js +5 -5
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +12 -12
  11. package/dist/models/generated-access.d.ts +1 -0
  12. package/dist/models/generated-access.d.ts.map +1 -0
  13. package/dist/models/generated-provider-loaders.d.ts +1 -0
  14. package/dist/models/generated-provider-loaders.d.ts.map +1 -0
  15. package/dist/models/generated.d.ts +1 -0
  16. package/dist/models/generated.d.ts.map +1 -0
  17. package/dist/models/index.d.ts +1 -0
  18. package/dist/models/index.d.ts.map +1 -0
  19. package/dist/models/models-dev-catalog.d.ts +1 -0
  20. package/dist/models/models-dev-catalog.d.ts.map +1 -0
  21. package/dist/models/providers/aihubmix.d.ts +1 -0
  22. package/dist/models/providers/aihubmix.d.ts.map +1 -0
  23. package/dist/models/providers/anthropic.d.ts +1 -0
  24. package/dist/models/providers/anthropic.d.ts.map +1 -0
  25. package/dist/models/providers/asksage.d.ts +1 -0
  26. package/dist/models/providers/asksage.d.ts.map +1 -0
  27. package/dist/models/providers/baseten.d.ts +1 -0
  28. package/dist/models/providers/baseten.d.ts.map +1 -0
  29. package/dist/models/providers/bedrock.d.ts +1 -0
  30. package/dist/models/providers/bedrock.d.ts.map +1 -0
  31. package/dist/models/providers/cerebras.d.ts +1 -0
  32. package/dist/models/providers/cerebras.d.ts.map +1 -0
  33. package/dist/models/providers/claude-code.d.ts +1 -0
  34. package/dist/models/providers/claude-code.d.ts.map +1 -0
  35. package/dist/models/providers/cline.d.ts +1 -0
  36. package/dist/models/providers/cline.d.ts.map +1 -0
  37. package/dist/models/providers/deepseek.d.ts +1 -0
  38. package/dist/models/providers/deepseek.d.ts.map +1 -0
  39. package/dist/models/providers/dify.d.ts +1 -0
  40. package/dist/models/providers/dify.d.ts.map +1 -0
  41. package/dist/models/providers/doubao.d.ts +1 -0
  42. package/dist/models/providers/doubao.d.ts.map +1 -0
  43. package/dist/models/providers/fireworks.d.ts +1 -0
  44. package/dist/models/providers/fireworks.d.ts.map +1 -0
  45. package/dist/models/providers/gemini.d.ts +1 -0
  46. package/dist/models/providers/gemini.d.ts.map +1 -0
  47. package/dist/models/providers/groq.d.ts +1 -0
  48. package/dist/models/providers/groq.d.ts.map +1 -0
  49. package/dist/models/providers/hicap.d.ts +1 -0
  50. package/dist/models/providers/hicap.d.ts.map +1 -0
  51. package/dist/models/providers/huawei-cloud-maas.d.ts +1 -0
  52. package/dist/models/providers/huawei-cloud-maas.d.ts.map +1 -0
  53. package/dist/models/providers/huggingface.d.ts +1 -0
  54. package/dist/models/providers/huggingface.d.ts.map +1 -0
  55. package/dist/models/providers/index.d.ts +1 -0
  56. package/dist/models/providers/index.d.ts.map +1 -0
  57. package/dist/models/providers/litellm.d.ts +1 -0
  58. package/dist/models/providers/litellm.d.ts.map +1 -0
  59. package/dist/models/providers/lmstudio.d.ts +1 -0
  60. package/dist/models/providers/lmstudio.d.ts.map +1 -0
  61. package/dist/models/providers/minimax.d.ts +1 -0
  62. package/dist/models/providers/minimax.d.ts.map +1 -0
  63. package/dist/models/providers/mistral.d.ts +1 -0
  64. package/dist/models/providers/mistral.d.ts.map +1 -0
  65. package/dist/models/providers/moonshot.d.ts +1 -0
  66. package/dist/models/providers/moonshot.d.ts.map +1 -0
  67. package/dist/models/providers/nebius.d.ts +1 -0
  68. package/dist/models/providers/nebius.d.ts.map +1 -0
  69. package/dist/models/providers/nous-research.d.ts +1 -0
  70. package/dist/models/providers/nous-research.d.ts.map +1 -0
  71. package/dist/models/providers/oca.d.ts +1 -0
  72. package/dist/models/providers/oca.d.ts.map +1 -0
  73. package/dist/models/providers/ollama.d.ts +1 -0
  74. package/dist/models/providers/ollama.d.ts.map +1 -0
  75. package/dist/models/providers/openai-codex.d.ts +1 -0
  76. package/dist/models/providers/openai-codex.d.ts.map +1 -0
  77. package/dist/models/providers/openai.d.ts +1 -0
  78. package/dist/models/providers/openai.d.ts.map +1 -0
  79. package/dist/models/providers/opencode.d.ts +1 -0
  80. package/dist/models/providers/opencode.d.ts.map +1 -0
  81. package/dist/models/providers/openrouter.d.ts +1 -0
  82. package/dist/models/providers/openrouter.d.ts.map +1 -0
  83. package/dist/models/providers/qwen-code.d.ts +1 -0
  84. package/dist/models/providers/qwen-code.d.ts.map +1 -0
  85. package/dist/models/providers/qwen.d.ts +1 -0
  86. package/dist/models/providers/qwen.d.ts.map +1 -0
  87. package/dist/models/providers/requesty.d.ts +1 -0
  88. package/dist/models/providers/requesty.d.ts.map +1 -0
  89. package/dist/models/providers/sambanova.d.ts +1 -0
  90. package/dist/models/providers/sambanova.d.ts.map +1 -0
  91. package/dist/models/providers/sapaicore.d.ts +1 -0
  92. package/dist/models/providers/sapaicore.d.ts.map +1 -0
  93. package/dist/models/providers/together.d.ts +1 -0
  94. package/dist/models/providers/together.d.ts.map +1 -0
  95. package/dist/models/providers/vercel-ai-gateway.d.ts +1 -0
  96. package/dist/models/providers/vercel-ai-gateway.d.ts.map +1 -0
  97. package/dist/models/providers/vertex.d.ts +1 -0
  98. package/dist/models/providers/vertex.d.ts.map +1 -0
  99. package/dist/models/providers/xai.d.ts +1 -0
  100. package/dist/models/providers/xai.d.ts.map +1 -0
  101. package/dist/models/providers/zai.d.ts +1 -0
  102. package/dist/models/providers/zai.d.ts.map +1 -0
  103. package/dist/models/query.d.ts +1 -0
  104. package/dist/models/query.d.ts.map +1 -0
  105. package/dist/models/registry.d.ts +1 -0
  106. package/dist/models/registry.d.ts.map +1 -0
  107. package/dist/models/schemas/index.d.ts +1 -0
  108. package/dist/models/schemas/index.d.ts.map +1 -0
  109. package/dist/models/schemas/model.d.ts +1 -0
  110. package/dist/models/schemas/model.d.ts.map +1 -0
  111. package/dist/models/schemas/query.d.ts +1 -0
  112. package/dist/models/schemas/query.d.ts.map +1 -0
  113. package/dist/providers/handlers/ai-sdk-community.d.ts +1 -0
  114. package/dist/providers/handlers/ai-sdk-community.d.ts.map +1 -0
  115. package/dist/providers/handlers/ai-sdk-provider-base.d.ts +1 -0
  116. package/dist/providers/handlers/ai-sdk-provider-base.d.ts.map +1 -0
  117. package/dist/providers/handlers/anthropic-base.d.ts +1 -0
  118. package/dist/providers/handlers/anthropic-base.d.ts.map +1 -0
  119. package/dist/providers/handlers/asksage.d.ts +1 -0
  120. package/dist/providers/handlers/asksage.d.ts.map +1 -0
  121. package/dist/providers/handlers/auth.d.ts +1 -0
  122. package/dist/providers/handlers/auth.d.ts.map +1 -0
  123. package/dist/providers/handlers/base.d.ts +1 -0
  124. package/dist/providers/handlers/base.d.ts.map +1 -0
  125. package/dist/providers/handlers/bedrock-base.d.ts +1 -0
  126. package/dist/providers/handlers/bedrock-base.d.ts.map +1 -0
  127. package/dist/providers/handlers/bedrock-client.d.ts +1 -0
  128. package/dist/providers/handlers/bedrock-client.d.ts.map +1 -0
  129. package/dist/providers/handlers/community-sdk.d.ts +1 -0
  130. package/dist/providers/handlers/community-sdk.d.ts.map +1 -0
  131. package/dist/providers/handlers/fetch-base.d.ts +1 -0
  132. package/dist/providers/handlers/fetch-base.d.ts.map +1 -0
  133. package/dist/providers/handlers/gemini-base.d.ts +1 -0
  134. package/dist/providers/handlers/gemini-base.d.ts.map +1 -0
  135. package/dist/providers/handlers/index.d.ts +1 -0
  136. package/dist/providers/handlers/index.d.ts.map +1 -0
  137. package/dist/providers/handlers/openai-base.d.ts +1 -0
  138. package/dist/providers/handlers/openai-base.d.ts.map +1 -0
  139. package/dist/providers/handlers/openai-responses.d.ts +1 -0
  140. package/dist/providers/handlers/openai-responses.d.ts.map +1 -0
  141. package/dist/providers/handlers/providers.d.ts +1 -0
  142. package/dist/providers/handlers/providers.d.ts.map +1 -0
  143. package/dist/providers/handlers/r1-base.d.ts +1 -0
  144. package/dist/providers/handlers/r1-base.d.ts.map +1 -0
  145. package/dist/providers/handlers/registry.d.ts +1 -0
  146. package/dist/providers/handlers/registry.d.ts.map +1 -0
  147. package/dist/providers/handlers/vertex.d.ts +1 -0
  148. package/dist/providers/handlers/vertex.d.ts.map +1 -0
  149. package/dist/providers/index.d.ts +1 -0
  150. package/dist/providers/index.d.ts.map +1 -0
  151. package/dist/providers/public.browser.d.ts +1 -0
  152. package/dist/providers/public.browser.d.ts.map +1 -0
  153. package/dist/providers/public.d.ts +1 -0
  154. package/dist/providers/public.d.ts.map +1 -0
  155. package/dist/providers/shared/openai-compatible.d.ts +1 -0
  156. package/dist/providers/shared/openai-compatible.d.ts.map +1 -0
  157. package/dist/providers/transform/ai-sdk-community-format.d.ts +1 -0
  158. package/dist/providers/transform/ai-sdk-community-format.d.ts.map +1 -0
  159. package/dist/providers/transform/anthropic-format.d.ts +1 -0
  160. package/dist/providers/transform/anthropic-format.d.ts.map +1 -0
  161. package/dist/providers/transform/content-format.d.ts +1 -0
  162. package/dist/providers/transform/content-format.d.ts.map +1 -0
  163. package/dist/providers/transform/gemini-format.d.ts +1 -0
  164. package/dist/providers/transform/gemini-format.d.ts.map +1 -0
  165. package/dist/providers/transform/index.d.ts +1 -0
  166. package/dist/providers/transform/index.d.ts.map +1 -0
  167. package/dist/providers/transform/openai-format.d.ts +1 -0
  168. package/dist/providers/transform/openai-format.d.ts.map +1 -0
  169. package/dist/providers/transform/r1-format.d.ts +1 -0
  170. package/dist/providers/transform/r1-format.d.ts.map +1 -0
  171. package/dist/providers/types/config.d.ts +1 -0
  172. package/dist/providers/types/config.d.ts.map +1 -0
  173. package/dist/providers/types/handler.d.ts +1 -0
  174. package/dist/providers/types/handler.d.ts.map +1 -0
  175. package/dist/providers/types/index.d.ts +1 -0
  176. package/dist/providers/types/index.d.ts.map +1 -0
  177. package/dist/providers/types/messages.d.ts +1 -0
  178. package/dist/providers/types/messages.d.ts.map +1 -0
  179. package/dist/providers/types/model-info.d.ts +1 -0
  180. package/dist/providers/types/model-info.d.ts.map +1 -0
  181. package/dist/providers/types/provider-ids.d.ts +1 -1
  182. package/dist/providers/types/provider-ids.d.ts.map +1 -0
  183. package/dist/providers/types/settings.d.ts +1 -0
  184. package/dist/providers/types/settings.d.ts.map +1 -0
  185. package/dist/providers/types/stream.d.ts +1 -0
  186. package/dist/providers/types/stream.d.ts.map +1 -0
  187. package/dist/providers/utils/index.d.ts +1 -0
  188. package/dist/providers/utils/index.d.ts.map +1 -0
  189. package/dist/providers/utils/retry.d.ts +1 -0
  190. package/dist/providers/utils/retry.d.ts.map +1 -0
  191. package/dist/providers/utils/stream-processor.d.ts +1 -0
  192. package/dist/providers/utils/stream-processor.d.ts.map +1 -0
  193. package/dist/providers/utils/tool-processor.d.ts +1 -0
  194. package/dist/providers/utils/tool-processor.d.ts.map +1 -0
  195. package/dist/sdk.d.ts +1 -0
  196. package/dist/sdk.d.ts.map +1 -0
  197. package/dist/types.d.ts +1 -0
  198. package/dist/types.d.ts.map +1 -0
  199. package/package.json +3 -4
  200. package/src/catalog.ts +0 -20
  201. package/src/config-browser.ts +0 -11
  202. package/src/config.ts +0 -49
  203. package/src/index.browser.ts +0 -9
  204. package/src/index.ts +0 -10
  205. package/src/live-providers.test.ts +0 -138
  206. package/src/models/generated-access.ts +0 -41
  207. package/src/models/generated-provider-loaders.ts +0 -166
  208. package/src/models/generated.ts +0 -11785
  209. package/src/models/index.ts +0 -271
  210. package/src/models/models-dev-catalog.test.ts +0 -161
  211. package/src/models/models-dev-catalog.ts +0 -168
  212. package/src/models/providers/aihubmix.ts +0 -19
  213. package/src/models/providers/anthropic.ts +0 -60
  214. package/src/models/providers/asksage.ts +0 -19
  215. package/src/models/providers/baseten.ts +0 -21
  216. package/src/models/providers/bedrock.ts +0 -30
  217. package/src/models/providers/cerebras.ts +0 -24
  218. package/src/models/providers/claude-code.ts +0 -51
  219. package/src/models/providers/cline.ts +0 -25
  220. package/src/models/providers/deepseek.ts +0 -33
  221. package/src/models/providers/dify.ts +0 -17
  222. package/src/models/providers/doubao.ts +0 -33
  223. package/src/models/providers/fireworks.ts +0 -34
  224. package/src/models/providers/gemini.ts +0 -43
  225. package/src/models/providers/groq.ts +0 -33
  226. package/src/models/providers/hicap.ts +0 -18
  227. package/src/models/providers/huawei-cloud-maas.ts +0 -18
  228. package/src/models/providers/huggingface.ts +0 -22
  229. package/src/models/providers/index.ts +0 -162
  230. package/src/models/providers/litellm.ts +0 -19
  231. package/src/models/providers/lmstudio.ts +0 -22
  232. package/src/models/providers/minimax.ts +0 -34
  233. package/src/models/providers/mistral.ts +0 -19
  234. package/src/models/providers/moonshot.ts +0 -34
  235. package/src/models/providers/nebius.ts +0 -24
  236. package/src/models/providers/nous-research.ts +0 -21
  237. package/src/models/providers/oca.ts +0 -30
  238. package/src/models/providers/ollama.ts +0 -18
  239. package/src/models/providers/openai-codex.ts +0 -46
  240. package/src/models/providers/openai.ts +0 -43
  241. package/src/models/providers/opencode.ts +0 -28
  242. package/src/models/providers/openrouter.ts +0 -24
  243. package/src/models/providers/qwen-code.ts +0 -33
  244. package/src/models/providers/qwen.ts +0 -34
  245. package/src/models/providers/requesty.ts +0 -23
  246. package/src/models/providers/sambanova.ts +0 -23
  247. package/src/models/providers/sapaicore.ts +0 -34
  248. package/src/models/providers/together.ts +0 -35
  249. package/src/models/providers/vercel-ai-gateway.ts +0 -23
  250. package/src/models/providers/vertex.ts +0 -36
  251. package/src/models/providers/xai.ts +0 -34
  252. package/src/models/providers/zai.ts +0 -25
  253. package/src/models/query.ts +0 -407
  254. package/src/models/registry.ts +0 -511
  255. package/src/models/schemas/index.ts +0 -62
  256. package/src/models/schemas/model.ts +0 -308
  257. package/src/models/schemas/query.ts +0 -336
  258. package/src/providers/browser.ts +0 -4
  259. package/src/providers/handlers/ai-sdk-community.ts +0 -229
  260. package/src/providers/handlers/ai-sdk-provider-base.ts +0 -203
  261. package/src/providers/handlers/anthropic-base.test.ts +0 -30
  262. package/src/providers/handlers/anthropic-base.ts +0 -387
  263. package/src/providers/handlers/asksage.test.ts +0 -103
  264. package/src/providers/handlers/asksage.ts +0 -138
  265. package/src/providers/handlers/auth.test.ts +0 -19
  266. package/src/providers/handlers/auth.ts +0 -121
  267. package/src/providers/handlers/base.test.ts +0 -230
  268. package/src/providers/handlers/base.ts +0 -310
  269. package/src/providers/handlers/bedrock-base.ts +0 -390
  270. package/src/providers/handlers/bedrock-client.ts +0 -100
  271. package/src/providers/handlers/codex.test.ts +0 -160
  272. package/src/providers/handlers/community-sdk.test.ts +0 -321
  273. package/src/providers/handlers/community-sdk.ts +0 -391
  274. package/src/providers/handlers/fetch-base.ts +0 -68
  275. package/src/providers/handlers/gemini-base.test.ts +0 -261
  276. package/src/providers/handlers/gemini-base.ts +0 -307
  277. package/src/providers/handlers/index.ts +0 -67
  278. package/src/providers/handlers/openai-base.ts +0 -341
  279. package/src/providers/handlers/openai-responses.test.ts +0 -259
  280. package/src/providers/handlers/openai-responses.ts +0 -634
  281. package/src/providers/handlers/providers.test.ts +0 -120
  282. package/src/providers/handlers/providers.ts +0 -563
  283. package/src/providers/handlers/r1-base.ts +0 -283
  284. package/src/providers/handlers/registry.ts +0 -185
  285. package/src/providers/handlers/vertex.test.ts +0 -124
  286. package/src/providers/handlers/vertex.ts +0 -302
  287. package/src/providers/index.ts +0 -534
  288. package/src/providers/public.browser.ts +0 -20
  289. package/src/providers/public.ts +0 -51
  290. package/src/providers/shared/openai-compatible.ts +0 -63
  291. package/src/providers/transform/ai-sdk-community-format.test.ts +0 -73
  292. package/src/providers/transform/ai-sdk-community-format.ts +0 -115
  293. package/src/providers/transform/anthropic-format.ts +0 -230
  294. package/src/providers/transform/content-format.ts +0 -34
  295. package/src/providers/transform/format-conversion.test.ts +0 -413
  296. package/src/providers/transform/gemini-format.ts +0 -262
  297. package/src/providers/transform/index.ts +0 -22
  298. package/src/providers/transform/openai-format.ts +0 -290
  299. package/src/providers/transform/r1-format.ts +0 -287
  300. package/src/providers/types/config.ts +0 -396
  301. package/src/providers/types/handler.ts +0 -92
  302. package/src/providers/types/index.ts +0 -120
  303. package/src/providers/types/messages.ts +0 -162
  304. package/src/providers/types/model-info.test.ts +0 -57
  305. package/src/providers/types/model-info.ts +0 -65
  306. package/src/providers/types/provider-ids.test.ts +0 -12
  307. package/src/providers/types/provider-ids.ts +0 -89
  308. package/src/providers/types/settings.test.ts +0 -49
  309. package/src/providers/types/settings.ts +0 -533
  310. package/src/providers/types/stream.ts +0 -117
  311. package/src/providers/utils/index.ts +0 -27
  312. package/src/providers/utils/retry.test.ts +0 -140
  313. package/src/providers/utils/retry.ts +0 -188
  314. package/src/providers/utils/stream-processor.test.ts +0 -232
  315. package/src/providers/utils/stream-processor.ts +0 -472
  316. package/src/providers/utils/tool-processor.test.ts +0 -235
  317. package/src/providers/utils/tool-processor.ts +0 -146
  318. package/src/sdk.ts +0 -264
  319. package/src/types.ts +0 -79
@@ -1,634 +0,0 @@
1
- /**
2
- * OpenAI Responses API Handler
3
- *
4
- * Handler for OpenAI's Responses API format, which is used by newer models
5
- * that require native tool calling (e.g., GPT-5, o3, codex).
6
- *
7
- * The Responses API has a different structure than Chat Completions:
8
- * - Uses `instructions` instead of system messages
9
- * - Uses `input` instead of messages array
10
- * - Has different streaming event types (response.*, not choices.delta)
11
- * - Supports reasoning with encrypted content
12
- */
13
-
14
- import OpenAI from "openai";
15
- import {
16
- normalizeToolUseInput,
17
- serializeToolResultContent,
18
- } from "../transform/content-format";
19
- import type {
20
- ApiStream,
21
- HandlerModelInfo,
22
- ModelInfo,
23
- ProviderConfig,
24
- } from "../types";
25
- import type {
26
- ContentBlock,
27
- Message,
28
- ToolDefinition,
29
- ToolUseContent,
30
- } from "../types/messages";
31
- import { retryStream } from "../utils/retry";
32
- import { getMissingApiKeyError, resolveApiKeyForProvider } from "./auth";
33
- import { BaseHandler } from "./base";
34
-
35
- const DEFAULT_REASONING_EFFORT = "medium" as const;
36
-
37
- /**
38
- * Convert tool definitions to Responses API format
39
- */
40
- function convertToolsToResponsesFormat(
41
- tools?: ToolDefinition[],
42
- _options?: { stripFormat?: boolean },
43
- ) {
44
- if (!tools?.length) return undefined;
45
-
46
- return tools.map((tool) => ({
47
- type: "function" as const,
48
- name: tool.name,
49
- description: tool.description,
50
- parameters: tool.inputSchema,
51
- }));
52
- }
53
-
54
- /**
55
- * Convert messages to Responses API input format
56
- */
57
- function convertToResponsesInput(messages: Message[]) {
58
- type ResponsesInputItem =
59
- | {
60
- type: "message";
61
- role: "user" | "assistant";
62
- content: Array<{ type: "input_text" | "output_text"; text: string }>;
63
- }
64
- | {
65
- type: "function_call";
66
- call_id: string;
67
- name: string;
68
- arguments: string;
69
- }
70
- | {
71
- type: "function_call_output";
72
- call_id: string;
73
- output: string;
74
- };
75
-
76
- const input: ResponsesInputItem[] = [];
77
-
78
- const toText = (
79
- role: "user" | "assistant",
80
- contentBlocks: Array<{ type: "text"; text: string }>,
81
- ) => {
82
- const textContent = contentBlocks.map((block) => block.text).join("\n");
83
- if (!textContent) {
84
- return;
85
- }
86
- input.push({
87
- type: "message",
88
- role,
89
- content: [
90
- {
91
- type: role === "user" ? "input_text" : "output_text",
92
- text: textContent,
93
- },
94
- ],
95
- });
96
- };
97
-
98
- const isTextBlock = (
99
- block: ContentBlock,
100
- ): block is { type: "text"; text: string } => block.type === "text";
101
-
102
- const assistantToolUseCallId = (block: ToolUseContent): string =>
103
- block.call_id?.trim() || block.id;
104
-
105
- for (const msg of messages) {
106
- if (msg.role !== "user" && msg.role !== "assistant") {
107
- continue;
108
- }
109
-
110
- if (!Array.isArray(msg.content)) {
111
- if (msg.content) {
112
- toText(msg.role, [{ type: "text", text: msg.content }]);
113
- }
114
- continue;
115
- }
116
-
117
- let bufferedText: Array<{ type: "text"; text: string }> = [];
118
- const flushText = () => {
119
- if (bufferedText.length === 0) {
120
- return;
121
- }
122
- toText(msg.role, bufferedText);
123
- bufferedText = [];
124
- };
125
-
126
- for (const block of msg.content) {
127
- if (isTextBlock(block)) {
128
- bufferedText.push(block);
129
- continue;
130
- }
131
-
132
- if (msg.role === "assistant" && block.type === "tool_use") {
133
- flushText();
134
- const toolUseBlock = block as ToolUseContent;
135
- input.push({
136
- type: "function_call",
137
- call_id: assistantToolUseCallId(toolUseBlock),
138
- name: toolUseBlock.name,
139
- arguments: JSON.stringify(normalizeToolUseInput(toolUseBlock.input)),
140
- });
141
- continue;
142
- }
143
-
144
- if (msg.role === "user" && block.type === "tool_result") {
145
- flushText();
146
- input.push({
147
- type: "function_call_output",
148
- call_id: block.tool_use_id,
149
- output: serializeToolResultContent(block.content),
150
- });
151
- }
152
- }
153
-
154
- flushText();
155
- }
156
-
157
- return input;
158
- }
159
-
160
- /**
161
- * Handler for OpenAI Responses API
162
- *
163
- * Uses ProviderConfig fields:
164
- * - baseUrl: Base URL for the API
165
- * - modelId: Model ID
166
- * - knownModels: Known models with their info
167
- * - headers: Custom headers
168
- */
169
- export class OpenAIResponsesHandler extends BaseHandler {
170
- protected client: OpenAI | undefined;
171
-
172
- /**
173
- * Ensure the OpenAI client is initialized
174
- */
175
- protected ensureClient(): OpenAI {
176
- if (!this.client) {
177
- const baseURL = this.config.baseUrl;
178
-
179
- if (!baseURL) {
180
- throw new Error("Base URL is required. Set baseUrl in config.");
181
- }
182
- const apiKey = resolveApiKeyForProvider(
183
- this.config.providerId,
184
- this.config.apiKey,
185
- );
186
- if (!apiKey) {
187
- throw new Error(getMissingApiKeyError(this.config.providerId));
188
- }
189
- const requestHeaders = this.getRequestHeaders();
190
- const hasAuthorizationHeader = Object.keys(requestHeaders).some(
191
- (key) => key.toLowerCase() === "authorization",
192
- );
193
-
194
- this.client = new OpenAI({
195
- apiKey,
196
- baseURL,
197
- defaultHeaders: hasAuthorizationHeader
198
- ? requestHeaders
199
- : { ...requestHeaders, Authorization: `Bearer ${apiKey}` },
200
- });
201
- }
202
- return this.client;
203
- }
204
-
205
- /**
206
- * Get model info, falling back to provider defaults
207
- */
208
- getModel(): HandlerModelInfo {
209
- const modelId = this.config.modelId;
210
- if (!modelId) {
211
- throw new Error("Model ID is required. Set modelId in config.");
212
- }
213
-
214
- const modelInfo =
215
- this.config.modelInfo ??
216
- this.config.knownModels?.[modelId] ??
217
- this.getDefaultModelInfo();
218
-
219
- return { id: modelId, info: { ...modelInfo, id: modelId } };
220
- }
221
-
222
- protected getDefaultModelInfo(): ModelInfo {
223
- // Responses API models don't support prompt caching
224
- const capabilities = [].filter((c) => c !== "prompt-cache");
225
- return {
226
- id: this.config.modelId,
227
- capabilities,
228
- };
229
- }
230
-
231
- getMessages(
232
- _systemPrompt: string,
233
- messages: Message[],
234
- ): ReturnType<typeof convertToResponsesInput> {
235
- return convertToResponsesInput(messages);
236
- }
237
-
238
- /**
239
- * Create a streaming message using the Responses API
240
- */
241
- async *createMessage(
242
- systemPrompt: string,
243
- messages: Message[],
244
- tools?: ToolDefinition[],
245
- ): ApiStream {
246
- yield* retryStream(() =>
247
- this.createMessageInternal(systemPrompt, messages, tools),
248
- );
249
- }
250
-
251
- private async *createMessageInternal(
252
- systemPrompt: string,
253
- messages: Message[],
254
- tools?: ToolDefinition[],
255
- ): ApiStream {
256
- const client = this.ensureClient();
257
- const { id: modelId, info: modelInfo } = this.getModel();
258
- const abortSignal = this.getAbortSignal();
259
- const fallbackResponseId = this.createResponseId();
260
- let resolvedResponseId: string | undefined;
261
- const functionCallMetadataByItemId = new Map<
262
- string,
263
- { callId?: string; name?: string }
264
- >();
265
-
266
- // Convert messages to Responses API input format
267
- const input = this.getMessages(systemPrompt, messages);
268
-
269
- // Convert tools to Responses API format
270
- const responseTools = convertToolsToResponsesFormat(tools, {
271
- stripFormat: this.config.providerId === "openai-codex",
272
- });
273
-
274
- // Responses API requires tools for native tool calling
275
- if (!responseTools?.length) {
276
- throw new Error(
277
- "OpenAI Responses API requires tools to be provided. Enable native tool calling in settings.",
278
- );
279
- }
280
-
281
- // Build reasoning config
282
- const supportsReasoning =
283
- modelInfo.capabilities?.includes("reasoning") ?? false;
284
- const effectiveReasoningEffort =
285
- this.config.reasoningEffort ??
286
- (this.config.thinking ? DEFAULT_REASONING_EFFORT : undefined);
287
- const reasoningConfig =
288
- supportsReasoning && effectiveReasoningEffort
289
- ? {
290
- effort: effectiveReasoningEffort,
291
- summary: "auto" as const,
292
- }
293
- : undefined;
294
- const requestHeaders = this.getRequestHeaders();
295
- const hasAuthorizationHeader = Object.keys(requestHeaders).some(
296
- (key) => key.toLowerCase() === "authorization",
297
- );
298
- const apiKey = resolveApiKeyForProvider(
299
- this.config.providerId,
300
- this.config.apiKey,
301
- );
302
- if (!hasAuthorizationHeader && apiKey) {
303
- requestHeaders.Authorization = `Bearer ${apiKey}`;
304
- }
305
- if (
306
- this.config.providerId === "openai-codex" &&
307
- typeof this.config.accountId === "string" &&
308
- this.config.accountId.trim().length > 0
309
- ) {
310
- const accountId = this.config.accountId.trim();
311
- // ChatGPT Codex endpoints may require an explicit account identifier.
312
- requestHeaders["chatgpt-account-id"] = accountId;
313
- requestHeaders["openai-account-id"] = accountId;
314
- }
315
-
316
- // Create the response using Responses API
317
- let stream: AsyncIterable<any>;
318
- try {
319
- stream = await (client as any).responses.create(
320
- {
321
- model: modelId,
322
- instructions: systemPrompt,
323
- input,
324
- // ChatGPT account Codex rejects requests unless explicit non-storage is set.
325
- store: this.config.providerId === "openai-codex" ? false : undefined,
326
- stream: true,
327
- tools: responseTools,
328
- reasoning: reasoningConfig,
329
- },
330
- { signal: abortSignal, headers: requestHeaders },
331
- );
332
- } catch (error) {
333
- const normalizedBadRequest =
334
- this.normalizeOpenAICompatibleBadRequest(error);
335
- if (normalizedBadRequest) {
336
- throw normalizedBadRequest;
337
- }
338
- if (this.config.providerId === "openai-codex") {
339
- const rawError = error as
340
- | (Error & {
341
- status?: number;
342
- message?: string;
343
- error?: { message?: string; detail?: string };
344
- response?: { status?: number };
345
- })
346
- | undefined;
347
- const status =
348
- rawError?.status ??
349
- rawError?.response?.status ??
350
- (typeof rawError?.message === "string" &&
351
- rawError.message.includes("400")
352
- ? 400
353
- : undefined);
354
- if (status === 400) {
355
- const detail =
356
- rawError?.error?.detail ??
357
- rawError?.error?.message ??
358
- (typeof rawError?.message === "string" ? rawError.message : "");
359
- throw new Error(
360
- `OpenAI Codex request was rejected (HTTP 400). ${detail ? `Detail: ${detail}` : "Re-run 'clite auth openai-codex', verify model access, and ensure accountId is present in provider settings."}`,
361
- { cause: error },
362
- );
363
- }
364
- }
365
- throw error;
366
- }
367
-
368
- // Process the response stream
369
- for await (const chunk of stream) {
370
- const apiResponseId = this.getApiResponseId(chunk);
371
- if (apiResponseId) {
372
- resolvedResponseId = apiResponseId;
373
- }
374
-
375
- yield* this.processResponseChunk(
376
- chunk,
377
- modelInfo,
378
- resolvedResponseId ?? fallbackResponseId,
379
- functionCallMetadataByItemId,
380
- );
381
- }
382
- }
383
-
384
- /**
385
- * Process a single chunk from the Responses API stream
386
- */
387
- protected *processResponseChunk(
388
- chunk: any,
389
- _modelInfo: ModelInfo,
390
- responseId: string,
391
- functionCallMetadataByItemId: Map<
392
- string,
393
- { callId?: string; name?: string }
394
- >,
395
- ): Generator<import("../types").ApiStreamChunk> {
396
- // Handle different event types from Responses API
397
- switch (chunk.type) {
398
- case "response.output_item.added": {
399
- const item = chunk.item;
400
- if (item.type === "function_call" && item.id) {
401
- functionCallMetadataByItemId.set(item.id, {
402
- callId: item.call_id,
403
- name: item.name,
404
- });
405
- yield {
406
- type: "tool_calls",
407
- id: item.id || responseId,
408
- tool_call: {
409
- call_id: item.call_id,
410
- function: {
411
- id: item.id,
412
- name: item.name,
413
- arguments: item.arguments,
414
- },
415
- },
416
- };
417
- }
418
- if (item.type === "reasoning" && item.encrypted_content && item.id) {
419
- yield {
420
- type: "reasoning",
421
- id: item.id || responseId,
422
- reasoning: "",
423
- redacted_data: item.encrypted_content,
424
- };
425
- }
426
- break;
427
- }
428
-
429
- case "response.output_item.done": {
430
- const item = chunk.item;
431
- if (item.type === "function_call") {
432
- if (item.id) {
433
- functionCallMetadataByItemId.set(item.id, {
434
- callId: item.call_id,
435
- name: item.name,
436
- });
437
- }
438
- yield {
439
- type: "tool_calls",
440
- id: item.id || responseId,
441
- tool_call: {
442
- call_id: item.call_id,
443
- function: {
444
- id: item.id,
445
- name: item.name,
446
- arguments: item.arguments,
447
- },
448
- },
449
- };
450
- }
451
- if (item.type === "reasoning") {
452
- yield {
453
- type: "reasoning",
454
- id: item.id || responseId,
455
- details: item.summary,
456
- reasoning: "",
457
- };
458
- }
459
- break;
460
- }
461
-
462
- case "response.reasoning_summary_part.added":
463
- yield {
464
- type: "reasoning",
465
- id: chunk.item_id || responseId,
466
- reasoning: chunk.part?.text || "",
467
- };
468
- break;
469
-
470
- case "response.reasoning_summary_text.delta":
471
- yield {
472
- type: "reasoning",
473
- id: chunk.item_id || responseId,
474
- reasoning: chunk.delta || "",
475
- };
476
- break;
477
-
478
- case "response.reasoning_summary_part.done":
479
- yield {
480
- type: "reasoning",
481
- id: chunk.item_id || responseId,
482
- details: chunk.part,
483
- reasoning: "",
484
- };
485
- break;
486
-
487
- case "response.output_text.delta":
488
- if (chunk.delta) {
489
- yield {
490
- id: chunk.item_id || responseId,
491
- type: "text",
492
- text: chunk.delta,
493
- };
494
- }
495
- break;
496
-
497
- case "response.reasoning_text.delta":
498
- if (chunk.delta) {
499
- yield {
500
- id: chunk.item_id || responseId,
501
- type: "reasoning",
502
- reasoning: chunk.delta,
503
- };
504
- }
505
- break;
506
-
507
- case "response.function_call_arguments.delta":
508
- {
509
- const meta = chunk.item_id
510
- ? functionCallMetadataByItemId.get(chunk.item_id)
511
- : undefined;
512
- yield {
513
- type: "tool_calls",
514
- id: chunk.item_id || responseId,
515
- tool_call: {
516
- call_id: meta?.callId,
517
- function: {
518
- id: chunk.item_id,
519
- name: meta?.name,
520
- arguments: chunk.delta,
521
- },
522
- },
523
- };
524
- }
525
- break;
526
-
527
- case "response.function_call_arguments.done":
528
- if (chunk.item_id && chunk.arguments) {
529
- const meta = functionCallMetadataByItemId.get(chunk.item_id);
530
- yield {
531
- type: "tool_calls",
532
- id: chunk.item_id || responseId,
533
- tool_call: {
534
- call_id: chunk.call_id ?? meta?.callId,
535
- function: {
536
- id: chunk.item_id,
537
- name: chunk.name ?? meta?.name,
538
- arguments: chunk.arguments,
539
- },
540
- },
541
- };
542
- }
543
- break;
544
-
545
- case "response.incomplete": {
546
- const incompleteReason = chunk.response?.incomplete_details?.reason;
547
- yield {
548
- type: "done",
549
- success: false,
550
- incompleteReason,
551
- id: chunk.response?.id || responseId,
552
- };
553
- break;
554
- }
555
-
556
- case "response.failed": {
557
- const error = chunk.response?.error;
558
- yield {
559
- type: "done",
560
- success: false,
561
- error: error?.message || "Unknown error",
562
- id: chunk.response?.id || responseId,
563
- };
564
- break;
565
- }
566
-
567
- case "response.completed": {
568
- if (chunk.response?.usage) {
569
- const usage = chunk.response.usage;
570
- const inputTokens = usage.input_tokens || 0;
571
- const outputTokens = usage.output_tokens || 0;
572
- const cacheReadTokens =
573
- usage.input_tokens_details?.cached_tokens || 0;
574
- const cacheWriteTokens = 0;
575
-
576
- const totalCost = this.calculateCostFromInclusiveInput(
577
- inputTokens,
578
- outputTokens,
579
- cacheReadTokens,
580
- cacheWriteTokens,
581
- );
582
-
583
- yield {
584
- type: "usage",
585
- inputTokens: Math.max(
586
- 0,
587
- inputTokens - cacheReadTokens - cacheWriteTokens,
588
- ),
589
- outputTokens,
590
- cacheWriteTokens,
591
- cacheReadTokens,
592
- totalCost,
593
- id: chunk.response.id || responseId,
594
- };
595
- }
596
-
597
- // Yield done chunk to indicate streaming completed successfully
598
- yield {
599
- type: "done",
600
- success: true,
601
- id: chunk.response?.id || responseId,
602
- };
603
- break;
604
- }
605
- }
606
- }
607
-
608
- private getApiResponseId(chunk: any): string | undefined {
609
- if (
610
- typeof chunk?.response?.id === "string" &&
611
- chunk.response.id.length > 0
612
- ) {
613
- return chunk.response.id;
614
- }
615
-
616
- if (
617
- typeof chunk?.response_id === "string" &&
618
- chunk.response_id.length > 0
619
- ) {
620
- return chunk.response_id;
621
- }
622
-
623
- return undefined;
624
- }
625
- }
626
-
627
- /**
628
- * Create an OpenAI Responses API handler
629
- */
630
- export function createOpenAIResponsesHandler(
631
- config: ProviderConfig,
632
- ): OpenAIResponsesHandler {
633
- return new OpenAIResponsesHandler(config);
634
- }