@huyooo/ai-chat-core 0.2.45 → 0.3.3
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/dist/adapter/index.d.ts +11 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/model-adapter.d.ts +25 -0
- package/dist/adapter/model-adapter.d.ts.map +1 -0
- package/dist/adapter/model-options.d.ts +53 -0
- package/dist/adapter/model-options.d.ts.map +1 -0
- package/dist/adapter/types.d.ts +28 -0
- package/dist/adapter/types.d.ts.map +1 -0
- package/dist/chat-runtime.d.ts +96 -0
- package/dist/chat-runtime.d.ts.map +1 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/events.d.ts +605 -1
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +1 -1
- package/dist/extension/index.d.ts +9 -0
- package/dist/extension/index.d.ts.map +1 -0
- package/dist/extension/types.d.ts +46 -0
- package/dist/extension/types.d.ts.map +1 -0
- package/dist/families/index.d.ts +11 -0
- package/dist/families/index.d.ts.map +1 -0
- package/dist/families/presets.d.ts +31 -0
- package/dist/families/presets.d.ts.map +1 -0
- package/dist/families/resolver.d.ts +11 -0
- package/dist/families/resolver.d.ts.map +1 -0
- package/dist/families/types.d.ts +29 -0
- package/dist/families/types.d.ts.map +1 -0
- package/dist/governance/command-safety.d.ts +34 -0
- package/dist/governance/command-safety.d.ts.map +1 -0
- package/dist/governance/governance.d.ts +19 -0
- package/dist/governance/governance.d.ts.map +1 -0
- package/dist/governance/index.d.ts +12 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/types.d.ts +29 -0
- package/dist/governance/types.d.ts.map +1 -0
- package/dist/index.d.ts +72 -804
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -1
- package/dist/internal/management-args.d.ts +13 -0
- package/dist/internal/management-args.d.ts.map +1 -0
- package/dist/internal/management-results.d.ts +21 -0
- package/dist/internal/management-results.d.ts.map +1 -0
- package/dist/llm-config.d.ts +108 -0
- package/dist/llm-config.d.ts.map +1 -0
- package/dist/logger/core.d.ts +31 -0
- package/dist/logger/core.d.ts.map +1 -0
- package/dist/logger/index.d.ts +9 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/orchestrator/compression-handler.d.ts +29 -0
- package/dist/orchestrator/compression-handler.d.ts.map +1 -0
- package/dist/orchestrator/context-compressor.d.ts +51 -0
- package/dist/orchestrator/context-compressor.d.ts.map +1 -0
- package/dist/orchestrator/context-summarizer.d.ts +41 -0
- package/dist/orchestrator/context-summarizer.d.ts.map +1 -0
- package/dist/orchestrator/index.d.ts +12 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +46 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/types.d.ts +58 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/parts/index.d.ts +13 -0
- package/dist/parts/index.d.ts.map +1 -0
- package/dist/parts/registry.d.ts +11 -0
- package/dist/parts/registry.d.ts.map +1 -0
- package/dist/parts/summaries.d.ts +9 -0
- package/dist/parts/summaries.d.ts.map +1 -0
- package/dist/parts/types.d.ts +61 -0
- package/dist/parts/types.d.ts.map +1 -0
- package/dist/platform.d.ts +17 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +1 -0
- package/dist/protocols/anthropic.d.ts +20 -0
- package/dist/protocols/anthropic.d.ts.map +1 -0
- package/dist/protocols/ark.d.ts +36 -0
- package/dist/protocols/ark.d.ts.map +1 -0
- package/dist/protocols/deepseek.d.ts +24 -0
- package/dist/protocols/deepseek.d.ts.map +1 -0
- package/dist/protocols/error-utils.d.ts +14 -0
- package/dist/protocols/error-utils.d.ts.map +1 -0
- package/dist/protocols/gemini.d.ts +24 -0
- package/dist/protocols/gemini.d.ts.map +1 -0
- package/dist/protocols/glm.d.ts +20 -0
- package/dist/protocols/glm.d.ts.map +1 -0
- package/dist/protocols/grok.d.ts +20 -0
- package/dist/protocols/grok.d.ts.map +1 -0
- package/dist/protocols/index.d.ts +31 -0
- package/dist/protocols/index.d.ts.map +1 -0
- package/dist/protocols/minimax.d.ts +38 -0
- package/dist/protocols/minimax.d.ts.map +1 -0
- package/dist/protocols/moonshot.d.ts +20 -0
- package/dist/protocols/moonshot.d.ts.map +1 -0
- package/dist/protocols/openai-sse.d.ts +33 -0
- package/dist/protocols/openai-sse.d.ts.map +1 -0
- package/dist/protocols/openai.d.ts +19 -0
- package/dist/protocols/openai.d.ts.map +1 -0
- package/dist/protocols/qwen.d.ts +26 -0
- package/dist/protocols/qwen.d.ts.map +1 -0
- package/dist/protocols/responses-sse.d.ts +30 -0
- package/dist/protocols/responses-sse.d.ts.map +1 -0
- package/dist/protocols/sse-reader.d.ts +23 -0
- package/dist/protocols/sse-reader.d.ts.map +1 -0
- package/dist/protocols/tool-arguments.d.ts +8 -0
- package/dist/protocols/tool-arguments.d.ts.map +1 -0
- package/dist/protocols/types.d.ts +148 -0
- package/dist/protocols/types.d.ts.map +1 -0
- package/dist/protocols/vercel-gateway.d.ts +15 -0
- package/dist/protocols/vercel-gateway.d.ts.map +1 -0
- package/dist/runtime.d.ts +151 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1 -0
- package/dist/skills/index.d.ts +14 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/management/admin.d.ts +10 -0
- package/dist/skills/management/admin.d.ts.map +1 -0
- package/dist/skills/management/index.d.ts +11 -0
- package/dist/skills/management/index.d.ts.map +1 -0
- package/dist/skills/management/inputs.d.ts +44 -0
- package/dist/skills/management/inputs.d.ts.map +1 -0
- package/dist/skills/management/operations.d.ts +78 -0
- package/dist/skills/management/operations.d.ts.map +1 -0
- package/dist/skills/management/types.d.ts +70 -0
- package/dist/skills/management/types.d.ts.map +1 -0
- package/dist/skills/registry.d.ts +37 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/summaries.d.ts +9 -0
- package/dist/skills/summaries.d.ts.map +1 -0
- package/dist/skills/types.d.ts +61 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/test-utils/mock-sse.d.ts +13 -0
- package/dist/test-utils/mock-sse.d.ts.map +1 -0
- package/dist/tool-manager/define-tool.d.ts +35 -0
- package/dist/tool-manager/define-tool.d.ts.map +1 -0
- package/dist/tool-manager/formats.d.ts +46 -0
- package/dist/tool-manager/formats.d.ts.map +1 -0
- package/dist/tool-manager/identity.d.ts +18 -0
- package/dist/tool-manager/identity.d.ts.map +1 -0
- package/dist/tool-manager/in-process-provider.d.ts +15 -0
- package/dist/tool-manager/in-process-provider.d.ts.map +1 -0
- package/dist/tool-manager/index.d.ts +18 -0
- package/dist/tool-manager/index.d.ts.map +1 -0
- package/dist/tool-manager/manager.d.ts +18 -0
- package/dist/tool-manager/manager.d.ts.map +1 -0
- package/dist/tool-manager/mcp-provider.d.ts +21 -0
- package/dist/tool-manager/mcp-provider.d.ts.map +1 -0
- package/dist/tool-manager/summaries.d.ts +39 -0
- package/dist/tool-manager/summaries.d.ts.map +1 -0
- package/dist/tool-manager/types.d.ts +314 -0
- package/dist/tool-manager/types.d.ts.map +1 -0
- package/dist/types.d.ts +663 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +26 -15
- package/src/adapter/index.ts +25 -0
- package/src/adapter/model-adapter.ts +196 -0
- package/src/adapter/model-options.ts +143 -0
- package/src/adapter/types.ts +41 -0
- package/src/chat-runtime.ts +515 -0
- package/src/constants.ts +9 -102
- package/src/events.ts +364 -150
- package/src/extension/index.ts +24 -0
- package/src/extension/types.ts +49 -0
- package/src/families/index.ts +28 -0
- package/src/families/presets.ts +124 -0
- package/src/families/resolver.ts +22 -0
- package/src/families/types.ts +55 -0
- package/src/governance/command-safety.ts +224 -0
- package/src/governance/governance.ts +125 -0
- package/src/governance/index.ts +38 -0
- package/src/governance/types.ts +44 -0
- package/src/index.ts +250 -145
- package/src/internal/management-args.ts +39 -0
- package/src/internal/management-results.ts +60 -0
- package/src/llm-config.ts +137 -0
- package/src/logger/core.ts +96 -0
- package/src/logger/index.ts +8 -0
- package/src/orchestrator/compression-handler.ts +137 -0
- package/src/{providers → orchestrator}/context-compressor.ts +79 -47
- package/src/orchestrator/context-summarizer.ts +123 -0
- package/src/orchestrator/index.ts +20 -0
- package/src/orchestrator/orchestrator.ts +1002 -0
- package/src/orchestrator/types.ts +70 -0
- package/src/parts/index.ts +20 -0
- package/src/parts/registry.ts +95 -0
- package/src/parts/summaries.ts +40 -0
- package/src/parts/types.ts +63 -0
- package/src/platform.ts +73 -0
- package/src/protocols/anthropic.ts +377 -0
- package/src/protocols/ark.ts +300 -0
- package/src/protocols/deepseek.ts +192 -0
- package/src/{providers/protocols → protocols}/error-utils.ts +17 -20
- package/src/protocols/gemini.ts +352 -0
- package/src/protocols/glm.ts +212 -0
- package/src/protocols/grok.ts +98 -0
- package/src/protocols/index.ts +48 -0
- package/src/protocols/minimax.ts +308 -0
- package/src/protocols/moonshot.ts +186 -0
- package/src/protocols/openai-sse.ts +156 -0
- package/src/protocols/openai.ts +97 -0
- package/src/protocols/qwen.ts +358 -0
- package/src/protocols/responses-sse.ts +224 -0
- package/src/protocols/sse-reader.ts +54 -0
- package/src/protocols/tool-arguments.ts +32 -0
- package/src/{providers/protocols → protocols}/types.ts +46 -37
- package/src/protocols/vercel-gateway.ts +391 -0
- package/src/runtime.ts +167 -0
- package/src/skills/index.ts +29 -0
- package/src/skills/management/admin.ts +170 -0
- package/src/skills/management/index.ts +27 -0
- package/src/skills/management/inputs.ts +79 -0
- package/src/skills/management/operations.ts +256 -0
- package/src/skills/management/types.ts +57 -0
- package/src/skills/registry.ts +120 -0
- package/src/skills/summaries.ts +48 -0
- package/src/skills/types.ts +65 -0
- package/src/test-utils/mock-sse.ts +3 -3
- package/src/tool-manager/define-tool.ts +201 -0
- package/src/tool-manager/formats.ts +146 -0
- package/src/tool-manager/identity.ts +80 -0
- package/src/tool-manager/in-process-provider.ts +164 -0
- package/src/tool-manager/index.ts +63 -0
- package/src/tool-manager/manager.ts +562 -0
- package/src/tool-manager/mcp-provider.ts +509 -0
- package/src/tool-manager/summaries.ts +136 -0
- package/src/tool-manager/types.ts +389 -0
- package/src/types.ts +750 -191
- package/dist/events-CU5D5ray.d.ts +0 -1128
- package/src/agent.ts +0 -409
- package/src/internal/update-plan.ts +0 -2
- package/src/internal/web-search.ts +0 -77
- package/src/mcp/client-manager.ts +0 -302
- package/src/mcp/index.ts +0 -2
- package/src/mcp/types.ts +0 -43
- package/src/providers/context-summarizer.ts +0 -70
- package/src/providers/index.ts +0 -125
- package/src/providers/model-registry.ts +0 -466
- package/src/providers/orchestrator.ts +0 -839
- package/src/providers/protocols/anthropic.ts +0 -406
- package/src/providers/protocols/ark.ts +0 -362
- package/src/providers/protocols/deepseek.ts +0 -344
- package/src/providers/protocols/gemini.ts +0 -350
- package/src/providers/protocols/index.ts +0 -36
- package/src/providers/protocols/openai.ts +0 -420
- package/src/providers/protocols/qwen.ts +0 -315
- package/src/providers/types.ts +0 -264
- package/src/providers/unified-adapter.ts +0 -367
- package/src/router.ts +0 -72
- package/src/tools.ts +0 -162
- package/src/utils.ts +0 -86
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* UnifiedAdapter - 统一适配器
|
|
3
|
-
*
|
|
4
|
-
* 组合 Protocol + FamilyConfig,产出标准 StreamChunk
|
|
5
|
-
*
|
|
6
|
-
* 设计原则:
|
|
7
|
-
* 1. Protocol 只负责 HTTP/SSE 通信,产出 RawEvent
|
|
8
|
-
* 2. UnifiedAdapter 根据 FamilyConfig 将 RawEvent 转换为 StreamChunk
|
|
9
|
-
* 3. 所有模型都使用同一个 UnifiedAdapter,行为差异由 FamilyConfig 决定
|
|
10
|
-
* 4. 实现 ProviderAdapter 接口,可与现有 Orchestrator 无缝集成
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type {
|
|
14
|
-
Protocol,
|
|
15
|
-
ProtocolMessage,
|
|
16
|
-
ProtocolToolDefinition,
|
|
17
|
-
RawEvent,
|
|
18
|
-
} from './protocols';
|
|
19
|
-
import {
|
|
20
|
-
createArkProtocol,
|
|
21
|
-
createDeepSeekProtocol,
|
|
22
|
-
createQwenProtocol,
|
|
23
|
-
createGeminiProtocol,
|
|
24
|
-
createOpenAIProtocol,
|
|
25
|
-
createAnthropicProtocol,
|
|
26
|
-
} from './protocols';
|
|
27
|
-
import {
|
|
28
|
-
getModelFamily,
|
|
29
|
-
getModelProtocol,
|
|
30
|
-
getVisibleModels,
|
|
31
|
-
type ModelFamilyConfig,
|
|
32
|
-
type ProtocolId,
|
|
33
|
-
} from './model-registry';
|
|
34
|
-
import type {
|
|
35
|
-
ProviderAdapter,
|
|
36
|
-
StreamChunk,
|
|
37
|
-
ToolCallRequest,
|
|
38
|
-
SearchResultItem,
|
|
39
|
-
StandardMessage,
|
|
40
|
-
SimpleToolDefinition,
|
|
41
|
-
StreamOnceOptions,
|
|
42
|
-
} from './types';
|
|
43
|
-
import { DebugLogger } from '../utils';
|
|
44
|
-
|
|
45
|
-
const logger = DebugLogger.module('UnifiedAdapter');
|
|
46
|
-
|
|
47
|
-
// ==================== 配置类型 ====================
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* UnifiedAdapter 配置
|
|
51
|
-
*/
|
|
52
|
-
export interface UnifiedAdapterConfig {
|
|
53
|
-
/** ARK API Key(豆包/DeepSeek) */
|
|
54
|
-
arkApiKey?: string;
|
|
55
|
-
arkApiUrl?: string;
|
|
56
|
-
|
|
57
|
-
/** Qwen API Key(通义千问) */
|
|
58
|
-
qwenApiKey?: string;
|
|
59
|
-
qwenApiUrl?: string;
|
|
60
|
-
|
|
61
|
-
/** Gemini API Key */
|
|
62
|
-
geminiApiKey?: string;
|
|
63
|
-
geminiApiUrl?: string;
|
|
64
|
-
|
|
65
|
-
/** OpenRouter API Key */
|
|
66
|
-
openrouterApiKey?: string;
|
|
67
|
-
openrouterApiUrl?: string;
|
|
68
|
-
|
|
69
|
-
/** Vercel API Key(用于 Vercel AI Gateway 访问 Claude) */
|
|
70
|
-
vercelApiKey?: string;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* 流式调用选项
|
|
75
|
-
*/
|
|
76
|
-
export interface StreamOptions {
|
|
77
|
-
/** 模型 ID */
|
|
78
|
-
model: string;
|
|
79
|
-
/** 是否启用 thinking */
|
|
80
|
-
enableThinking?: boolean;
|
|
81
|
-
/** 是否启用搜索 */
|
|
82
|
-
enableSearch?: boolean;
|
|
83
|
-
/** 中断信号 */
|
|
84
|
-
signal: AbortSignal;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// ==================== UnifiedAdapter ====================
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* 统一适配器
|
|
91
|
-
*
|
|
92
|
-
* 实现 ProviderAdapter 接口,根据模型自动选择 Protocol,并根据 FamilyConfig 转换事件
|
|
93
|
-
*/
|
|
94
|
-
export class UnifiedAdapter implements ProviderAdapter {
|
|
95
|
-
readonly name = 'unified';
|
|
96
|
-
|
|
97
|
-
/** 支持的模型列表(从 Registry 获取) */
|
|
98
|
-
get supportedModels(): string[] {
|
|
99
|
-
return getVisibleModels().map(m => m.id);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private protocols: Map<ProtocolId, Protocol> = new Map();
|
|
103
|
-
|
|
104
|
-
constructor(config: UnifiedAdapterConfig) {
|
|
105
|
-
// 初始化各 Protocol
|
|
106
|
-
if (config.arkApiKey) {
|
|
107
|
-
// 豆包(ARK 原生)
|
|
108
|
-
this.protocols.set('ark', createArkProtocol({
|
|
109
|
-
apiKey: config.arkApiKey,
|
|
110
|
-
apiUrl: config.arkApiUrl,
|
|
111
|
-
}));
|
|
112
|
-
// DeepSeek(通过 ARK,但独立 Protocol)
|
|
113
|
-
this.protocols.set('deepseek', createDeepSeekProtocol({
|
|
114
|
-
apiKey: config.arkApiKey,
|
|
115
|
-
apiUrl: config.arkApiUrl,
|
|
116
|
-
}));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (config.qwenApiKey) {
|
|
120
|
-
this.protocols.set('qwen', createQwenProtocol({
|
|
121
|
-
apiKey: config.qwenApiKey,
|
|
122
|
-
apiUrl: config.qwenApiUrl,
|
|
123
|
-
}));
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (config.geminiApiKey) {
|
|
127
|
-
this.protocols.set('gemini', createGeminiProtocol({
|
|
128
|
-
apiKey: config.geminiApiKey,
|
|
129
|
-
apiUrl: config.geminiApiUrl,
|
|
130
|
-
}));
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// OpenAI 通过 OpenRouter 访问
|
|
134
|
-
if (config.openrouterApiKey) {
|
|
135
|
-
this.protocols.set('openai', createOpenAIProtocol({
|
|
136
|
-
apiKey: config.openrouterApiKey,
|
|
137
|
-
apiUrl: config.openrouterApiUrl,
|
|
138
|
-
}));
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Anthropic 使用 Vercel AI SDK
|
|
142
|
-
if (config.vercelApiKey) {
|
|
143
|
-
this.protocols.set('anthropic', createAnthropicProtocol({
|
|
144
|
-
apiKey: config.vercelApiKey,
|
|
145
|
-
}));
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* 检查是否支持指定模型
|
|
151
|
-
*/
|
|
152
|
-
supportsModel(model: string): boolean {
|
|
153
|
-
const protocol = getModelProtocol(model);
|
|
154
|
-
return protocol ? this.protocols.has(protocol) : false;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* 获取模型的家族配置
|
|
159
|
-
*/
|
|
160
|
-
getModelFamilyConfig(model: string): ModelFamilyConfig | undefined {
|
|
161
|
-
return getModelFamily(model);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* 实现 ProviderAdapter.streamOnce 接口
|
|
166
|
-
*
|
|
167
|
-
* @param messages 标准消息列表
|
|
168
|
-
* @param tools 工具定义
|
|
169
|
-
* @param options 调用选项
|
|
170
|
-
* @returns 标准 StreamChunk 流
|
|
171
|
-
*/
|
|
172
|
-
async *streamOnce(
|
|
173
|
-
messages: StandardMessage[],
|
|
174
|
-
tools: SimpleToolDefinition[],
|
|
175
|
-
options: StreamOnceOptions
|
|
176
|
-
): AsyncGenerator<StreamChunk> {
|
|
177
|
-
const { model, enableThinking = false, enableSearch = false, signal } = options;
|
|
178
|
-
|
|
179
|
-
// 转换消息格式(StandardMessage → ProtocolMessage)
|
|
180
|
-
const protocolMessages: ProtocolMessage[] = messages.map(m => ({
|
|
181
|
-
role: m.role,
|
|
182
|
-
content: m.content,
|
|
183
|
-
images: m.images,
|
|
184
|
-
toolCalls: m.toolCalls?.map(tc => ({
|
|
185
|
-
id: tc.id,
|
|
186
|
-
name: tc.name,
|
|
187
|
-
arguments: tc.arguments,
|
|
188
|
-
thoughtSignature: tc.thought_signature,
|
|
189
|
-
})),
|
|
190
|
-
toolCallId: m.toolCallId,
|
|
191
|
-
toolName: m.toolName,
|
|
192
|
-
}));
|
|
193
|
-
|
|
194
|
-
// 转换工具格式(SimpleToolDefinition → ProtocolToolDefinition)
|
|
195
|
-
const protocolTools: ProtocolToolDefinition[] = tools;
|
|
196
|
-
|
|
197
|
-
yield* this.stream(protocolMessages, protocolTools, {
|
|
198
|
-
model,
|
|
199
|
-
enableThinking,
|
|
200
|
-
enableSearch,
|
|
201
|
-
signal,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* 流式调用(内部方法)
|
|
207
|
-
*/
|
|
208
|
-
private async *stream(
|
|
209
|
-
messages: ProtocolMessage[],
|
|
210
|
-
tools: ProtocolToolDefinition[],
|
|
211
|
-
options: StreamOptions
|
|
212
|
-
): AsyncGenerator<StreamChunk> {
|
|
213
|
-
const { model, enableThinking = false, enableSearch = false, signal } = options;
|
|
214
|
-
|
|
215
|
-
// 获取模型配置
|
|
216
|
-
const protocolId = getModelProtocol(model);
|
|
217
|
-
const familyConfig = getModelFamily(model);
|
|
218
|
-
|
|
219
|
-
if (!protocolId) {
|
|
220
|
-
yield { type: 'error', error: `未知模型: ${model}` };
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (!familyConfig) {
|
|
225
|
-
yield { type: 'error', error: `模型 ${model} 缺少家族配置` };
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const protocol = this.protocols.get(protocolId);
|
|
230
|
-
if (!protocol) {
|
|
231
|
-
yield { type: 'error', error: `Protocol ${protocolId} 未配置` };
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
logger.debug('开始流式调用', {
|
|
236
|
-
model,
|
|
237
|
-
protocol: protocolId,
|
|
238
|
-
family: familyConfig.id,
|
|
239
|
-
enableThinking,
|
|
240
|
-
enableSearch,
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
// 调用 Protocol 获取原始事件流
|
|
244
|
-
const rawStream = protocol.stream(messages, tools, {
|
|
245
|
-
model,
|
|
246
|
-
familyConfig,
|
|
247
|
-
enableThinking,
|
|
248
|
-
enableSearch,
|
|
249
|
-
signal,
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
// 转换为标准 StreamChunk
|
|
253
|
-
yield* this.transformEvents(rawStream, familyConfig, enableThinking, enableSearch);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* 将 RawEvent 转换为 StreamChunk
|
|
258
|
-
*
|
|
259
|
-
* 根据 FamilyConfig 处理行为差异
|
|
260
|
-
*/
|
|
261
|
-
private async *transformEvents(
|
|
262
|
-
rawStream: AsyncGenerator<RawEvent>,
|
|
263
|
-
familyConfig: ModelFamilyConfig,
|
|
264
|
-
enableThinking: boolean,
|
|
265
|
-
enableSearch: boolean
|
|
266
|
-
): AsyncGenerator<StreamChunk> {
|
|
267
|
-
// 状态跟踪
|
|
268
|
-
let thinkingBuffer = '';
|
|
269
|
-
let thinkingStarted = false;
|
|
270
|
-
|
|
271
|
-
for await (const event of rawStream) {
|
|
272
|
-
switch (event.type) {
|
|
273
|
-
// ========== Thinking 处理 ==========
|
|
274
|
-
case 'thinking_delta':
|
|
275
|
-
// 只有启用 thinking 且家族支持时才输出
|
|
276
|
-
if (enableThinking && familyConfig.supportsThinking && event.delta) {
|
|
277
|
-
// 去除开头的换行
|
|
278
|
-
let delta = event.delta;
|
|
279
|
-
if (!thinkingStarted) {
|
|
280
|
-
delta = delta.replace(/^\n+/, '');
|
|
281
|
-
if (delta) thinkingStarted = true;
|
|
282
|
-
}
|
|
283
|
-
if (delta) {
|
|
284
|
-
thinkingBuffer += delta;
|
|
285
|
-
yield { type: 'thinking', thinking: delta };
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
break;
|
|
289
|
-
|
|
290
|
-
case 'thinking_done':
|
|
291
|
-
if (enableThinking && familyConfig.supportsThinking) {
|
|
292
|
-
yield { type: 'thinking_done' };
|
|
293
|
-
}
|
|
294
|
-
break;
|
|
295
|
-
|
|
296
|
-
// ========== 文本处理 ==========
|
|
297
|
-
case 'text_delta':
|
|
298
|
-
if (event.delta) {
|
|
299
|
-
yield { type: 'text', text: event.delta };
|
|
300
|
-
}
|
|
301
|
-
break;
|
|
302
|
-
|
|
303
|
-
// ========== 工具调用处理 ==========
|
|
304
|
-
case 'tool_call_done':
|
|
305
|
-
if (event.toolCall) {
|
|
306
|
-
const toolCall: ToolCallRequest = {
|
|
307
|
-
id: event.toolCall.id || '',
|
|
308
|
-
name: event.toolCall.name || '',
|
|
309
|
-
arguments: event.toolCall.arguments || '{}',
|
|
310
|
-
};
|
|
311
|
-
// 保留 Gemini 的 thoughtSignature
|
|
312
|
-
if (event.toolCall.thoughtSignature) {
|
|
313
|
-
toolCall.thought_signature = event.toolCall.thoughtSignature;
|
|
314
|
-
}
|
|
315
|
-
yield { type: 'tool_call', toolCall };
|
|
316
|
-
}
|
|
317
|
-
break;
|
|
318
|
-
|
|
319
|
-
// ========== 搜索结果处理 ==========
|
|
320
|
-
case 'search_result':
|
|
321
|
-
if (enableSearch && event.searchResults) {
|
|
322
|
-
const searchResults: SearchResultItem[] = event.searchResults.map(r => ({
|
|
323
|
-
title: r.title,
|
|
324
|
-
url: r.url,
|
|
325
|
-
snippet: r.snippet,
|
|
326
|
-
}));
|
|
327
|
-
yield { type: 'search_result', searchResults };
|
|
328
|
-
}
|
|
329
|
-
break;
|
|
330
|
-
|
|
331
|
-
// ========== 完成处理 ==========
|
|
332
|
-
case 'done':
|
|
333
|
-
// usage 数据由 protocol 层透传
|
|
334
|
-
yield {
|
|
335
|
-
type: 'done',
|
|
336
|
-
finishReason: event.finishReason || 'stop',
|
|
337
|
-
// 透传 Token 使用统计
|
|
338
|
-
usage: event.usage ? {
|
|
339
|
-
promptTokens: event.usage.promptTokens,
|
|
340
|
-
completionTokens: event.usage.completionTokens,
|
|
341
|
-
totalTokens: event.usage.totalTokens,
|
|
342
|
-
reasoningTokens: event.usage.reasoningTokens,
|
|
343
|
-
cachedTokens: event.usage.cachedTokens,
|
|
344
|
-
} : undefined,
|
|
345
|
-
};
|
|
346
|
-
break;
|
|
347
|
-
|
|
348
|
-
// ========== 错误处理 ==========
|
|
349
|
-
case 'error':
|
|
350
|
-
yield { type: 'error', error: event.error || '未知错误' };
|
|
351
|
-
break;
|
|
352
|
-
|
|
353
|
-
// 忽略其他事件(如 tool_call_start, tool_call_delta)
|
|
354
|
-
default:
|
|
355
|
-
break;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* 创建 UnifiedAdapter
|
|
363
|
-
*/
|
|
364
|
-
export function createUnifiedAdapter(config: UnifiedAdapterConfig): UnifiedAdapter {
|
|
365
|
-
return new UnifiedAdapter(config);
|
|
366
|
-
}
|
|
367
|
-
|
package/src/router.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 模型路由模块
|
|
3
|
-
*
|
|
4
|
-
* 根据模型 ID 查询对应的 Protocol 和 Family 配置
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
getModelEntry,
|
|
9
|
-
getModelFamily,
|
|
10
|
-
type ProtocolId,
|
|
11
|
-
type ModelFamilyConfig,
|
|
12
|
-
type ModelRegistryEntry,
|
|
13
|
-
} from './providers/model-registry';
|
|
14
|
-
|
|
15
|
-
/** Provider 类型 = Protocol 类型 */
|
|
16
|
-
export type ProviderType = ProtocolId;
|
|
17
|
-
|
|
18
|
-
/** 路由结果 */
|
|
19
|
-
export interface RouteResult {
|
|
20
|
-
/** Protocol 类型 */
|
|
21
|
-
provider: ProviderType;
|
|
22
|
-
/** 是否未注册(使用默认 Provider) */
|
|
23
|
-
isDefault: boolean;
|
|
24
|
-
/** 模型注册信息 */
|
|
25
|
-
registryEntry?: ModelRegistryEntry;
|
|
26
|
-
/** 模型家族配置 */
|
|
27
|
-
familyConfig?: ModelFamilyConfig;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** 默认 Provider(未注册模型的兜底) */
|
|
31
|
-
const DEFAULT_PROVIDER: ProviderType = 'ark';
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* 获取模型的 Provider
|
|
35
|
-
*/
|
|
36
|
-
export function routeModelToProvider(model: string): ProviderType {
|
|
37
|
-
return routeModelWithDetails(model).provider;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 获取模型的完整路由信息
|
|
42
|
-
*/
|
|
43
|
-
export function routeModelWithDetails(model: string): RouteResult {
|
|
44
|
-
const registryEntry = getModelEntry(model);
|
|
45
|
-
if (registryEntry) {
|
|
46
|
-
return {
|
|
47
|
-
provider: registryEntry.protocol,
|
|
48
|
-
registryEntry,
|
|
49
|
-
familyConfig: getModelFamily(model),
|
|
50
|
-
isDefault: false,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
provider: DEFAULT_PROVIDER,
|
|
56
|
-
isDefault: true
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* 获取默认 Provider
|
|
62
|
-
*/
|
|
63
|
-
export function getDefaultProvider(): ProviderType {
|
|
64
|
-
return DEFAULT_PROVIDER;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* 检查模型是否属于指定 Provider
|
|
69
|
-
*/
|
|
70
|
-
export function isModelForProvider(model: string, provider: ProviderType): boolean {
|
|
71
|
-
return routeModelToProvider(model) === provider;
|
|
72
|
-
}
|
package/src/tools.ts
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 工具执行器
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { ToolExecutor } from './types';
|
|
6
|
-
|
|
7
|
-
/** 危险命令黑名单 */
|
|
8
|
-
const DANGEROUS_COMMANDS = [
|
|
9
|
-
'rm -rf /', 'rm -rf ~', 'format', 'mkfs', 'dd if=',
|
|
10
|
-
'shutdown', 'reboot', 'sudo rm', 'sudo format'
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
function isDangerousCommand(command: string): boolean {
|
|
14
|
-
const lowerCommand = command.toLowerCase().trim();
|
|
15
|
-
return DANGEROUS_COMMANDS.some(dangerous =>
|
|
16
|
-
lowerCommand.includes(dangerous.toLowerCase())
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 创建默认工具执行器(Node.js 环境)
|
|
22
|
-
*
|
|
23
|
-
* 用于执行 shell 命令,包含基本安全检查
|
|
24
|
-
* 支持通过 AbortSignal 取消命令执行
|
|
25
|
-
*/
|
|
26
|
-
export function createDefaultToolExecutor(defaultCwd: string = process.cwd()): ToolExecutor {
|
|
27
|
-
return {
|
|
28
|
-
async executeCommand(command: string, cwd?: string, signal?: AbortSignal, hooks?: { onStdout?: (chunk: string) => void; onStderr?: (chunk: string) => void }) {
|
|
29
|
-
// 检查是否已取消
|
|
30
|
-
if (signal?.aborted) {
|
|
31
|
-
return { success: false, error: '操作已取消' };
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (isDangerousCommand(command)) {
|
|
35
|
-
return { success: false, error: '该命令被安全策略阻止' };
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
const { spawn } = await import('child_process');
|
|
40
|
-
|
|
41
|
-
return new Promise((resolve) => {
|
|
42
|
-
let stdout = '';
|
|
43
|
-
let stderr = '';
|
|
44
|
-
let killed = false;
|
|
45
|
-
let killTimer: NodeJS.Timeout | null = null;
|
|
46
|
-
|
|
47
|
-
const child = spawn('sh', ['-c', command], {
|
|
48
|
-
cwd: cwd || defaultCwd,
|
|
49
|
-
env: process.env,
|
|
50
|
-
// 关键:让 sh 及其子进程处于同一进程组,便于取消/超时时“一锅端”
|
|
51
|
-
// macOS/Linux: 可用负 PID kill 进程组;Windows 会忽略 detached 的语义
|
|
52
|
-
detached: process.platform !== 'win32',
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
const killProcessTree = (signalName: NodeJS.Signals) => {
|
|
56
|
-
if (killed) return;
|
|
57
|
-
killed = true;
|
|
58
|
-
try {
|
|
59
|
-
if (process.platform !== 'win32' && typeof child.pid === 'number') {
|
|
60
|
-
// 负 PID => 发送到该进程组(避免 sh 死了但子进程继续跑)
|
|
61
|
-
process.kill(-child.pid, signalName);
|
|
62
|
-
} else {
|
|
63
|
-
child.kill(signalName);
|
|
64
|
-
}
|
|
65
|
-
} catch {
|
|
66
|
-
try {
|
|
67
|
-
child.kill(signalName);
|
|
68
|
-
} catch {
|
|
69
|
-
// ignore
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// 兜底:若 SIGTERM 不生效,短延迟后再 SIGKILL
|
|
74
|
-
if (killTimer) clearTimeout(killTimer);
|
|
75
|
-
killTimer = setTimeout(() => {
|
|
76
|
-
try {
|
|
77
|
-
if (process.platform !== 'win32' && typeof child.pid === 'number') {
|
|
78
|
-
process.kill(-child.pid, 'SIGKILL');
|
|
79
|
-
} else {
|
|
80
|
-
child.kill('SIGKILL');
|
|
81
|
-
}
|
|
82
|
-
} catch {
|
|
83
|
-
// ignore
|
|
84
|
-
}
|
|
85
|
-
}, 1500);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
// 设置超时
|
|
89
|
-
const timeout = setTimeout(() => {
|
|
90
|
-
if (killed) return;
|
|
91
|
-
killProcessTree('SIGTERM');
|
|
92
|
-
resolve({ success: false, error: '命令执行超时(30秒)' });
|
|
93
|
-
}, 30000);
|
|
94
|
-
|
|
95
|
-
// 监听取消信号
|
|
96
|
-
const abortHandler = () => {
|
|
97
|
-
if (killed) return;
|
|
98
|
-
killProcessTree('SIGTERM');
|
|
99
|
-
clearTimeout(timeout);
|
|
100
|
-
resolve({ success: false, error: '操作已取消' });
|
|
101
|
-
};
|
|
102
|
-
signal?.addEventListener('abort', abortHandler);
|
|
103
|
-
|
|
104
|
-
child.stdout?.on('data', (data) => {
|
|
105
|
-
const chunk = data.toString();
|
|
106
|
-
stdout += chunk;
|
|
107
|
-
hooks?.onStdout?.(chunk);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
child.stderr?.on('data', (data) => {
|
|
111
|
-
const chunk = data.toString();
|
|
112
|
-
stderr += chunk;
|
|
113
|
-
hooks?.onStderr?.(chunk);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
child.on('close', (code) => {
|
|
117
|
-
clearTimeout(timeout);
|
|
118
|
-
signal?.removeEventListener('abort', abortHandler);
|
|
119
|
-
if (killTimer) {
|
|
120
|
-
clearTimeout(killTimer);
|
|
121
|
-
killTimer = null;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (killed) return;
|
|
125
|
-
|
|
126
|
-
const output = stdout.trim();
|
|
127
|
-
const errOutput = stderr.trim();
|
|
128
|
-
|
|
129
|
-
if (code === 0) {
|
|
130
|
-
resolve({ success: true, output: output || errOutput || '执行成功' });
|
|
131
|
-
} else {
|
|
132
|
-
// 非零退出码但有输出时,也算成功(某些命令会这样)
|
|
133
|
-
if (output) {
|
|
134
|
-
const warning = errOutput ? `\n[警告: ${errOutput}]` : '';
|
|
135
|
-
resolve({ success: true, output: output + warning });
|
|
136
|
-
} else if (errOutput) {
|
|
137
|
-
resolve({ success: false, error: errOutput });
|
|
138
|
-
} else {
|
|
139
|
-
resolve({ success: false, error: `命令退出码: ${code}` });
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
child.on('error', (err) => {
|
|
145
|
-
clearTimeout(timeout);
|
|
146
|
-
signal?.removeEventListener('abort', abortHandler);
|
|
147
|
-
if (killTimer) {
|
|
148
|
-
clearTimeout(killTimer);
|
|
149
|
-
killTimer = null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (!killed) {
|
|
153
|
-
resolve({ success: false, error: err.message });
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
} catch (error) {
|
|
158
|
-
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 调试日志工具
|
|
3
|
-
*
|
|
4
|
-
* 通过 DebugLogger.enable(true) 全局开启,
|
|
5
|
-
* 通过 DebugLogger.setLogFile(path) 同时写入 JSONL 文件,
|
|
6
|
-
* 各模块通过 DebugLogger.module('Name') 创建带前缀的 logger。
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { appendFileSync } from 'node:fs';
|
|
10
|
-
|
|
11
|
-
let enabled = false;
|
|
12
|
-
let logFilePath: string | null = null;
|
|
13
|
-
|
|
14
|
-
export class DebugLogger {
|
|
15
|
-
private prefix: string;
|
|
16
|
-
|
|
17
|
-
private constructor(prefix: string) {
|
|
18
|
-
this.prefix = prefix;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** 全局启停调试日志 */
|
|
22
|
-
static enable(value: boolean): void {
|
|
23
|
-
enabled = value;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** 查询是否已启用 */
|
|
27
|
-
static isEnabled(): boolean {
|
|
28
|
-
return enabled;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** 设置日志文件路径(JSONL 格式,追加写入) */
|
|
32
|
-
static setLogFile(filePath: string): void {
|
|
33
|
-
logFilePath = filePath;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** 创建模块专用 logger */
|
|
37
|
-
static module(name: string): DebugLogger {
|
|
38
|
-
return new DebugLogger(`[${name}]`);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
debug(...args: unknown[]): void {
|
|
42
|
-
if (enabled) {
|
|
43
|
-
console.debug(this.prefix, ...args);
|
|
44
|
-
this.writeToFile('debug', args);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
info(...args: unknown[]): void {
|
|
49
|
-
if (enabled) {
|
|
50
|
-
console.info(this.prefix, ...args);
|
|
51
|
-
this.writeToFile('info', args);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
warn(...args: unknown[]): void {
|
|
56
|
-
if (enabled) {
|
|
57
|
-
console.warn(this.prefix, ...args);
|
|
58
|
-
this.writeToFile('warn', args);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
error(...args: unknown[]): void {
|
|
63
|
-
if (enabled) {
|
|
64
|
-
console.error(this.prefix, ...args);
|
|
65
|
-
this.writeToFile('error', args);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
private writeToFile(level: string, args: unknown[]): void {
|
|
70
|
-
if (!logFilePath) return;
|
|
71
|
-
try {
|
|
72
|
-
const entry = JSON.stringify({
|
|
73
|
-
t: Date.now(),
|
|
74
|
-
level,
|
|
75
|
-
module: this.prefix,
|
|
76
|
-
args: args.map(a => {
|
|
77
|
-
try { return typeof a === 'string' ? a : JSON.parse(JSON.stringify(a)); }
|
|
78
|
-
catch { return String(a); }
|
|
79
|
-
}),
|
|
80
|
-
});
|
|
81
|
-
appendFileSync(logFilePath, entry + '\n');
|
|
82
|
-
} catch {
|
|
83
|
-
// 写文件失败不影响主流程
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|