@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,321 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
2
- import type { ApiStreamChunk } from "../types";
3
- import {
4
- ClaudeCodeHandler,
5
- DifyHandler,
6
- MistralHandler,
7
- OpenCodeHandler,
8
- SapAiCoreHandler,
9
- } from "./community-sdk";
10
-
11
- const streamTextSpy = vi.fn();
12
- const claudeCodeSpy = vi.fn((modelId: string) => ({ modelId }));
13
- const opencodeSpy = vi.fn((modelId: string) => ({ modelId }));
14
- const mistralSpy = vi.fn((modelId: string) => ({ modelId }));
15
- const difySpy = vi.fn(
16
- (modelId: string, settings?: Record<string, unknown>) => ({
17
- modelId,
18
- settings,
19
- }),
20
- );
21
- const sapAiProviderSpy = vi.fn((modelId: string) => ({ modelId }));
22
- let lastCreateSapAiProviderOptions: Record<string, unknown> | undefined;
23
- let lastCreateDifyProviderOptions: Record<string, unknown> | undefined;
24
-
25
- vi.mock("ai", () => ({
26
- streamText: (input: unknown) => streamTextSpy(input),
27
- }));
28
-
29
- vi.mock("ai-sdk-provider-claude-code", () => ({
30
- claudeCode: (modelId: string) => claudeCodeSpy(modelId),
31
- createClaudeCode: () => (modelId: string) => claudeCodeSpy(modelId),
32
- }));
33
-
34
- vi.mock("ai-sdk-provider-opencode-sdk", () => ({
35
- opencode: (modelId: string) => opencodeSpy(modelId),
36
- createOpencode: () => (modelId: string) => opencodeSpy(modelId),
37
- }));
38
-
39
- vi.mock("@ai-sdk/mistral", () => ({
40
- mistral: (modelId: string) => mistralSpy(modelId),
41
- createMistral: () => (modelId: string) => mistralSpy(modelId),
42
- }));
43
-
44
- vi.mock("dify-ai-provider", () => ({
45
- difyProvider: (modelId: string, settings?: Record<string, unknown>) =>
46
- difySpy(modelId, settings),
47
- createDifyProvider: (options?: Record<string, unknown>) => {
48
- lastCreateDifyProviderOptions = options;
49
- return (modelId: string, settings?: Record<string, unknown>) =>
50
- difySpy(modelId, settings);
51
- },
52
- }));
53
-
54
- vi.mock("@jerome-benoit/sap-ai-provider", () => ({
55
- sapai: (modelId: string) => sapAiProviderSpy(modelId),
56
- createSAPAIProvider: (options?: Record<string, unknown>) => {
57
- lastCreateSapAiProviderOptions = options;
58
- return (modelId: string) => sapAiProviderSpy(modelId);
59
- },
60
- }));
61
-
62
- async function* makeStreamParts(parts: unknown[]) {
63
- for (const part of parts) {
64
- yield part;
65
- }
66
- }
67
-
68
- describe("Community SDK handlers", () => {
69
- beforeEach(() => {
70
- vi.clearAllMocks();
71
- lastCreateSapAiProviderOptions = undefined;
72
- lastCreateDifyProviderOptions = undefined;
73
- });
74
-
75
- describe("ClaudeCodeHandler", () => {
76
- it("streams text and usage through AI SDK fullStream", async () => {
77
- streamTextSpy.mockReturnValue({
78
- fullStream: makeStreamParts([
79
- { type: "text-delta", textDelta: "Hello" },
80
- {
81
- type: "finish",
82
- usage: { inputTokens: 10, outputTokens: 3 },
83
- },
84
- ]),
85
- });
86
-
87
- const handler = new ClaudeCodeHandler({
88
- providerId: "claude-code",
89
- modelId: "sonnet",
90
- });
91
-
92
- const chunks: ApiStreamChunk[] = [];
93
- for await (const chunk of handler.createMessage("System", [
94
- { role: "user", content: "Hi" },
95
- ])) {
96
- chunks.push(chunk);
97
- }
98
-
99
- expect(claudeCodeSpy).toHaveBeenCalledWith("sonnet");
100
- expect(chunks.map((chunk) => chunk.type)).toEqual([
101
- "text",
102
- "usage",
103
- "done",
104
- ]);
105
- const textChunk = chunks.find(
106
- (chunk): chunk is Extract<ApiStreamChunk, { type: "text" }> =>
107
- chunk.type === "text",
108
- );
109
- const usageChunk = chunks.find(
110
- (chunk): chunk is Extract<ApiStreamChunk, { type: "usage" }> =>
111
- chunk.type === "usage",
112
- );
113
- expect(textChunk?.text).toBe("Hello");
114
- expect(usageChunk?.inputTokens).toBe(10);
115
- expect(usageChunk?.outputTokens).toBe(3);
116
- });
117
-
118
- it("keeps cached input tokens separate from total input tokens", async () => {
119
- streamTextSpy.mockReturnValue({
120
- fullStream: makeStreamParts([
121
- {
122
- type: "finish",
123
- usage: { inputTokens: 10, outputTokens: 3, cachedInputTokens: 4 },
124
- },
125
- ]),
126
- });
127
-
128
- const handler = new ClaudeCodeHandler({
129
- providerId: "claude-code",
130
- modelId: "sonnet",
131
- });
132
-
133
- const chunks: ApiStreamChunk[] = [];
134
- for await (const chunk of handler.createMessage("System", [
135
- { role: "user", content: "Hi" },
136
- ])) {
137
- chunks.push(chunk);
138
- }
139
-
140
- const usageChunk = chunks.find(
141
- (chunk): chunk is Extract<ApiStreamChunk, { type: "usage" }> =>
142
- chunk.type === "usage",
143
- );
144
- expect(usageChunk).toMatchObject({
145
- inputTokens: 6,
146
- outputTokens: 3,
147
- cacheReadTokens: 4,
148
- });
149
- });
150
-
151
- it("uses a fallback model id when model is missing", () => {
152
- const handler = new ClaudeCodeHandler({
153
- providerId: "claude-code",
154
- modelId: "",
155
- });
156
-
157
- expect(handler.getModel().id).toBe("sonnet");
158
- });
159
- });
160
-
161
- describe("MistralHandler", () => {
162
- it("uses a fallback model id when model is missing", () => {
163
- const handler = new MistralHandler({
164
- providerId: "mistral",
165
- modelId: "",
166
- });
167
-
168
- expect(handler.getModel().id).toBe("mistral-medium-latest");
169
- });
170
- });
171
-
172
- describe("DifyHandler", () => {
173
- it("passes baseURL and apiKey model settings to dify provider", async () => {
174
- streamTextSpy.mockReturnValue({
175
- fullStream: makeStreamParts([{ type: "finish", usage: {} }]),
176
- });
177
-
178
- const handler = new DifyHandler({
179
- providerId: "dify",
180
- modelId: "workflow-123",
181
- apiKey: "dify-key",
182
- baseUrl: "https://dify.example.com/v1",
183
- });
184
-
185
- for await (const _chunk of handler.createMessage("System", [
186
- { role: "user", content: "Hi" },
187
- ])) {
188
- // noop
189
- }
190
-
191
- expect(lastCreateDifyProviderOptions).toEqual({
192
- baseURL: "https://dify.example.com/v1",
193
- });
194
- expect(difySpy).toHaveBeenCalledWith("workflow-123", {
195
- responseMode: "blocking",
196
- apiKey: "dify-key",
197
- });
198
- });
199
- });
200
-
201
- describe("OpenCodeHandler", () => {
202
- it("streams text and usage through AI SDK fullStream", async () => {
203
- streamTextSpy.mockReturnValue({
204
- fullStream: makeStreamParts([
205
- { type: "text-delta", textDelta: "Hello" },
206
- {
207
- type: "finish",
208
- usage: { inputTokens: 10, outputTokens: 3 },
209
- },
210
- ]),
211
- });
212
-
213
- const handler = new OpenCodeHandler({
214
- providerId: "opencode",
215
- modelId: "gpt-5.1-codex",
216
- });
217
-
218
- const chunks: ApiStreamChunk[] = [];
219
- for await (const chunk of handler.createMessage("System", [
220
- { role: "user", content: "Hi" },
221
- ])) {
222
- chunks.push(chunk);
223
- }
224
-
225
- expect(opencodeSpy).toHaveBeenCalledWith("openai/gpt-5.1-codex");
226
- expect(chunks.map((chunk) => chunk.type)).toEqual([
227
- "text",
228
- "usage",
229
- "done",
230
- ]);
231
- const textChunk = chunks.find(
232
- (chunk): chunk is Extract<ApiStreamChunk, { type: "text" }> =>
233
- chunk.type === "text",
234
- );
235
- const usageChunk = chunks.find(
236
- (chunk): chunk is Extract<ApiStreamChunk, { type: "usage" }> =>
237
- chunk.type === "usage",
238
- );
239
- expect(textChunk?.text).toBe("Hello");
240
- expect(usageChunk?.inputTokens).toBe(10);
241
- expect(usageChunk?.outputTokens).toBe(3);
242
- });
243
-
244
- it("uses full model IDs without changes", async () => {
245
- streamTextSpy.mockReturnValue({
246
- fullStream: makeStreamParts([{ type: "finish", usage: {} }]),
247
- });
248
-
249
- const handler = new OpenCodeHandler({
250
- providerId: "opencode",
251
- modelId: "openai/gpt-5.1-codex-max",
252
- });
253
-
254
- for await (const _chunk of handler.createMessage("System", [
255
- { role: "user", content: "Hi" },
256
- ])) {
257
- // noop
258
- }
259
-
260
- expect(opencodeSpy).toHaveBeenCalledWith("openai/gpt-5.1-codex-max");
261
- });
262
- });
263
-
264
- describe("SapAiCoreHandler", () => {
265
- it("uses a fallback model id when model is missing", () => {
266
- const handler = new SapAiCoreHandler({
267
- providerId: "sapaicore",
268
- modelId: "",
269
- });
270
-
271
- expect(handler.getModel().id).toBe("anthropic--claude-3.5-sonnet");
272
- });
273
-
274
- it("maps sap config to provider create options and streams text", async () => {
275
- streamTextSpy.mockReturnValue({
276
- fullStream: makeStreamParts([
277
- { type: "text-delta", textDelta: "Hello" },
278
- {
279
- type: "finish",
280
- usage: { inputTokens: 10, outputTokens: 3 },
281
- },
282
- ]),
283
- });
284
-
285
- const handler = new SapAiCoreHandler({
286
- providerId: "sapaicore",
287
- modelId: "gpt-4o",
288
- sap: {
289
- resourceGroup: "default",
290
- deploymentId: "dep-123",
291
- useOrchestrationMode: false,
292
- defaultSettings: {
293
- modelParams: { temperature: 0 },
294
- },
295
- },
296
- });
297
-
298
- const chunks: ApiStreamChunk[] = [];
299
- for await (const chunk of handler.createMessage("System", [
300
- { role: "user", content: "Hi" },
301
- ])) {
302
- chunks.push(chunk);
303
- }
304
-
305
- expect(sapAiProviderSpy).toHaveBeenCalledWith("gpt-4o");
306
- expect(lastCreateSapAiProviderOptions).toEqual({
307
- resourceGroup: "default",
308
- deploymentId: "dep-123",
309
- api: "foundation-models",
310
- defaultSettings: {
311
- modelParams: { temperature: 0 },
312
- },
313
- });
314
- expect(chunks.map((chunk) => chunk.type)).toEqual([
315
- "text",
316
- "usage",
317
- "done",
318
- ]);
319
- });
320
- });
321
- });
@@ -1,391 +0,0 @@
1
- /**
2
- * Community SDK Handlers
3
- *
4
- * Consolidated handlers for:
5
- * - Codex CLI (`openai-codex`)
6
- * - Claude Code (`claude-code`)
7
- * - OpenCode (`opencode`)
8
- * - Mistral (`mistral`)
9
- * - Dify (`dify`)
10
- * - SAP AI Core (`sapaicore`)
11
- */
12
-
13
- import type { ProviderConfig } from "../types";
14
- import type { EmitAiSdkStreamOptions } from "./ai-sdk-community";
15
- import { AiSdkProviderHandler } from "./ai-sdk-provider-base";
16
-
17
- let zodCompatPatched = false;
18
-
19
- async function ensureCodexZodCompatibility(): Promise<void> {
20
- if (zodCompatPatched) {
21
- return;
22
- }
23
- zodCompatPatched = true;
24
-
25
- try {
26
- const zodModule = (await import("zod")) as Record<string, unknown>;
27
- const z = (zodModule.z ?? zodModule) as Record<string, unknown>;
28
- const objectFactory = z.object as
29
- | ((shape?: Record<string, unknown>) => {
30
- refine?: (check: (value: unknown) => boolean) => unknown;
31
- })
32
- | undefined;
33
- if (typeof objectFactory !== "function") {
34
- return;
35
- }
36
-
37
- const refined = objectFactory({}).refine?.(() => true) as
38
- | { passthrough?: unknown }
39
- | undefined;
40
- if (!refined || typeof refined.passthrough === "function") {
41
- return;
42
- }
43
-
44
- const proto = Object.getPrototypeOf(refined) as
45
- | { passthrough?: unknown }
46
- | undefined;
47
- if (!proto || typeof proto.passthrough === "function") {
48
- return;
49
- }
50
-
51
- Object.defineProperty(proto, "passthrough", {
52
- value(this: unknown) {
53
- return this;
54
- },
55
- configurable: true,
56
- enumerable: false,
57
- writable: true,
58
- });
59
- } catch {
60
- // Best-effort compatibility shim for codex-cli provider with zod v3.
61
- }
62
- }
63
-
64
- function isLikelyOpenAIApiKey(value: string): boolean {
65
- return value.startsWith("sk-");
66
- }
67
-
68
- function shouldDisableAiSdkWarnings(): boolean {
69
- const raw = process.env.AI_SDK_LOG_WARNINGS?.trim().toLowerCase();
70
- return raw === "0" || raw === "false" || raw === "off";
71
- }
72
-
73
- function resolveOpenCodeModelId(modelId: string): string {
74
- if (modelId.includes("/")) {
75
- return modelId;
76
- }
77
- return `openai/${modelId}`;
78
- }
79
-
80
- export class CodexHandler extends AiSdkProviderHandler {
81
- protected getProviderDefinition() {
82
- return {
83
- moduleName: "ai-sdk-provider-codex-cli",
84
- createExportName: "createCodexCli",
85
- providerExportName: "codexCli",
86
- missingDependencyError:
87
- "Codex provider requires `ai-sdk-provider-codex-cli` and the Codex CLI at runtime. Install dependencies and run `codex` to authenticate.",
88
- };
89
- }
90
-
91
- protected getDefaultModelId(): string {
92
- return "gpt-5.3-codex";
93
- }
94
-
95
- protected async beforeLoadProviderModule(): Promise<void> {
96
- await ensureCodexZodCompatibility();
97
- }
98
-
99
- protected getProviderCreateOptions(): Record<string, unknown> {
100
- const codexOptions = this.config.codex ?? {};
101
- const defaultSettings: Record<string, unknown> = {
102
- ...(codexOptions.defaultSettings ?? {}),
103
- };
104
-
105
- if (
106
- this.config.reasoningEffort &&
107
- defaultSettings.reasoningEffort === undefined
108
- ) {
109
- defaultSettings.reasoningEffort = this.config.reasoningEffort;
110
- } else if (
111
- this.config.thinking &&
112
- defaultSettings.reasoningEffort === undefined
113
- ) {
114
- defaultSettings.reasoningEffort = "medium";
115
- }
116
-
117
- const apiKey = this.config.apiKey?.trim();
118
- const hasOAuthAccessToken =
119
- typeof this.config.accessToken === "string" &&
120
- this.config.accessToken.trim().length > 0;
121
- if (apiKey && !hasOAuthAccessToken && isLikelyOpenAIApiKey(apiKey)) {
122
- defaultSettings.env = {
123
- ...((defaultSettings.env as Record<string, string> | undefined) ?? {}),
124
- OPENAI_API_KEY: apiKey,
125
- };
126
- }
127
-
128
- return {
129
- defaultSettings:
130
- Object.keys(defaultSettings).length > 0 ? defaultSettings : undefined,
131
- };
132
- }
133
-
134
- protected getProviderModelSettings(): Record<string, unknown> | undefined {
135
- return this.config.codex?.modelSettings;
136
- }
137
-
138
- protected getStreamErrorMessage(): string {
139
- return "Codex stream failed";
140
- }
141
-
142
- protected getEmitStreamOptions(): Omit<
143
- EmitAiSdkStreamOptions,
144
- "responseId" | "errorMessage" | "calculateCost"
145
- > {
146
- return {
147
- reasoningTypes: ["reasoning-delta", "reasoning"],
148
- toolCallArgsOrder: ["args", "input"],
149
- };
150
- }
151
- }
152
-
153
- export class ClaudeCodeHandler extends AiSdkProviderHandler {
154
- protected getProviderDefinition() {
155
- return {
156
- moduleName: "ai-sdk-provider-claude-code",
157
- createExportName: "createClaudeCode",
158
- providerExportName: "claudeCode",
159
- missingDependencyError:
160
- "Claude Code provider requires `ai-sdk-provider-claude-code` at runtime. Install dependencies and run `claude login`.",
161
- };
162
- }
163
-
164
- protected getDefaultModelId(): string {
165
- return "sonnet";
166
- }
167
-
168
- protected getProviderCreateOptions(): Record<string, unknown> | undefined {
169
- return this.config.claudeCode ?? {};
170
- }
171
-
172
- protected getLoadAiSdkOptions() {
173
- return {
174
- beforeImport: () => {
175
- if (shouldDisableAiSdkWarnings()) {
176
- (globalThis as Record<string, unknown>).AI_SDK_LOG_WARNINGS = false;
177
- }
178
- },
179
- };
180
- }
181
-
182
- protected getStreamErrorMessage(): string {
183
- return "Claude Code stream failed";
184
- }
185
-
186
- protected getEmitStreamOptions(): Omit<
187
- EmitAiSdkStreamOptions,
188
- "responseId" | "errorMessage" | "calculateCost"
189
- > {
190
- return {
191
- reasoningTypes: ["reasoning-delta"],
192
- };
193
- }
194
- }
195
-
196
- export class OpenCodeHandler extends AiSdkProviderHandler {
197
- protected getProviderDefinition() {
198
- return {
199
- moduleName: "ai-sdk-provider-opencode-sdk",
200
- createExportName: "createOpencode",
201
- providerExportName: "opencode",
202
- missingDependencyError:
203
- "OpenCode provider requires `ai-sdk-provider-opencode-sdk` and OpenCode at runtime.",
204
- };
205
- }
206
-
207
- protected getDefaultModelId(): string {
208
- return "openai/gpt-5.3-codex";
209
- }
210
-
211
- protected getProviderCreateOptions(): Record<string, unknown> {
212
- const opencodeOptions = this.config.opencode ?? {};
213
- const defaultSettings = {
214
- ...(opencodeOptions.defaultSettings ?? {}),
215
- };
216
- if ((defaultSettings as Record<string, unknown>).agent === undefined) {
217
- (defaultSettings as Record<string, unknown>).agent = "general";
218
- }
219
- return {
220
- hostname: opencodeOptions.hostname,
221
- port: opencodeOptions.port,
222
- autoStartServer: opencodeOptions.autoStartServer,
223
- serverTimeout: opencodeOptions.serverTimeout,
224
- defaultSettings:
225
- Object.keys(defaultSettings).length > 0 ? defaultSettings : undefined,
226
- };
227
- }
228
-
229
- protected getProviderModelSettings(): Record<string, unknown> | undefined {
230
- return this.config.opencode?.modelSettings;
231
- }
232
-
233
- protected normalizeModelId(modelId: string): string {
234
- return resolveOpenCodeModelId(modelId);
235
- }
236
-
237
- protected getStreamErrorMessage(): string {
238
- return "OpenCode stream failed";
239
- }
240
-
241
- protected getEmitStreamOptions(): Omit<
242
- EmitAiSdkStreamOptions,
243
- "responseId" | "errorMessage" | "calculateCost"
244
- > {
245
- return {
246
- reasoningTypes: ["reasoning-delta", "reasoning"],
247
- enableTextFallback: true,
248
- };
249
- }
250
- }
251
-
252
- export class SapAiCoreHandler extends AiSdkProviderHandler {
253
- protected getProviderDefinition() {
254
- return {
255
- moduleName: "@jerome-benoit/sap-ai-provider",
256
- createExportName: "createSAPAIProvider",
257
- providerExportName: "sapai",
258
- missingDependencyError:
259
- "SAP AI Core provider requires `@jerome-benoit/sap-ai-provider` at runtime.",
260
- };
261
- }
262
-
263
- protected getDefaultModelId(): string {
264
- return "anthropic--claude-3.5-sonnet";
265
- }
266
-
267
- protected getProviderCreateOptions(): Record<string, unknown> | undefined {
268
- const sapOptions = this.config.sap ?? {};
269
- const api =
270
- sapOptions.api ??
271
- (sapOptions.useOrchestrationMode === undefined
272
- ? undefined
273
- : sapOptions.useOrchestrationMode
274
- ? "orchestration"
275
- : "foundation-models");
276
-
277
- const createOptions: Record<string, unknown> = {
278
- resourceGroup: sapOptions.resourceGroup,
279
- deploymentId: sapOptions.deploymentId,
280
- api,
281
- defaultSettings: sapOptions.defaultSettings,
282
- };
283
-
284
- const cleaned = Object.fromEntries(
285
- Object.entries(createOptions).filter(([, value]) => value !== undefined),
286
- );
287
- return Object.keys(cleaned).length > 0 ? cleaned : undefined;
288
- }
289
-
290
- protected getStreamErrorMessage(): string {
291
- return "SAP AI Core stream failed";
292
- }
293
-
294
- protected getEmitStreamOptions(): Omit<
295
- EmitAiSdkStreamOptions,
296
- "responseId" | "errorMessage" | "calculateCost"
297
- > {
298
- return {
299
- reasoningTypes: ["reasoning-delta", "reasoning"],
300
- enableToolCalls: true,
301
- toolCallArgsOrder: ["args", "input"],
302
- };
303
- }
304
- }
305
-
306
- export class MistralHandler extends AiSdkProviderHandler {
307
- protected getProviderDefinition() {
308
- return {
309
- moduleName: "@ai-sdk/mistral",
310
- createExportName: "createMistral",
311
- providerExportName: "mistral",
312
- missingDependencyError:
313
- "Mistral provider requires `@ai-sdk/mistral` at runtime.",
314
- };
315
- }
316
-
317
- protected getDefaultModelId(): string {
318
- return "mistral-medium-latest";
319
- }
320
-
321
- protected getStreamErrorMessage(): string {
322
- return "Mistral stream failed";
323
- }
324
- }
325
-
326
- export class DifyHandler extends AiSdkProviderHandler {
327
- protected getProviderDefinition() {
328
- return {
329
- moduleName: "dify-ai-provider",
330
- createExportName: "createDifyProvider",
331
- providerExportName: "difyProvider",
332
- missingDependencyError:
333
- "Dify provider requires `dify-ai-provider` at runtime.",
334
- };
335
- }
336
-
337
- protected getDefaultModelId(): string {
338
- return "default";
339
- }
340
-
341
- protected getProviderCreateOptions(): Record<string, unknown> | undefined {
342
- if (!this.config.baseUrl) {
343
- return undefined;
344
- }
345
- return {
346
- baseURL: this.config.baseUrl,
347
- };
348
- }
349
-
350
- protected getProviderModelSettings(): Record<string, unknown> | undefined {
351
- const modelSettings: Record<string, unknown> = {
352
- responseMode: "blocking",
353
- };
354
- if (this.config.apiKey) {
355
- modelSettings.apiKey = this.config.apiKey;
356
- }
357
- return modelSettings;
358
- }
359
-
360
- protected getStreamErrorMessage(): string {
361
- return "Dify stream failed";
362
- }
363
- }
364
-
365
- export function createCodexHandler(config: ProviderConfig): CodexHandler {
366
- return new CodexHandler(config);
367
- }
368
-
369
- export function createClaudeCodeHandler(
370
- config: ProviderConfig,
371
- ): ClaudeCodeHandler {
372
- return new ClaudeCodeHandler(config);
373
- }
374
-
375
- export function createOpenCodeHandler(config: ProviderConfig): OpenCodeHandler {
376
- return new OpenCodeHandler(config);
377
- }
378
-
379
- export function createSapAiCoreHandler(
380
- config: ProviderConfig,
381
- ): SapAiCoreHandler {
382
- return new SapAiCoreHandler(config);
383
- }
384
-
385
- export function createMistralHandler(config: ProviderConfig): MistralHandler {
386
- return new MistralHandler(config);
387
- }
388
-
389
- export function createDifyHandler(config: ProviderConfig): DifyHandler {
390
- return new DifyHandler(config);
391
- }