agentdog 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +244 -0
  3. package/dist/adapters/adapter-factory.d.ts +21 -0
  4. package/dist/adapters/adapter-factory.d.ts.map +1 -0
  5. package/dist/adapters/adapter-factory.js +157 -0
  6. package/dist/adapters/adapter-factory.js.map +1 -0
  7. package/dist/adapters/http-sse-adapter.d.ts +49 -0
  8. package/dist/adapters/http-sse-adapter.d.ts.map +1 -0
  9. package/dist/adapters/http-sse-adapter.js +485 -0
  10. package/dist/adapters/http-sse-adapter.js.map +1 -0
  11. package/dist/adapters/stdio-adapter.d.ts +69 -0
  12. package/dist/adapters/stdio-adapter.d.ts.map +1 -0
  13. package/dist/adapters/stdio-adapter.js +664 -0
  14. package/dist/adapters/stdio-adapter.js.map +1 -0
  15. package/dist/adapters/streamable-http-adapter.d.ts +38 -0
  16. package/dist/adapters/streamable-http-adapter.d.ts.map +1 -0
  17. package/dist/adapters/streamable-http-adapter.js +321 -0
  18. package/dist/adapters/streamable-http-adapter.js.map +1 -0
  19. package/dist/ai-gateway/anthropic-errors.d.ts +4 -0
  20. package/dist/ai-gateway/anthropic-errors.d.ts.map +1 -0
  21. package/dist/ai-gateway/anthropic-errors.js +17 -0
  22. package/dist/ai-gateway/anthropic-errors.js.map +1 -0
  23. package/dist/ai-gateway/auth.d.ts +3 -0
  24. package/dist/ai-gateway/auth.d.ts.map +1 -0
  25. package/dist/ai-gateway/auth.js +14 -0
  26. package/dist/ai-gateway/auth.js.map +1 -0
  27. package/dist/ai-gateway/auth.test.d.ts +2 -0
  28. package/dist/ai-gateway/auth.test.d.ts.map +1 -0
  29. package/dist/ai-gateway/auth.test.js +57 -0
  30. package/dist/ai-gateway/auth.test.js.map +1 -0
  31. package/dist/ai-gateway/count-tokens.d.ts +5 -0
  32. package/dist/ai-gateway/count-tokens.d.ts.map +1 -0
  33. package/dist/ai-gateway/count-tokens.js +37 -0
  34. package/dist/ai-gateway/count-tokens.js.map +1 -0
  35. package/dist/ai-gateway/count-tokens.test.d.ts +2 -0
  36. package/dist/ai-gateway/count-tokens.test.d.ts.map +1 -0
  37. package/dist/ai-gateway/count-tokens.test.js +19 -0
  38. package/dist/ai-gateway/count-tokens.test.js.map +1 -0
  39. package/dist/ai-gateway/dialects.d.ts +4 -0
  40. package/dist/ai-gateway/dialects.d.ts.map +1 -0
  41. package/dist/ai-gateway/dialects.js +15 -0
  42. package/dist/ai-gateway/dialects.js.map +1 -0
  43. package/dist/ai-gateway/gateway-server.d.ts +15 -0
  44. package/dist/ai-gateway/gateway-server.d.ts.map +1 -0
  45. package/dist/ai-gateway/gateway-server.js +121 -0
  46. package/dist/ai-gateway/gateway-server.js.map +1 -0
  47. package/dist/ai-gateway/integration.test.d.ts +2 -0
  48. package/dist/ai-gateway/integration.test.d.ts.map +1 -0
  49. package/dist/ai-gateway/integration.test.js +205 -0
  50. package/dist/ai-gateway/integration.test.js.map +1 -0
  51. package/dist/ai-gateway/ir/anthropic-in.d.ts +3 -0
  52. package/dist/ai-gateway/ir/anthropic-in.d.ts.map +1 -0
  53. package/dist/ai-gateway/ir/anthropic-in.js +121 -0
  54. package/dist/ai-gateway/ir/anthropic-in.js.map +1 -0
  55. package/dist/ai-gateway/ir/anthropic-in.test.d.ts +2 -0
  56. package/dist/ai-gateway/ir/anthropic-in.test.d.ts.map +1 -0
  57. package/dist/ai-gateway/ir/anthropic-in.test.js +93 -0
  58. package/dist/ai-gateway/ir/anthropic-in.test.js.map +1 -0
  59. package/dist/ai-gateway/ir/anthropic-sse.d.ts +22 -0
  60. package/dist/ai-gateway/ir/anthropic-sse.d.ts.map +1 -0
  61. package/dist/ai-gateway/ir/anthropic-sse.js +200 -0
  62. package/dist/ai-gateway/ir/anthropic-sse.js.map +1 -0
  63. package/dist/ai-gateway/ir/anthropic-sse.test.d.ts +2 -0
  64. package/dist/ai-gateway/ir/anthropic-sse.test.d.ts.map +1 -0
  65. package/dist/ai-gateway/ir/anthropic-sse.test.js +101 -0
  66. package/dist/ai-gateway/ir/anthropic-sse.test.js.map +1 -0
  67. package/dist/ai-gateway/ir/gemini-out.d.ts +20 -0
  68. package/dist/ai-gateway/ir/gemini-out.d.ts.map +1 -0
  69. package/dist/ai-gateway/ir/gemini-out.js +218 -0
  70. package/dist/ai-gateway/ir/gemini-out.js.map +1 -0
  71. package/dist/ai-gateway/ir/gemini-out.test.d.ts +2 -0
  72. package/dist/ai-gateway/ir/gemini-out.test.d.ts.map +1 -0
  73. package/dist/ai-gateway/ir/gemini-out.test.js +125 -0
  74. package/dist/ai-gateway/ir/gemini-out.test.js.map +1 -0
  75. package/dist/ai-gateway/ir/openai-out.d.ts +17 -0
  76. package/dist/ai-gateway/ir/openai-out.d.ts.map +1 -0
  77. package/dist/ai-gateway/ir/openai-out.js +226 -0
  78. package/dist/ai-gateway/ir/openai-out.js.map +1 -0
  79. package/dist/ai-gateway/ir/openai-out.test.d.ts +2 -0
  80. package/dist/ai-gateway/ir/openai-out.test.d.ts.map +1 -0
  81. package/dist/ai-gateway/ir/openai-out.test.js +144 -0
  82. package/dist/ai-gateway/ir/openai-out.test.js.map +1 -0
  83. package/dist/ai-gateway/ir/types.d.ts +77 -0
  84. package/dist/ai-gateway/ir/types.d.ts.map +1 -0
  85. package/dist/ai-gateway/ir/types.js +4 -0
  86. package/dist/ai-gateway/ir/types.js.map +1 -0
  87. package/dist/ai-gateway/ir-channel.d.ts +15 -0
  88. package/dist/ai-gateway/ir-channel.d.ts.map +1 -0
  89. package/dist/ai-gateway/ir-channel.js +120 -0
  90. package/dist/ai-gateway/ir-channel.js.map +1 -0
  91. package/dist/ai-gateway/model-router.d.ts +11 -0
  92. package/dist/ai-gateway/model-router.d.ts.map +1 -0
  93. package/dist/ai-gateway/model-router.js +27 -0
  94. package/dist/ai-gateway/model-router.js.map +1 -0
  95. package/dist/ai-gateway/model-router.test.d.ts +2 -0
  96. package/dist/ai-gateway/model-router.test.d.ts.map +1 -0
  97. package/dist/ai-gateway/model-router.test.js +43 -0
  98. package/dist/ai-gateway/model-router.test.js.map +1 -0
  99. package/dist/ai-gateway/passthrough.d.ts +9 -0
  100. package/dist/ai-gateway/passthrough.d.ts.map +1 -0
  101. package/dist/ai-gateway/passthrough.js +81 -0
  102. package/dist/ai-gateway/passthrough.js.map +1 -0
  103. package/dist/ai-gateway/passthrough.test.d.ts +2 -0
  104. package/dist/ai-gateway/passthrough.test.d.ts.map +1 -0
  105. package/dist/ai-gateway/passthrough.test.js +108 -0
  106. package/dist/ai-gateway/passthrough.test.js.map +1 -0
  107. package/dist/ai-gateway/upstream/model-lister.d.ts +13 -0
  108. package/dist/ai-gateway/upstream/model-lister.d.ts.map +1 -0
  109. package/dist/ai-gateway/upstream/model-lister.js +61 -0
  110. package/dist/ai-gateway/upstream/model-lister.js.map +1 -0
  111. package/dist/ai-gateway/upstream/provider-client.d.ts +20 -0
  112. package/dist/ai-gateway/upstream/provider-client.d.ts.map +1 -0
  113. package/dist/ai-gateway/upstream/provider-client.js +76 -0
  114. package/dist/ai-gateway/upstream/provider-client.js.map +1 -0
  115. package/dist/ai-gateway/upstream/provider-client.test.d.ts +2 -0
  116. package/dist/ai-gateway/upstream/provider-client.test.d.ts.map +1 -0
  117. package/dist/ai-gateway/upstream/provider-client.test.js +69 -0
  118. package/dist/ai-gateway/upstream/provider-client.test.js.map +1 -0
  119. package/dist/cli/cli-main.d.ts +7 -0
  120. package/dist/cli/cli-main.d.ts.map +1 -0
  121. package/dist/cli/cli-main.js +116 -0
  122. package/dist/cli/cli-main.js.map +1 -0
  123. package/dist/cli/cli-router.d.ts +20 -0
  124. package/dist/cli/cli-router.d.ts.map +1 -0
  125. package/dist/cli/cli-router.js +271 -0
  126. package/dist/cli/cli-router.js.map +1 -0
  127. package/dist/cli/cli-utils.d.ts +30 -0
  128. package/dist/cli/cli-utils.d.ts.map +1 -0
  129. package/dist/cli/cli-utils.js +219 -0
  130. package/dist/cli/cli-utils.js.map +1 -0
  131. package/dist/cli/commands/audit-commands.d.ts +30 -0
  132. package/dist/cli/commands/audit-commands.d.ts.map +1 -0
  133. package/dist/cli/commands/audit-commands.js +417 -0
  134. package/dist/cli/commands/audit-commands.js.map +1 -0
  135. package/dist/cli/commands/autostart-command.d.ts +21 -0
  136. package/dist/cli/commands/autostart-command.d.ts.map +1 -0
  137. package/dist/cli/commands/autostart-command.js +243 -0
  138. package/dist/cli/commands/autostart-command.js.map +1 -0
  139. package/dist/cli/commands/autostart-command.test.d.ts +2 -0
  140. package/dist/cli/commands/autostart-command.test.d.ts.map +1 -0
  141. package/dist/cli/commands/autostart-command.test.js +35 -0
  142. package/dist/cli/commands/autostart-command.test.js.map +1 -0
  143. package/dist/cli/commands/config-commands.d.ts +30 -0
  144. package/dist/cli/commands/config-commands.d.ts.map +1 -0
  145. package/dist/cli/commands/config-commands.js +1013 -0
  146. package/dist/cli/commands/config-commands.js.map +1 -0
  147. package/dist/cli/commands/daemon-commands.d.ts +76 -0
  148. package/dist/cli/commands/daemon-commands.d.ts.map +1 -0
  149. package/dist/cli/commands/daemon-commands.js +451 -0
  150. package/dist/cli/commands/daemon-commands.js.map +1 -0
  151. package/dist/cli/commands/detect-commands.d.ts +17 -0
  152. package/dist/cli/commands/detect-commands.d.ts.map +1 -0
  153. package/dist/cli/commands/detect-commands.js +293 -0
  154. package/dist/cli/commands/detect-commands.js.map +1 -0
  155. package/dist/cli/commands/diagnose-commands.d.ts +19 -0
  156. package/dist/cli/commands/diagnose-commands.d.ts.map +1 -0
  157. package/dist/cli/commands/diagnose-commands.js +326 -0
  158. package/dist/cli/commands/diagnose-commands.js.map +1 -0
  159. package/dist/cli/commands/optimize-commands.d.ts +14 -0
  160. package/dist/cli/commands/optimize-commands.d.ts.map +1 -0
  161. package/dist/cli/commands/optimize-commands.js +189 -0
  162. package/dist/cli/commands/optimize-commands.js.map +1 -0
  163. package/dist/cli/commands/proxy-command.d.ts +27 -0
  164. package/dist/cli/commands/proxy-command.d.ts.map +1 -0
  165. package/dist/cli/commands/proxy-command.js +212 -0
  166. package/dist/cli/commands/proxy-command.js.map +1 -0
  167. package/dist/cli/commands/start-command.d.ts +22 -0
  168. package/dist/cli/commands/start-command.d.ts.map +1 -0
  169. package/dist/cli/commands/start-command.js +275 -0
  170. package/dist/cli/commands/start-command.js.map +1 -0
  171. package/dist/config/config-manager.d.ts +125 -0
  172. package/dist/config/config-manager.d.ts.map +1 -0
  173. package/dist/config/config-manager.js +569 -0
  174. package/dist/config/config-manager.js.map +1 -0
  175. package/dist/config/config-manager.test.d.ts +2 -0
  176. package/dist/config/config-manager.test.d.ts.map +1 -0
  177. package/dist/config/config-manager.test.js +209 -0
  178. package/dist/config/config-manager.test.js.map +1 -0
  179. package/dist/core/auto-config-generator.d.ts +55 -0
  180. package/dist/core/auto-config-generator.d.ts.map +1 -0
  181. package/dist/core/auto-config-generator.js +278 -0
  182. package/dist/core/auto-config-generator.js.map +1 -0
  183. package/dist/core/mcpdog-server.d.ts +49 -0
  184. package/dist/core/mcpdog-server.d.ts.map +1 -0
  185. package/dist/core/mcpdog-server.js +552 -0
  186. package/dist/core/mcpdog-server.js.map +1 -0
  187. package/dist/core/protocol-detector.d.ts +56 -0
  188. package/dist/core/protocol-detector.d.ts.map +1 -0
  189. package/dist/core/protocol-detector.js +365 -0
  190. package/dist/core/protocol-detector.js.map +1 -0
  191. package/dist/daemon/daemon-client.d.ts +34 -0
  192. package/dist/daemon/daemon-client.d.ts.map +1 -0
  193. package/dist/daemon/daemon-client.js +130 -0
  194. package/dist/daemon/daemon-client.js.map +1 -0
  195. package/dist/daemon/daemon-client.test.d.ts +2 -0
  196. package/dist/daemon/daemon-client.test.d.ts.map +1 -0
  197. package/dist/daemon/daemon-client.test.js +77 -0
  198. package/dist/daemon/daemon-client.test.js.map +1 -0
  199. package/dist/daemon/daemon-info.d.ts +7 -0
  200. package/dist/daemon/daemon-info.d.ts.map +1 -0
  201. package/dist/daemon/daemon-info.js +34 -0
  202. package/dist/daemon/daemon-info.js.map +1 -0
  203. package/dist/daemon/daemon-info.test.d.ts +2 -0
  204. package/dist/daemon/daemon-info.test.d.ts.map +1 -0
  205. package/dist/daemon/daemon-info.test.js +57 -0
  206. package/dist/daemon/daemon-info.test.js.map +1 -0
  207. package/dist/daemon/daemon-web-server.ai.test.d.ts +2 -0
  208. package/dist/daemon/daemon-web-server.ai.test.d.ts.map +1 -0
  209. package/dist/daemon/daemon-web-server.ai.test.js +119 -0
  210. package/dist/daemon/daemon-web-server.ai.test.js.map +1 -0
  211. package/dist/daemon/daemon-web-server.d.ts +59 -0
  212. package/dist/daemon/daemon-web-server.d.ts.map +1 -0
  213. package/dist/daemon/daemon-web-server.js +1236 -0
  214. package/dist/daemon/daemon-web-server.js.map +1 -0
  215. package/dist/daemon/daemon-web-server.test.d.ts +2 -0
  216. package/dist/daemon/daemon-web-server.test.d.ts.map +1 -0
  217. package/dist/daemon/daemon-web-server.test.js +93 -0
  218. package/dist/daemon/daemon-web-server.test.js.map +1 -0
  219. package/dist/daemon/mcpdog-daemon.d.ts +42 -0
  220. package/dist/daemon/mcpdog-daemon.d.ts.map +1 -0
  221. package/dist/daemon/mcpdog-daemon.js +302 -0
  222. package/dist/daemon/mcpdog-daemon.js.map +1 -0
  223. package/dist/daemon/stdio-proxy.d.ts +17 -0
  224. package/dist/daemon/stdio-proxy.d.ts.map +1 -0
  225. package/dist/daemon/stdio-proxy.js +143 -0
  226. package/dist/daemon/stdio-proxy.js.map +1 -0
  227. package/dist/index.d.ts +14 -0
  228. package/dist/index.d.ts.map +1 -0
  229. package/dist/index.js +198 -0
  230. package/dist/index.js.map +1 -0
  231. package/dist/intent-analyzer.d.ts +27 -0
  232. package/dist/intent-analyzer.d.ts.map +1 -0
  233. package/dist/intent-analyzer.js +140 -0
  234. package/dist/intent-analyzer.js.map +1 -0
  235. package/dist/logging/server-log-manager.d.ts +75 -0
  236. package/dist/logging/server-log-manager.d.ts.map +1 -0
  237. package/dist/logging/server-log-manager.js +185 -0
  238. package/dist/logging/server-log-manager.js.map +1 -0
  239. package/dist/mcp-registry.d.ts +35 -0
  240. package/dist/mcp-registry.d.ts.map +1 -0
  241. package/dist/mcp-registry.js +166 -0
  242. package/dist/mcp-registry.js.map +1 -0
  243. package/dist/middleware/auth.d.ts +5 -0
  244. package/dist/middleware/auth.d.ts.map +1 -0
  245. package/dist/middleware/auth.js +81 -0
  246. package/dist/middleware/auth.js.map +1 -0
  247. package/dist/mock-tool-database.d.ts +41 -0
  248. package/dist/mock-tool-database.d.ts.map +1 -0
  249. package/dist/mock-tool-database.js +461 -0
  250. package/dist/mock-tool-database.js.map +1 -0
  251. package/dist/proxy-server-manager.d.ts +11 -0
  252. package/dist/proxy-server-manager.d.ts.map +1 -0
  253. package/dist/proxy-server-manager.js +144 -0
  254. package/dist/proxy-server-manager.js.map +1 -0
  255. package/dist/router/tool-router.d.ts +61 -0
  256. package/dist/router/tool-router.d.ts.map +1 -0
  257. package/dist/router/tool-router.js +539 -0
  258. package/dist/router/tool-router.js.map +1 -0
  259. package/dist/router/tool-router.test.d.ts +2 -0
  260. package/dist/router/tool-router.test.d.ts.map +1 -0
  261. package/dist/router/tool-router.test.js +113 -0
  262. package/dist/router/tool-router.test.js.map +1 -0
  263. package/dist/streamable-http-server.d.ts +27 -0
  264. package/dist/streamable-http-server.d.ts.map +1 -0
  265. package/dist/streamable-http-server.js +302 -0
  266. package/dist/streamable-http-server.js.map +1 -0
  267. package/dist/tool-finder.d.ts +21 -0
  268. package/dist/tool-finder.d.ts.map +1 -0
  269. package/dist/tool-finder.js +86 -0
  270. package/dist/tool-finder.js.map +1 -0
  271. package/dist/tool-recommender.d.ts +23 -0
  272. package/dist/tool-recommender.d.ts.map +1 -0
  273. package/dist/tool-recommender.js +200 -0
  274. package/dist/tool-recommender.js.map +1 -0
  275. package/dist/types/index.d.ts +145 -0
  276. package/dist/types/index.d.ts.map +1 -0
  277. package/dist/types/index.js +2 -0
  278. package/dist/types/index.js.map +1 -0
  279. package/dist/utils/server-name-validator.d.ts +47 -0
  280. package/dist/utils/server-name-validator.d.ts.map +1 -0
  281. package/dist/utils/server-name-validator.js +156 -0
  282. package/dist/utils/server-name-validator.js.map +1 -0
  283. package/dist/web/web-server.d.ts +44 -0
  284. package/dist/web/web-server.d.ts.map +1 -0
  285. package/dist/web/web-server.js +500 -0
  286. package/dist/web/web-server.js.map +1 -0
  287. package/package.json +68 -0
  288. package/web/dist/assets/index-DMVhVtNU.css +1 -0
  289. package/web/dist/assets/index-VMXIgcOH.js +92 -0
  290. package/web/dist/assets/index-VMXIgcOH.js.map +1 -0
  291. package/web/dist/index.html +14 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-out.js","sourceRoot":"","sources":["../../../src/ai-gateway/ir/openai-out.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=openai-out.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-out.test.d.ts","sourceRoot":"","sources":["../../../src/ai-gateway/ir/openai-out.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,144 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { irToOpenAI, OpenAIStreamState, openaiSSELineToEvents, openaiFinalToIREvents } from './openai-out.js';
