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.
- package/LICENSE +22 -0
- package/README.md +244 -0
- package/dist/adapters/adapter-factory.d.ts +21 -0
- package/dist/adapters/adapter-factory.d.ts.map +1 -0
- package/dist/adapters/adapter-factory.js +157 -0
- package/dist/adapters/adapter-factory.js.map +1 -0
- package/dist/adapters/http-sse-adapter.d.ts +49 -0
- package/dist/adapters/http-sse-adapter.d.ts.map +1 -0
- package/dist/adapters/http-sse-adapter.js +485 -0
- package/dist/adapters/http-sse-adapter.js.map +1 -0
- package/dist/adapters/stdio-adapter.d.ts +69 -0
- package/dist/adapters/stdio-adapter.d.ts.map +1 -0
- package/dist/adapters/stdio-adapter.js +664 -0
- package/dist/adapters/stdio-adapter.js.map +1 -0
- package/dist/adapters/streamable-http-adapter.d.ts +38 -0
- package/dist/adapters/streamable-http-adapter.d.ts.map +1 -0
- package/dist/adapters/streamable-http-adapter.js +321 -0
- package/dist/adapters/streamable-http-adapter.js.map +1 -0
- package/dist/ai-gateway/anthropic-errors.d.ts +4 -0
- package/dist/ai-gateway/anthropic-errors.d.ts.map +1 -0
- package/dist/ai-gateway/anthropic-errors.js +17 -0
- package/dist/ai-gateway/anthropic-errors.js.map +1 -0
- package/dist/ai-gateway/auth.d.ts +3 -0
- package/dist/ai-gateway/auth.d.ts.map +1 -0
- package/dist/ai-gateway/auth.js +14 -0
- package/dist/ai-gateway/auth.js.map +1 -0
- package/dist/ai-gateway/auth.test.d.ts +2 -0
- package/dist/ai-gateway/auth.test.d.ts.map +1 -0
- package/dist/ai-gateway/auth.test.js +57 -0
- package/dist/ai-gateway/auth.test.js.map +1 -0
- package/dist/ai-gateway/count-tokens.d.ts +5 -0
- package/dist/ai-gateway/count-tokens.d.ts.map +1 -0
- package/dist/ai-gateway/count-tokens.js +37 -0
- package/dist/ai-gateway/count-tokens.js.map +1 -0
- package/dist/ai-gateway/count-tokens.test.d.ts +2 -0
- package/dist/ai-gateway/count-tokens.test.d.ts.map +1 -0
- package/dist/ai-gateway/count-tokens.test.js +19 -0
- package/dist/ai-gateway/count-tokens.test.js.map +1 -0
- package/dist/ai-gateway/dialects.d.ts +4 -0
- package/dist/ai-gateway/dialects.d.ts.map +1 -0
- package/dist/ai-gateway/dialects.js +15 -0
- package/dist/ai-gateway/dialects.js.map +1 -0
- package/dist/ai-gateway/gateway-server.d.ts +15 -0
- package/dist/ai-gateway/gateway-server.d.ts.map +1 -0
- package/dist/ai-gateway/gateway-server.js +121 -0
- package/dist/ai-gateway/gateway-server.js.map +1 -0
- package/dist/ai-gateway/integration.test.d.ts +2 -0
- package/dist/ai-gateway/integration.test.d.ts.map +1 -0
- package/dist/ai-gateway/integration.test.js +205 -0
- package/dist/ai-gateway/integration.test.js.map +1 -0
- package/dist/ai-gateway/ir/anthropic-in.d.ts +3 -0
- package/dist/ai-gateway/ir/anthropic-in.d.ts.map +1 -0
- package/dist/ai-gateway/ir/anthropic-in.js +121 -0
- package/dist/ai-gateway/ir/anthropic-in.js.map +1 -0
- package/dist/ai-gateway/ir/anthropic-in.test.d.ts +2 -0
- package/dist/ai-gateway/ir/anthropic-in.test.d.ts.map +1 -0
- package/dist/ai-gateway/ir/anthropic-in.test.js +93 -0
- package/dist/ai-gateway/ir/anthropic-in.test.js.map +1 -0
- package/dist/ai-gateway/ir/anthropic-sse.d.ts +22 -0
- package/dist/ai-gateway/ir/anthropic-sse.d.ts.map +1 -0
- package/dist/ai-gateway/ir/anthropic-sse.js +200 -0
- package/dist/ai-gateway/ir/anthropic-sse.js.map +1 -0
- package/dist/ai-gateway/ir/anthropic-sse.test.d.ts +2 -0
- package/dist/ai-gateway/ir/anthropic-sse.test.d.ts.map +1 -0
- package/dist/ai-gateway/ir/anthropic-sse.test.js +101 -0
- package/dist/ai-gateway/ir/anthropic-sse.test.js.map +1 -0
- package/dist/ai-gateway/ir/gemini-out.d.ts +20 -0
- package/dist/ai-gateway/ir/gemini-out.d.ts.map +1 -0
- package/dist/ai-gateway/ir/gemini-out.js +218 -0
- package/dist/ai-gateway/ir/gemini-out.js.map +1 -0
- package/dist/ai-gateway/ir/gemini-out.test.d.ts +2 -0
- package/dist/ai-gateway/ir/gemini-out.test.d.ts.map +1 -0
- package/dist/ai-gateway/ir/gemini-out.test.js +125 -0
- package/dist/ai-gateway/ir/gemini-out.test.js.map +1 -0
- package/dist/ai-gateway/ir/openai-out.d.ts +17 -0
- package/dist/ai-gateway/ir/openai-out.d.ts.map +1 -0
- package/dist/ai-gateway/ir/openai-out.js +226 -0
- package/dist/ai-gateway/ir/openai-out.js.map +1 -0
- package/dist/ai-gateway/ir/openai-out.test.d.ts +2 -0
- package/dist/ai-gateway/ir/openai-out.test.d.ts.map +1 -0
- package/dist/ai-gateway/ir/openai-out.test.js +144 -0
- package/dist/ai-gateway/ir/openai-out.test.js.map +1 -0
- package/dist/ai-gateway/ir/types.d.ts +77 -0
- package/dist/ai-gateway/ir/types.d.ts.map +1 -0
- package/dist/ai-gateway/ir/types.js +4 -0
- package/dist/ai-gateway/ir/types.js.map +1 -0
- package/dist/ai-gateway/ir-channel.d.ts +15 -0
- package/dist/ai-gateway/ir-channel.d.ts.map +1 -0
- package/dist/ai-gateway/ir-channel.js +120 -0
- package/dist/ai-gateway/ir-channel.js.map +1 -0
- package/dist/ai-gateway/model-router.d.ts +11 -0
- package/dist/ai-gateway/model-router.d.ts.map +1 -0
- package/dist/ai-gateway/model-router.js +27 -0
- package/dist/ai-gateway/model-router.js.map +1 -0
- package/dist/ai-gateway/model-router.test.d.ts +2 -0
- package/dist/ai-gateway/model-router.test.d.ts.map +1 -0
- package/dist/ai-gateway/model-router.test.js +43 -0
- package/dist/ai-gateway/model-router.test.js.map +1 -0
- package/dist/ai-gateway/passthrough.d.ts +9 -0
- package/dist/ai-gateway/passthrough.d.ts.map +1 -0
- package/dist/ai-gateway/passthrough.js +81 -0
- package/dist/ai-gateway/passthrough.js.map +1 -0
- package/dist/ai-gateway/passthrough.test.d.ts +2 -0
- package/dist/ai-gateway/passthrough.test.d.ts.map +1 -0
- package/dist/ai-gateway/passthrough.test.js +108 -0
- package/dist/ai-gateway/passthrough.test.js.map +1 -0
- package/dist/ai-gateway/upstream/model-lister.d.ts +13 -0
- package/dist/ai-gateway/upstream/model-lister.d.ts.map +1 -0
- package/dist/ai-gateway/upstream/model-lister.js +61 -0
- package/dist/ai-gateway/upstream/model-lister.js.map +1 -0
- package/dist/ai-gateway/upstream/provider-client.d.ts +20 -0
- package/dist/ai-gateway/upstream/provider-client.d.ts.map +1 -0
- package/dist/ai-gateway/upstream/provider-client.js +76 -0
- package/dist/ai-gateway/upstream/provider-client.js.map +1 -0
- package/dist/ai-gateway/upstream/provider-client.test.d.ts +2 -0
- package/dist/ai-gateway/upstream/provider-client.test.d.ts.map +1 -0
- package/dist/ai-gateway/upstream/provider-client.test.js +69 -0
- package/dist/ai-gateway/upstream/provider-client.test.js.map +1 -0
- package/dist/cli/cli-main.d.ts +7 -0
- package/dist/cli/cli-main.d.ts.map +1 -0
- package/dist/cli/cli-main.js +116 -0
- package/dist/cli/cli-main.js.map +1 -0
- package/dist/cli/cli-router.d.ts +20 -0
- package/dist/cli/cli-router.d.ts.map +1 -0
- package/dist/cli/cli-router.js +271 -0
- package/dist/cli/cli-router.js.map +1 -0
- package/dist/cli/cli-utils.d.ts +30 -0
- package/dist/cli/cli-utils.d.ts.map +1 -0
- package/dist/cli/cli-utils.js +219 -0
- package/dist/cli/cli-utils.js.map +1 -0
- package/dist/cli/commands/audit-commands.d.ts +30 -0
- package/dist/cli/commands/audit-commands.d.ts.map +1 -0
- package/dist/cli/commands/audit-commands.js +417 -0
- package/dist/cli/commands/audit-commands.js.map +1 -0
- package/dist/cli/commands/autostart-command.d.ts +21 -0
- package/dist/cli/commands/autostart-command.d.ts.map +1 -0
- package/dist/cli/commands/autostart-command.js +243 -0
- package/dist/cli/commands/autostart-command.js.map +1 -0
- package/dist/cli/commands/autostart-command.test.d.ts +2 -0
- package/dist/cli/commands/autostart-command.test.d.ts.map +1 -0
- package/dist/cli/commands/autostart-command.test.js +35 -0
- package/dist/cli/commands/autostart-command.test.js.map +1 -0
- package/dist/cli/commands/config-commands.d.ts +30 -0
- package/dist/cli/commands/config-commands.d.ts.map +1 -0
- package/dist/cli/commands/config-commands.js +1013 -0
- package/dist/cli/commands/config-commands.js.map +1 -0
- package/dist/cli/commands/daemon-commands.d.ts +76 -0
- package/dist/cli/commands/daemon-commands.d.ts.map +1 -0
- package/dist/cli/commands/daemon-commands.js +451 -0
- package/dist/cli/commands/daemon-commands.js.map +1 -0
- package/dist/cli/commands/detect-commands.d.ts +17 -0
- package/dist/cli/commands/detect-commands.d.ts.map +1 -0
- package/dist/cli/commands/detect-commands.js +293 -0
- package/dist/cli/commands/detect-commands.js.map +1 -0
- package/dist/cli/commands/diagnose-commands.d.ts +19 -0
- package/dist/cli/commands/diagnose-commands.d.ts.map +1 -0
- package/dist/cli/commands/diagnose-commands.js +326 -0
- package/dist/cli/commands/diagnose-commands.js.map +1 -0
- package/dist/cli/commands/optimize-commands.d.ts +14 -0
- package/dist/cli/commands/optimize-commands.d.ts.map +1 -0
- package/dist/cli/commands/optimize-commands.js +189 -0
- package/dist/cli/commands/optimize-commands.js.map +1 -0
- package/dist/cli/commands/proxy-command.d.ts +27 -0
- package/dist/cli/commands/proxy-command.d.ts.map +1 -0
- package/dist/cli/commands/proxy-command.js +212 -0
- package/dist/cli/commands/proxy-command.js.map +1 -0
- package/dist/cli/commands/start-command.d.ts +22 -0
- package/dist/cli/commands/start-command.d.ts.map +1 -0
- package/dist/cli/commands/start-command.js +275 -0
- package/dist/cli/commands/start-command.js.map +1 -0
- package/dist/config/config-manager.d.ts +125 -0
- package/dist/config/config-manager.d.ts.map +1 -0
- package/dist/config/config-manager.js +569 -0
- package/dist/config/config-manager.js.map +1 -0
- package/dist/config/config-manager.test.d.ts +2 -0
- package/dist/config/config-manager.test.d.ts.map +1 -0
- package/dist/config/config-manager.test.js +209 -0
- package/dist/config/config-manager.test.js.map +1 -0
- package/dist/core/auto-config-generator.d.ts +55 -0
- package/dist/core/auto-config-generator.d.ts.map +1 -0
- package/dist/core/auto-config-generator.js +278 -0
- package/dist/core/auto-config-generator.js.map +1 -0
- package/dist/core/mcpdog-server.d.ts +49 -0
- package/dist/core/mcpdog-server.d.ts.map +1 -0
- package/dist/core/mcpdog-server.js +552 -0
- package/dist/core/mcpdog-server.js.map +1 -0
- package/dist/core/protocol-detector.d.ts +56 -0
- package/dist/core/protocol-detector.d.ts.map +1 -0
- package/dist/core/protocol-detector.js +365 -0
- package/dist/core/protocol-detector.js.map +1 -0
- package/dist/daemon/daemon-client.d.ts +34 -0
- package/dist/daemon/daemon-client.d.ts.map +1 -0
- package/dist/daemon/daemon-client.js +130 -0
- package/dist/daemon/daemon-client.js.map +1 -0
- package/dist/daemon/daemon-client.test.d.ts +2 -0
- package/dist/daemon/daemon-client.test.d.ts.map +1 -0
- package/dist/daemon/daemon-client.test.js +77 -0
- package/dist/daemon/daemon-client.test.js.map +1 -0
- package/dist/daemon/daemon-info.d.ts +7 -0
- package/dist/daemon/daemon-info.d.ts.map +1 -0
- package/dist/daemon/daemon-info.js +34 -0
- package/dist/daemon/daemon-info.js.map +1 -0
- package/dist/daemon/daemon-info.test.d.ts +2 -0
- package/dist/daemon/daemon-info.test.d.ts.map +1 -0
- package/dist/daemon/daemon-info.test.js +57 -0
- package/dist/daemon/daemon-info.test.js.map +1 -0
- package/dist/daemon/daemon-web-server.ai.test.d.ts +2 -0
- package/dist/daemon/daemon-web-server.ai.test.d.ts.map +1 -0
- package/dist/daemon/daemon-web-server.ai.test.js +119 -0
- package/dist/daemon/daemon-web-server.ai.test.js.map +1 -0
- package/dist/daemon/daemon-web-server.d.ts +59 -0
- package/dist/daemon/daemon-web-server.d.ts.map +1 -0
- package/dist/daemon/daemon-web-server.js +1236 -0
- package/dist/daemon/daemon-web-server.js.map +1 -0
- package/dist/daemon/daemon-web-server.test.d.ts +2 -0
- package/dist/daemon/daemon-web-server.test.d.ts.map +1 -0
- package/dist/daemon/daemon-web-server.test.js +93 -0
- package/dist/daemon/daemon-web-server.test.js.map +1 -0
- package/dist/daemon/mcpdog-daemon.d.ts +42 -0
- package/dist/daemon/mcpdog-daemon.d.ts.map +1 -0
- package/dist/daemon/mcpdog-daemon.js +302 -0
- package/dist/daemon/mcpdog-daemon.js.map +1 -0
- package/dist/daemon/stdio-proxy.d.ts +17 -0
- package/dist/daemon/stdio-proxy.d.ts.map +1 -0
- package/dist/daemon/stdio-proxy.js +143 -0
- package/dist/daemon/stdio-proxy.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +198 -0
- package/dist/index.js.map +1 -0
- package/dist/intent-analyzer.d.ts +27 -0
- package/dist/intent-analyzer.d.ts.map +1 -0
- package/dist/intent-analyzer.js +140 -0
- package/dist/intent-analyzer.js.map +1 -0
- package/dist/logging/server-log-manager.d.ts +75 -0
- package/dist/logging/server-log-manager.d.ts.map +1 -0
- package/dist/logging/server-log-manager.js +185 -0
- package/dist/logging/server-log-manager.js.map +1 -0
- package/dist/mcp-registry.d.ts +35 -0
- package/dist/mcp-registry.d.ts.map +1 -0
- package/dist/mcp-registry.js +166 -0
- package/dist/mcp-registry.js.map +1 -0
- package/dist/middleware/auth.d.ts +5 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +81 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/mock-tool-database.d.ts +41 -0
- package/dist/mock-tool-database.d.ts.map +1 -0
- package/dist/mock-tool-database.js +461 -0
- package/dist/mock-tool-database.js.map +1 -0
- package/dist/proxy-server-manager.d.ts +11 -0
- package/dist/proxy-server-manager.d.ts.map +1 -0
- package/dist/proxy-server-manager.js +144 -0
- package/dist/proxy-server-manager.js.map +1 -0
- package/dist/router/tool-router.d.ts +61 -0
- package/dist/router/tool-router.d.ts.map +1 -0
- package/dist/router/tool-router.js +539 -0
- package/dist/router/tool-router.js.map +1 -0
- package/dist/router/tool-router.test.d.ts +2 -0
- package/dist/router/tool-router.test.d.ts.map +1 -0
- package/dist/router/tool-router.test.js +113 -0
- package/dist/router/tool-router.test.js.map +1 -0
- package/dist/streamable-http-server.d.ts +27 -0
- package/dist/streamable-http-server.d.ts.map +1 -0
- package/dist/streamable-http-server.js +302 -0
- package/dist/streamable-http-server.js.map +1 -0
- package/dist/tool-finder.d.ts +21 -0
- package/dist/tool-finder.d.ts.map +1 -0
- package/dist/tool-finder.js +86 -0
- package/dist/tool-finder.js.map +1 -0
- package/dist/tool-recommender.d.ts +23 -0
- package/dist/tool-recommender.d.ts.map +1 -0
- package/dist/tool-recommender.js +200 -0
- package/dist/tool-recommender.js.map +1 -0
- package/dist/types/index.d.ts +145 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/server-name-validator.d.ts +47 -0
- package/dist/utils/server-name-validator.d.ts.map +1 -0
- package/dist/utils/server-name-validator.js +156 -0
- package/dist/utils/server-name-validator.js.map +1 -0
- package/dist/web/web-server.d.ts +44 -0
- package/dist/web/web-server.d.ts.map +1 -0
- package/dist/web/web-server.js +500 -0
- package/dist/web/web-server.js.map +1 -0
- package/package.json +68 -0
- package/web/dist/assets/index-DMVhVtNU.css +1 -0
- package/web/dist/assets/index-VMXIgcOH.js +92 -0
- package/web/dist/assets/index-VMXIgcOH.js.map +1 -0
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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":"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"}
|
|
@@ -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"}
|