3
+ const provider = {
4
+ id: '1', slug: 'deepseek', dialect: 'openai', baseUrl: 'https://api.deepseek.com', apiKey: 'sk', enabled: true,
5
+ };
6
+ function baseIR(over = {}) {
7
+ return {
8
+ system: [], messages: [], tools: [], toolChoice: null,
9
+ sampling: { maxTokens: 100 }, stream: false, ...over,
10
+ };
11
+ }
12
+ describe('irToOpenAI(请求方向)', () => {
13
+ it('system 分块合并为单字符串 system 消息', () => {
14
+ const { body } = irToOpenAI(baseIR({ system: [{ kind: 'text', text: 'A' }, { kind: 'text', text: 'B' }] }), provider, 'm');
15
+ expect(body.messages[0]).toEqual({ role: 'system', content: 'A\n\nB' });
16
+ });
17
+ it('图片转 image_url data URL', () => {
18
+ const { body } = irToOpenAI(baseIR({
19
+ messages: [{ role: 'user', content: [{ kind: 'image', mime: 'image/png', data: 'AAA' }] }],
20
+ }), provider, 'm');
21
+ expect(body.messages[0].content[0].image_url.url).toBe('data:image/png;base64,AAA');
22
+ });
23
+ it('tool_use 转 tool_calls(arguments 为 JSON 字符串)、tool_result 紧跟配对', () => {
24
+ const { body } = irToOpenAI(baseIR({
25
+ messages: [
26
+ { role: 'user', content: [{ kind: 'text', text: 'run ls' }] },
27
+ { role: 'assistant', content: [{ kind: 'toolUse', id: 'c1', name: 'bash', args: { cmd: 'ls' } }] },
28
+ { role: 'user', content: [{ kind: 'toolResult', toolUseId: 'c1', content: 'a.txt', isError: false }] },
29
+ ],
30
+ }), provider, 'm');
31
+ const assistant = body.messages[1];
32
+ expect(assistant.role).toBe('assistant');
33
+ expect(assistant.tool_calls[0]).toEqual({
34
+ id: 'c1', type: 'function', function: { name: 'bash', arguments: '{"cmd":"ls"}' },
35
+ });
36
+ const tool = body.messages[2];
37
+ expect(tool).toEqual({ role: 'tool', tool_call_id: 'c1', content: 'a.txt' });
38
+ });
39
+ it('缺失 tool_result 时补空 content 容错', () => {
40
+ const { body } = irToOpenAI(baseIR({
41
+ messages: [
42
+ { role: 'assistant', content: [{ kind: 'toolUse', id: 'c1', name: 'bash', args: {} }] },
43
+ { role: 'user', content: [{ kind: 'text', text: '继续' }] },
44
+ ],
45
+ }), provider, 'm');
46
+ // assistant tool_calls 之后必须紧跟 tool 消息(空 content),user 文本在后
47
+ expect(body.messages[1]).toEqual({ role: 'tool', tool_call_id: 'c1', content: '' });
48
+ expect(body.messages[2].role).toBe('user');
49
+ });
50
+ it('tools 包装 type:function、tool_choice 三态', () => {
51
+ const tools = [{ name: 'bash', description: 'run', inputSchema: { type: 'object' } }];
52
+ let r = irToOpenAI(baseIR({ tools, toolChoice: { mode: 'auto' } }), provider, 'm');
53
+ expect(r.body.tools[0]).toEqual({ type: 'function', function: { name: 'bash', description: 'run', parameters: { type: 'object' } } });
54
+ expect(r.body.tool_choice).toBe('auto');
55
+ r = irToOpenAI(baseIR({ tools, toolChoice: { mode: 'required' } }), provider, 'm');
56
+ expect(r.body.tool_choice).toBe('required');
57
+ r = irToOpenAI(baseIR({ tools, toolChoice: { mode: 'specific', name: 'bash' } }), provider, 'm');
58
+ expect(r.body.tool_choice).toEqual({ type: 'function', function: { name: 'bash' } });
59
+ });
60
+ it('采样参数:top_k 丢弃、stop 映射、stream 带 stream_options', () => {
61
+ const ir = baseIR({
62
+ sampling: { maxTokens: 7, temperature: 0.5, topP: 0.9, topK: 40, stopSequences: ['END'] },
63
+ });
64
+ const { body } = irToOpenAI(ir, provider, 'm');
65
+ expect(body.max_tokens).toBe(7);
66
+ expect(body.temperature).toBe(0.5);
67
+ expect(body.top_p).toBe(0.9);
68
+ expect(body).not.toHaveProperty('top_k');
69
+ expect(body.stop).toEqual(['END']);
70
+ expect(body).not.toHaveProperty('stream');
71
+ const { body: sbody } = irToOpenAI({ ...ir, stream: true }, provider, 'm');
72
+ expect(sbody.stream).toBe(true);
73
+ expect(sbody.stream_options).toEqual({ include_usage: true });
74
+ });
75
+ it('URL 与认证头', () => {
76
+ const r = irToOpenAI(baseIR(), provider, 'm');
77
+ expect(r.url).toBe('https://api.deepseek.com/v1/chat/completions');
78
+ expect(r.headers.authorization).toBe('Bearer sk');
79
+ const p2 = { ...provider, baseUrl: 'https://x.com/v1/' };
80
+ expect(irToOpenAI(baseIR(), p2, 'm').url).toBe('https://x.com/v1/chat/completions');
81
+ });
82
+ });
83
+ describe('OpenAI SSE → IR 事件(流式)', () => {
84
+ it('文本 delta、finish、usage 末帧', () => {
85
+ const state = new OpenAIStreamState();
86
+ const ev1 = openaiSSELineToEvents('data: {"choices":[{"delta":{"content":"Hi"},"finish_reason":null}]}', state);
87
+ expect(ev1).toEqual([{ type: 'textDelta', text: 'Hi' }]);
88
+ const ev2 = openaiSSELineToEvents('data: {"choices":[{"delta":{},"finish_reason":"stop"}]}', state);
89
+ expect(ev2).toEqual([{ type: 'finish', reason: 'stop' }]);
90
+ const ev3 = openaiSSELineToEvents('data: {"choices":[],"usage":{"prompt_tokens":10,"completion_tokens":5}}', state);
91
+ expect(ev3).toEqual([{ type: 'usage', input: 10, output: 5 }]);
92
+ expect(openaiSSELineToEvents('data: [DONE]', state)).toEqual([]);
93
+ });
94
+ it('多工具增量按 index 区分,首帧发 toolCallStart', () => {
95
+ const state = new OpenAIStreamState();
96
+ const ev1 = openaiSSELineToEvents('data: {"choices":[{"delta":{"tool_calls":[{"index":0,"id":"c1","function":{"name":"bash","arguments":"{\\"cm"}}]}}]}', state);
97
+ const ev2 = openaiSSELineToEvents('data: {"choices":[{"delta":{"tool_calls":[{"index":0,"function":{"arguments":"d\\":\\"ls\\"}"}}]}}]}', state);
98
+ const ev3 = openaiSSELineToEvents('data: {"choices":[{"delta":{"tool_calls":[{"index":1,"id":"c2","function":{"name":"read","arguments":"{}"}}]}}]}', state);
99
+ const ev4 = openaiSSELineToEvents('data: {"choices":[{"delta":{},"finish_reason":"tool_calls"}]}', state);
100
+ expect(ev1).toEqual([
101
+ { type: 'toolCallStart', id: 'c1', name: 'bash' },
102
+ { type: 'toolCallDelta', argsDelta: '{"cm' },
103
+ ]);
104
+ expect(ev2).toEqual([{ type: 'toolCallDelta', argsDelta: 'd":"ls"}' }]);
105
+ expect(ev3).toEqual([
106
+ { type: 'toolCallStart', id: 'c2', name: 'read' },
107
+ { type: 'toolCallDelta', argsDelta: '{}' },
108
+ ]);
109
+ // finish(tool_calls) + 两个 toolCallEnd
110
+ expect(ev4).toEqual([
111
+ { type: 'finish', reason: 'tool_calls' },
112
+ { type: 'toolCallEnd' },
113
+ { type: 'toolCallEnd' },
114
+ ]);
115
+ });
116
+ it('reasoning_content 丢弃', () => {
117
+ const state = new OpenAIStreamState();
118
+ const ev = openaiSSELineToEvents('data: {"choices":[{"delta":{"reasoning_content":"thinking..."}}]}', state);
119
+ expect(ev).toEqual([]);
120
+ });
121
+ });
122
+ describe('openaiFinalToIREvents(非流式)', () => {
123
+ it('文本 + 工具 + usage + finish 一次性转换', () => {
124
+ const events = openaiFinalToIREvents({
125
+ choices: [{
126
+ finish_reason: 'tool_calls',
127
+ message: {
128
+ content: '',
129
+ tool_calls: [{ id: 'c1', type: 'function', function: { name: 'bash', arguments: '{"cmd":"ls"}' } }],
130
+ },
131
+ }],
132
+ usage: { prompt_tokens: 8, completion_tokens: 2 },
133
+ });
134
+ expect(events).toEqual([
135
+ { type: 'messageStart' },
136
+ { type: 'toolCallStart', id: 'c1', name: 'bash' },
137
+ { type: 'toolCallDelta', argsDelta: '{"cmd":"ls"}' },
138
+ { type: 'toolCallEnd' },
139
+ { type: 'usage', input: 8, output: 2 },
140
+ { type: 'finish', reason: 'tool_calls' },
141
+ ]);
142
+ });
143
+ });
144
+ //# sourceMappingURL=openai-out.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-out.test.js","sourceRoot":"","sources":["../../../src/ai-gateway/ir/openai-out.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ export interface IRTextPart {
2
+ kind: 'text';
3
+ text: string;
4
+ cache?: boolean;
5
+ }
6
+ export interface IRImagePart {
7
+ kind: 'image';
8
+ mime: string;
9
+ data: string;
10
+ }
11
+ export interface IRToolUsePart {
12
+ kind: 'toolUse';
13
+ id: string;
14
+ name: string;
15
+ args: any;
16
+ }
17
+ export interface IRToolResultPart {
18
+ kind: 'toolResult';
19
+ toolUseId: string;
20
+ content: string;
21
+ isError: boolean;
22
+ }
23
+ export type IRPart = IRTextPart | IRImagePart | IRToolUsePart | IRToolResultPart;
24
+ export interface IRMessage {
25
+ role: 'user' | 'assistant';
26
+ content: IRPart[];
27
+ }
28
+ export interface IRTool {
29
+ name: string;
30
+ description: string;
31
+ inputSchema: any;
32
+ }
33
+ export interface IRToolChoice {
34
+ mode: 'auto' | 'none' | 'required' | 'specific';
35
+ name?: string;
36
+ }
37
+ export interface IRSampling {
38
+ maxTokens: number;
39
+ temperature?: number;
40
+ topP?: number;
41
+ topK?: number;
42
+ stopSequences?: string[];
43
+ }
44
+ export interface IRRequest {
45
+ system: IRTextPart[];
46
+ messages: IRMessage[];
47
+ tools: IRTool[];
48
+ toolChoice: IRToolChoice | null;
49
+ sampling: IRSampling;
50
+ stream: boolean;
51
+ }
52
+ export type IREvent = {
53
+ type: 'messageStart';
54
+ } | {
55
+ type: 'textDelta';
56
+ text: string;
57
+ } | {
58
+ type: 'toolCallStart';
59
+ id: string;
60
+ name: string;
61
+ } | {
62
+ type: 'toolCallDelta';
63
+ argsDelta: string;
64
+ } | {
65
+ type: 'toolCallEnd';
66
+ } | {
67
+ type: 'usage';
68
+ input: number;
69
+ output: number;
70
+ } | {
71
+ type: 'finish';
72
+ reason: 'stop' | 'tool_calls' | 'length';
73
+ } | {
74
+ type: 'error';
75
+ message: string;
76
+ };
77
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/ai-gateway/ir/types.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,GAAG,CAAC;CACX;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAEjF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,GAAG,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,YAAY,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,UAAU,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CACjB;AAID,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,QAAQ,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ // IR(中间表示)消息模型:Anthropic 入站解析为目标,openai/gemini 出口从它构造;
2
+ // 上游响应归一为 IREvent 事件流后统一转 Anthropic SSE 出站。
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/ai-gateway/ir/types.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,4CAA4C"}
@@ -0,0 +1,15 @@
1
+ import { Request, Response } from 'express';
2
+ import { AIProviderConfig } from '../types/index.js';
3
+ import { IREvent, IRRequest } from './ir/types.js';
4
+ export interface DialectCodec {
5
+ buildRequest(ir: IRRequest, provider: AIProviderConfig, model: string): {
6
+ url: string;
7
+ headers: Record<string, string>;
8
+ body: any;
9
+ };
10
+ parseSSELine(line: string, state: any): IREvent[] | null;
11
+ createState(): any;
12
+ parseFinal(json: any): IREvent[];
13
+ }
14
+ export declare function handleIRChannel(req: Request, res: Response, provider: AIProviderConfig, model: string, codec: DialectCodec): Promise<void>;
15
+ //# sourceMappingURL=ir-channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir-channel.d.ts","sourceRoot":"","sources":["../../src/ai-gateway/ir-channel.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAOnD,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG;QACtE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;KACzD,CAAC;IAEF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;IACzD,WAAW,IAAI,GAAG,CAAC;IAEnB,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,EAAE,CAAC;CAClC;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAoHf"}
@@ -0,0 +1,120 @@
1
+ import { anthropicToIR } from './ir/anthropic-in.js';
2
+ import { AnthropicSSEWriter, aggregateIR } from './ir/anthropic-sse.js';
3
+ import { sendUpstream } from './upstream/provider-client.js';
4
+ import { anthropicError, mapUpstreamStatus } from './anthropic-errors.js';
5
+ import { UPSTREAM_HEADER_TIMEOUT_MS, STREAM_WATCHDOG_MS } from './passthrough.js';
6
+ export async function handleIRChannel(req, res, provider, model, codec) {
7
+ const ir = anthropicToIR(req.body);
8
+ const { url, headers, body } = codec.buildRequest(ir, provider, model);
9
+ const abort = new AbortController();
10
+ res.on('close', () => abort.abort());
11
+ let upstream;
12
+ try {
13
+ upstream = await sendUpstream({
14
+ url,
15
+ method: 'POST',
16
+ headers,
17
+ body: JSON.stringify(body),
18
+ timeoutMs: UPSTREAM_HEADER_TIMEOUT_MS,
19
+ signal: abort.signal,
20
+ });
21
+ }
22
+ catch (error) {
23
+ if (abort.signal.aborted) {
24
+ return;
25
+ }
26
+ const isTimeout = /timeout/i.test(error.message);
27
+ anthropicError(res, isTimeout ? 504 : 502, 'api_error', `upstream request failed: ${error.message}`);
28
+ return;
29
+ }
30
+ // 上游错误:状态码透传,错误体转 Anthropic 格式、message 保留原文
31
+ if (upstream.status !== 200) {
32
+ if (res.writableEnded || abort.signal.aborted) {
33
+ return;
34
+ }
35
+ const text = await upstream.text().catch(() => '');
36
+ anthropicError(res, upstream.status, mapUpstreamStatus(upstream.status), text.slice(0, 2000) || `upstream ${upstream.status}`);
37
+ return;
38
+ }
39
+ const state = codec.createState();
40
+ if (!ir.stream) {
41
+ // 非流式:聚合为单个 Anthropic Message JSON
42
+ try {
43
+ const text = await upstream.text();
44
+ const events = codec.parseFinal(JSON.parse(text));
45
+ const message = aggregateIR(events, model);
46
+ res.status(200).json(message);
47
+ }
48
+ catch (error) {
49
+ if (!res.writableEnded && !abort.signal.aborted) {
50
+ anthropicError(res, 502, 'api_error', `failed to process upstream response: ${error.message}`);
51
+ }
52
+ }
53
+ return;
54
+ }
55
+ // 流式:延迟提交——首个语义事件(textDelta/toolCallStart)前不写 message_start
56
+ const writer = new AnthropicSSEWriter(res, model);
57
+ const buffered = [{ type: 'messageStart' }];
58
+ let committed = false;
59
+ const emit = (ev) => {
60
+ if (!committed) {
61
+ if (ev.type === 'textDelta' || ev.type === 'toolCallStart') {
62
+ committed = true;
63
+ for (const b of buffered) {
64
+ writer.write(b);
65
+ }
66
+ writer.write(ev);
67
+ }
68
+ else if (ev.type === 'error') {
69
+ // 首个语义事件前失败:可返回正确状态码的 JSON 错误体
70
+ if (!res.headersSent) {
71
+ anthropicError(res, 502, 'api_error', ev.message);
72
+ }
73
+ }
74
+ else {
75
+ buffered.push(ev);
76
+ }
77
+ return;
78
+ }
79
+ writer.write(ev);
80
+ };
81
+ let lastByteAt = Date.now();
82
+ const watchdog = setInterval(() => {
83
+ if (Date.now() - lastByteAt > STREAM_WATCHDOG_MS) {
84
+ clearInterval(watchdog);
85
+ writer.write({ type: 'error', message: 'upstream stream stalled' });
86
+ writer.finish();
87
+ abort.abort();
88
+ }
89
+ }, 30_000);
90
+ try {
91
+ await upstream.stream(line => {
92
+ lastByteAt = Date.now();
93
+ const events = codec.parseSSELine(line, state);
94
+ if (events) {
95
+ for (const ev of events) {
96
+ emit(ev);
97
+ }
98
+ }
99
+ });
100
+ if (!committed && !res.headersSent && !res.writableEnded) {
101
+ // 无任何语义事件(如空回复):正常提交空消息
102
+ committed = true;
103
+ for (const b of buffered) {
104
+ writer.write(b);
105
+ }
106
+ }
107
+ writer.finish();
108
+ }
109
+ catch (error) {
110
+ clearInterval(watchdog);
111
+ if (!res.headersSent && !res.writableEnded && !abort.signal.aborted) {
112
+ anthropicError(res, 502, 'api_error', `upstream stream failed: ${error.message}`);
113
+ }
114
+ else {
115
+ writer.write({ type: 'error', message: error.message });
116
+ writer.finish();
117
+ }
118
+ }
119
+ }
120
+ //# sourceMappingURL=ir-channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir-channel.js","sourceRoot":"","sources":["../../src/ai-gateway/ir-channel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { AIProviderConfig } from '../types/index.js';
2
+ export interface ResolvedModel {
3
+ provider: AIProviderConfig;
4
+ model: string;
5
+ }
6
+ export declare class ModelRouteError extends Error {
7
+ availableSlugs: string[];
8
+ constructor(message: string, availableSlugs: string[]);
9
+ }
10
+ export declare function resolveModel(model: string, providers: AIProviderConfig[]): ResolvedModel;
11
+ //# sourceMappingURL=model-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-router.d.ts","sourceRoot":"","sources":["../../src/ai-gateway/model-router.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,cAAc,EAAE,MAAM,EAAE,CAAC;gBACb,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE;CAKtD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,aAAa,CAyBxF"}
@@ -0,0 +1,27 @@
1
+ export class ModelRouteError extends Error {
2
+ availableSlugs;
3
+ constructor(message, availableSlugs) {
4
+ super(message);
5
+ this.name = 'ModelRouteError';
6
+ this.availableSlugs = availableSlugs;
7
+ }
8
+ }
9
+ export function resolveModel(model, providers) {
10
+ const enabled = providers.filter(p => p.enabled);
11
+ const availableSlugs = enabled.map(p => p.slug);
12
+ const colonIndex = model.indexOf(':');
13
+ if (!model || colonIndex === -1) {
14
+ throw new ModelRouteError(`invalid model "${model}": expected format "slug:modelId" (e.g. "deepseek:deepseek-chat")`, availableSlugs);
15
+ }
16
+ const slug = model.slice(0, colonIndex);
17
+ const realModel = model.slice(colonIndex + 1);
18
+ const provider = enabled.find(p => p.slug === slug);
19
+ if (!provider) {
20
+ throw new ModelRouteError(`Unknown provider slug "${slug}", available: ${availableSlugs.join(', ') || '(none)'}`, availableSlugs);
21
+ }
22
+ if (!realModel) {
23
+ throw new ModelRouteError(`invalid model "${model}": empty model id after slug`, availableSlugs);
24
+ }
25
+ return { provider, model: realModel };
26
+ }
27
+ //# sourceMappingURL=model-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-router.js","sourceRoot":"","sources":["../../src/ai-gateway/model-router.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,cAAc,CAAW;IACzB,YAAY,OAAe,EAAE,cAAwB;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;CACF;AAED,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,SAA6B;IACvE,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,eAAe,CACvB,kBAAkB,KAAK,mEAAmE,EAC1F,cAAc,CACf,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,eAAe,CACvB,0BAA0B,IAAI,iBAAiB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE,EACtF,cAAc,CACf,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,eAAe,CAAC,kBAAkB,KAAK,8BAA8B,EAAE,cAAc,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACxC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=model-router.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-router.test.d.ts","sourceRoot":"","sources":["../../src/ai-gateway/model-router.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { resolveModel, ModelRouteError } from './model-router.js';
3
+ const providers = [
4
+ { id: '1', slug: 'deepseek', dialect: 'openai', baseUrl: 'https://api.deepseek.com', apiKey: 'k', enabled: true },
5
+ { id: '2', slug: 'or', dialect: 'openai', baseUrl: 'https://x', apiKey: 'k', enabled: false },
6
+ ];
7
+ describe('resolveModel', () => {
8
+ it('解析 slug 与模型', () => {
9
+ const r = resolveModel('deepseek:deepseek-chat', providers);
10
+ expect(r.provider.id).toBe('1');
11
+ expect(r.model).toBe('deepseek-chat');
12
+ });
13
+ it('模型名含斜杠原样透传', () => {
14
+ expect(resolveModel('deepseek:openrouter/anthropic/claude-sonnet-4', providers).model)
15
+ .toBe('openrouter/anthropic/claude-sonnet-4');
16
+ });
17
+ it('模型名含冒号只在第一个冒号分割', () => {
18
+ expect(resolveModel('deepseek:a:b', providers).model).toBe('a:b');
19
+ });
20
+ it('无冒号抛错并提示格式', () => {
21
+ expect(() => resolveModel('deepseek-chat', providers)).toThrow(ModelRouteError);
22
+ expect(() => resolveModel('deepseek-chat', providers)).toThrowError(/slug:model/);
23
+ });
24
+ it('未知 slug 抛错并列出可用 slug', () => {
25
+ try {
26
+ resolveModel('foo:bar', providers);
27
+ expect.unreachable('should throw');
28
+ }
29
+ catch (e) {
30
+ expect(e).toBeInstanceOf(ModelRouteError);
31
+ expect(e.availableSlugs).toEqual(['deepseek']);
32
+ expect(e.message).toContain('foo');
33
+ expect(e.message).toContain('deepseek');
34
+ }
35
+ });
36
+ it('禁用 slug 不参与寻址', () => {
37
+ expect(() => resolveModel('or:bar', providers)).toThrow(ModelRouteError);
38
+ });
39
+ it('空串抛错', () => {
40
+ expect(() => resolveModel('', providers)).toThrow(ModelRouteError);
41
+ });
42
+ });
43
+ //# sourceMappingURL=model-router.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-router.test.js","sourceRoot":"","sources":["../../src/ai-gateway/model-router.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGlE,MAAM,SAAS,GAAuB;IACpC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,0BAA0B,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;IACjH,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;CAC9F,CAAC;AAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;QACrB,MAAM,CAAC,GAAG,YAAY,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;QAC5D,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;QACpB,MAAM,CAAC,YAAY,CAAC,+CAA+C,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC;aACnF,IAAI,CAAC,sCAAsC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;QACzB,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;QACpB,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAChF,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,IAAI,CAAC;YACH,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACnC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;YAC1C,MAAM,CAAE,CAAqB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YACpE,MAAM,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;QACvB,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACd,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Request, Response } from 'express';
2
+ import { AIProviderConfig } from '../types/index.js';
3
+ import { mapUpstreamStatus } from './anthropic-errors.js';
4
+ export declare const UPSTREAM_HEADER_TIMEOUT_MS = 30000;
5
+ export declare const STREAM_WATCHDOG_MS: number;
6
+ export declare function passthroughMessages(req: Request, res: Response, provider: AIProviderConfig, model: string): Promise<void>;
7
+ export declare function trimTrailingSlash(s: string): string;
8
+ export { mapUpstreamStatus };
9
+ //# sourceMappingURL=passthrough.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passthrough.d.ts","sourceRoot":"","sources":["../../src/ai-gateway/passthrough.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAkB,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1E,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,eAAO,MAAM,kBAAkB,QAAa,CAAC;AAE7C,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAkFf;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}