tabby-ai-assistant 1.0.12 → 1.0.15
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/.editorconfig +18 -0
- package/README.md +113 -55
- package/dist/index.js +1 -1
- package/package.json +6 -4
- package/src/components/chat/ai-sidebar.component.scss +220 -9
- package/src/components/chat/ai-sidebar.component.ts +364 -29
- package/src/components/chat/chat-input.component.ts +36 -4
- package/src/components/chat/chat-interface.component.ts +225 -5
- package/src/components/chat/chat-message.component.ts +6 -1
- package/src/components/settings/context-settings.component.ts +91 -91
- package/src/components/terminal/ai-toolbar-button.component.ts +4 -2
- package/src/components/terminal/command-suggestion.component.ts +148 -6
- package/src/index.ts +0 -6
- package/src/providers/tabby/ai-toolbar-button.provider.ts +7 -3
- package/src/services/chat/ai-sidebar.service.ts +414 -410
- package/src/services/chat/chat-session.service.ts +36 -12
- package/src/services/context/compaction.ts +110 -134
- package/src/services/context/manager.ts +27 -7
- package/src/services/context/memory.ts +17 -33
- package/src/services/context/summary.service.ts +136 -0
- package/src/services/core/ai-assistant.service.ts +1060 -37
- package/src/services/core/ai-provider-manager.service.ts +154 -25
- package/src/services/core/checkpoint.service.ts +218 -18
- package/src/services/core/config-provider.service.ts +4 -12
- package/src/services/core/toast.service.ts +106 -106
- package/src/services/providers/anthropic-provider.service.ts +126 -202
- package/src/services/providers/base-provider.service.ts +315 -21
- package/src/services/providers/glm-provider.service.ts +151 -233
- package/src/services/providers/minimax-provider.service.ts +55 -238
- package/src/services/providers/ollama-provider.service.ts +117 -188
- package/src/services/providers/openai-compatible.service.ts +165 -177
- package/src/services/providers/openai-provider.service.ts +170 -177
- package/src/services/providers/vllm-provider.service.ts +116 -188
- package/src/services/terminal/terminal-context.service.ts +265 -5
- package/src/services/terminal/terminal-manager.service.ts +748 -748
- package/src/services/terminal/terminal-tools.service.ts +612 -441
- package/src/types/ai.types.ts +156 -3
- package/src/types/provider.types.ts +206 -75
- package/src/utils/cost.utils.ts +249 -0
- package/src/utils/validation.utils.ts +306 -2
- package/dist/index.js.LICENSE.txt +0 -18
- package/src/index.ts.backup +0 -165
- package/src/services/chat/chat-history.service.ts.backup +0 -239
- package/src/services/terminal/command-analyzer.service.ts +0 -43
- package/src/services/terminal/context-menu.service.ts +0 -45
- package/src/services/terminal/hotkey.service.ts +0 -53
- package/webpack.config.js.backup +0 -57
package/src/types/ai.types.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
export enum MessageRole {
|
|
7
7
|
USER = 'user',
|
|
8
8
|
ASSISTANT = 'assistant',
|
|
9
|
-
SYSTEM = 'system'
|
|
9
|
+
SYSTEM = 'system',
|
|
10
|
+
TOOL = 'tool' // 工具结果角色(部分 AI 需要)
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
// 聊天消息
|
|
@@ -140,7 +141,7 @@ export interface ValidationResult {
|
|
|
140
141
|
|
|
141
142
|
// API消息接口(支持压缩标记)
|
|
142
143
|
export interface ApiMessage {
|
|
143
|
-
role: 'user' | 'assistant' | 'system';
|
|
144
|
+
role: 'user' | 'assistant' | 'system' | 'tool' | 'function';
|
|
144
145
|
content: string | ContentBlock[];
|
|
145
146
|
ts: number; // 时间戳(毫秒)
|
|
146
147
|
|
|
@@ -148,6 +149,11 @@ export interface ApiMessage {
|
|
|
148
149
|
isSummary?: boolean; // 是否为摘要消息
|
|
149
150
|
condenseId?: string; // 摘要ID
|
|
150
151
|
condenseParent?: string; // 被哪个摘要压缩
|
|
152
|
+
summaryMeta?: { // 摘要元数据
|
|
153
|
+
originalMessageCount: number;
|
|
154
|
+
tokensCost: number;
|
|
155
|
+
compressionRatio: number;
|
|
156
|
+
};
|
|
151
157
|
|
|
152
158
|
// 截断相关元数据
|
|
153
159
|
isTruncationMarker?: boolean; // 是否为截断标记
|
|
@@ -245,6 +251,16 @@ export interface ExtendedChatMessage extends ChatMessage {
|
|
|
245
251
|
tokenUsage?: TokenUsage;
|
|
246
252
|
}
|
|
247
253
|
|
|
254
|
+
// 压缩后的检查点数据接口
|
|
255
|
+
export interface CompressedCheckpointData {
|
|
256
|
+
compressed: boolean;
|
|
257
|
+
compressionRatio: number;
|
|
258
|
+
originalSize: number;
|
|
259
|
+
compressedSize: number;
|
|
260
|
+
messages?: ApiMessage[]; // 可选,用于即时访问
|
|
261
|
+
messagesJson: string; // 压缩后的JSON字符串
|
|
262
|
+
}
|
|
263
|
+
|
|
248
264
|
// 检查点接口
|
|
249
265
|
export interface Checkpoint {
|
|
250
266
|
id: string;
|
|
@@ -253,6 +269,11 @@ export interface Checkpoint {
|
|
|
253
269
|
summary: string;
|
|
254
270
|
createdAt: number; // 时间戳(毫秒)
|
|
255
271
|
tokenUsage: TokenUsage;
|
|
272
|
+
compressedData?: CompressedCheckpointData; // 压缩数据(可选)
|
|
273
|
+
|
|
274
|
+
// 新增字段
|
|
275
|
+
tags?: string[]; // 标签列表
|
|
276
|
+
isArchived?: boolean; // 是否已归档
|
|
256
277
|
}
|
|
257
278
|
|
|
258
279
|
// ============================================================================
|
|
@@ -261,7 +282,7 @@ export interface Checkpoint {
|
|
|
261
282
|
|
|
262
283
|
// 流式事件类型
|
|
263
284
|
export interface StreamEvent {
|
|
264
|
-
type: 'text_delta' | 'tool_use_start' | 'tool_use_delta' | 'tool_use_end' | 'message_end' | 'error';
|
|
285
|
+
type: 'text_delta' | 'tool_use_start' | 'tool_use_delta' | 'tool_use_end' | 'tool_result' | 'tool_error' | 'message_end' | 'error';
|
|
265
286
|
// 文本增量
|
|
266
287
|
textDelta?: string;
|
|
267
288
|
// 工具调用(完整时才有)
|
|
@@ -270,8 +291,140 @@ export interface StreamEvent {
|
|
|
270
291
|
name: string;
|
|
271
292
|
input: any;
|
|
272
293
|
};
|
|
294
|
+
// 工具结果(tool_result 事件)
|
|
295
|
+
result?: {
|
|
296
|
+
tool_use_id: string;
|
|
297
|
+
content: string;
|
|
298
|
+
is_error?: boolean;
|
|
299
|
+
};
|
|
273
300
|
// 错误信息
|
|
274
301
|
error?: string;
|
|
275
302
|
// 最终消息(message_end 时)
|
|
276
303
|
message?: ChatMessage;
|
|
277
304
|
}
|
|
305
|
+
|
|
306
|
+
// ============================================================================
|
|
307
|
+
// Agent 循环相关类型定义
|
|
308
|
+
// ============================================================================
|
|
309
|
+
|
|
310
|
+
// 工具调用接口
|
|
311
|
+
export interface ToolCall {
|
|
312
|
+
id: string;
|
|
313
|
+
name: string;
|
|
314
|
+
input: any;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// 工具结果接口
|
|
318
|
+
export interface ToolResult {
|
|
319
|
+
tool_use_id: string;
|
|
320
|
+
name?: string; // 工具名称
|
|
321
|
+
content: string;
|
|
322
|
+
is_error?: boolean;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Agent 事件类型
|
|
326
|
+
export type AgentEventType =
|
|
327
|
+
| 'text_delta' // 文本增量
|
|
328
|
+
| 'tool_use_start' // 工具开始
|
|
329
|
+
| 'tool_use_end' // 工具调用结束(收集参数)
|
|
330
|
+
| 'tool_executing' // 工具正在执行
|
|
331
|
+
| 'tool_executed' // 工具执行完成(带结果)
|
|
332
|
+
| 'tool_error' // 工具执行错误
|
|
333
|
+
| 'round_start' // 新一轮开始
|
|
334
|
+
| 'round_end' // 一轮结束
|
|
335
|
+
| 'agent_complete' // Agent 循环完成
|
|
336
|
+
| 'error'; // 错误
|
|
337
|
+
|
|
338
|
+
// Agent 流式事件
|
|
339
|
+
export interface AgentStreamEvent {
|
|
340
|
+
type: AgentEventType;
|
|
341
|
+
|
|
342
|
+
// text_delta 事件
|
|
343
|
+
textDelta?: string;
|
|
344
|
+
|
|
345
|
+
// 工具相关事件
|
|
346
|
+
toolCall?: {
|
|
347
|
+
id: string;
|
|
348
|
+
name: string;
|
|
349
|
+
input: any;
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// tool_executed/tool_error 事件
|
|
353
|
+
toolResult?: {
|
|
354
|
+
tool_use_id: string;
|
|
355
|
+
content: string;
|
|
356
|
+
is_error?: boolean;
|
|
357
|
+
duration?: number;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
// round_start/round_end 事件
|
|
361
|
+
round?: number;
|
|
362
|
+
|
|
363
|
+
// agent_complete 事件
|
|
364
|
+
reason?: TerminationReason;
|
|
365
|
+
totalRounds?: number;
|
|
366
|
+
terminationMessage?: string; // 可选的终止详情消息
|
|
367
|
+
|
|
368
|
+
// error 事件
|
|
369
|
+
error?: string;
|
|
370
|
+
|
|
371
|
+
// message_end 保留
|
|
372
|
+
message?: ChatMessage;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Agent 循环配置
|
|
376
|
+
export interface AgentLoopConfig {
|
|
377
|
+
maxRounds?: number; // 最大轮数,默认 15
|
|
378
|
+
timeoutMs?: number; // 默认 120000 (2分钟)
|
|
379
|
+
repeatThreshold?: number; // 默认 3 次
|
|
380
|
+
failureThreshold?: number; // 默认 2 次
|
|
381
|
+
enableTaskComplete?: boolean; // 默认 true
|
|
382
|
+
onRoundStart?: (round: number) => void;
|
|
383
|
+
onRoundEnd?: (round: number) => void;
|
|
384
|
+
onAgentComplete?: (reason: string, totalRounds: number) => void;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// ============================================================================
|
|
388
|
+
// 智能 Agent 终止相关类型定义
|
|
389
|
+
// ============================================================================
|
|
390
|
+
|
|
391
|
+
// 终止原因枚举
|
|
392
|
+
export type TerminationReason =
|
|
393
|
+
| 'task_complete' // AI 主动调用 task_complete 工具
|
|
394
|
+
| 'no_tools' // 本轮无工具调用
|
|
395
|
+
| 'summarizing' // 检测到 AI 正在总结
|
|
396
|
+
| 'repeated_tool' // 重复调用相同工具
|
|
397
|
+
| 'high_failure_rate' // 连续失败率过高
|
|
398
|
+
| 'timeout' // 总时间超时
|
|
399
|
+
| 'max_rounds' // 达到最大轮数(安全保底)
|
|
400
|
+
| 'user_cancel'; // 用户取消
|
|
401
|
+
|
|
402
|
+
// Agent 状态追踪
|
|
403
|
+
export interface AgentState {
|
|
404
|
+
currentRound: number;
|
|
405
|
+
startTime: number;
|
|
406
|
+
toolCallHistory: ToolCallRecord[];
|
|
407
|
+
lastAiResponse: string;
|
|
408
|
+
isActive: boolean;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// 工具调用记录
|
|
412
|
+
export interface ToolCallRecord {
|
|
413
|
+
name: string;
|
|
414
|
+
input: any;
|
|
415
|
+
inputHash: string; // 用于快速比较
|
|
416
|
+
success: boolean;
|
|
417
|
+
timestamp: number;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// 终止检测结果
|
|
421
|
+
export interface TerminationResult {
|
|
422
|
+
shouldTerminate: boolean;
|
|
423
|
+
reason: TerminationReason;
|
|
424
|
+
message?: string;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// 扩展 ToolResult 添加任务完成标记
|
|
428
|
+
export interface ExtendedToolResult extends ToolResult {
|
|
429
|
+
isTaskComplete?: boolean; // 特殊标记:task_complete 工具调用
|
|
430
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* AI提供商相关类型定义
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { Observable } from 'rxjs';
|
|
5
6
|
import { ProviderCapability, HealthStatus, ValidationResult } from './ai.types';
|
|
6
7
|
import { ChatRequest, ChatResponse, CommandRequest, CommandResponse, ExplainRequest, ExplainResponse, AnalysisRequest, AnalysisResponse } from './ai.types';
|
|
7
8
|
|
|
@@ -9,14 +10,18 @@ import { ChatRequest, ChatResponse, CommandRequest, CommandResponse, ExplainRequ
|
|
|
9
10
|
export { ProviderCapability, HealthStatus, ValidationResult };
|
|
10
11
|
export { ChatRequest, ChatResponse, CommandRequest, CommandResponse, ExplainRequest, ExplainResponse, AnalysisRequest, AnalysisResponse };
|
|
11
12
|
|
|
12
|
-
// 认证配置
|
|
13
|
+
// ==================== 认证配置 ====================
|
|
14
|
+
|
|
15
|
+
export type AuthType = 'apiKey' | 'bearer' | 'basic' | 'oauth' | 'none';
|
|
16
|
+
|
|
13
17
|
export interface AuthConfig {
|
|
14
|
-
type:
|
|
18
|
+
type: AuthType;
|
|
15
19
|
credentials: Record<string, string>;
|
|
16
20
|
requiresEncryption?: boolean;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
// 提供商配置
|
|
23
|
+
// ==================== 提供商配置 ====================
|
|
24
|
+
|
|
20
25
|
export interface ProviderConfig {
|
|
21
26
|
name: string;
|
|
22
27
|
displayName: string;
|
|
@@ -32,111 +37,234 @@ export interface ProviderConfig {
|
|
|
32
37
|
contextWindow?: number; // 供应商上下文窗口限制
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
//
|
|
36
|
-
export interface
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// 提供商默认配置
|
|
41
|
+
export interface ProviderDefaults {
|
|
42
|
+
baseURL: string;
|
|
43
|
+
model: string;
|
|
44
|
+
maxTokens: number;
|
|
45
|
+
temperature: number;
|
|
46
|
+
timeout: number;
|
|
47
|
+
retries: number;
|
|
48
|
+
contextWindow: number;
|
|
42
49
|
authConfig: AuthConfig;
|
|
43
|
-
supportedModels: string[];
|
|
44
|
-
pricing?: {
|
|
45
|
-
type: 'free' | 'paid' | 'freemium';
|
|
46
|
-
currency: string;
|
|
47
|
-
unit: string;
|
|
48
|
-
costPerUnit?: number;
|
|
49
|
-
};
|
|
50
|
-
documentation?: string;
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
//
|
|
54
|
-
export
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
52
|
+
// 所有已知提供商及其默认配置
|
|
53
|
+
export const PROVIDER_DEFAULTS: Record<string, ProviderDefaults> = {
|
|
54
|
+
openai: {
|
|
55
|
+
baseURL: 'https://api.openai.com/v1',
|
|
56
|
+
model: 'gpt-4',
|
|
57
|
+
maxTokens: 1000,
|
|
58
|
+
temperature: 0.7,
|
|
59
|
+
timeout: 30000,
|
|
60
|
+
retries: 3,
|
|
61
|
+
contextWindow: 128000,
|
|
62
|
+
authConfig: { type: 'bearer', credentials: {} }
|
|
63
|
+
},
|
|
64
|
+
anthropic: {
|
|
65
|
+
baseURL: 'https://api.anthropic.com',
|
|
66
|
+
model: 'claude-3-sonnet',
|
|
67
|
+
maxTokens: 1000,
|
|
68
|
+
temperature: 1.0,
|
|
69
|
+
timeout: 30000,
|
|
70
|
+
retries: 3,
|
|
71
|
+
contextWindow: 200000,
|
|
72
|
+
authConfig: { type: 'bearer', credentials: {} }
|
|
73
|
+
},
|
|
74
|
+
minimax: {
|
|
75
|
+
baseURL: 'https://api.minimaxi.com/anthropic',
|
|
76
|
+
model: 'MiniMax-M2',
|
|
77
|
+
maxTokens: 1000,
|
|
78
|
+
temperature: 1.0,
|
|
79
|
+
timeout: 30000,
|
|
80
|
+
retries: 3,
|
|
81
|
+
contextWindow: 128000,
|
|
82
|
+
authConfig: { type: 'bearer', credentials: {} }
|
|
83
|
+
},
|
|
84
|
+
glm: {
|
|
85
|
+
baseURL: 'https://open.bigmodel.cn/api/anthropic',
|
|
86
|
+
model: 'glm-4.6',
|
|
87
|
+
maxTokens: 1000,
|
|
88
|
+
temperature: 0.95,
|
|
89
|
+
timeout: 30000,
|
|
90
|
+
retries: 3,
|
|
91
|
+
contextWindow: 128000,
|
|
92
|
+
authConfig: { type: 'bearer', credentials: {} }
|
|
93
|
+
},
|
|
94
|
+
ollama: {
|
|
95
|
+
baseURL: 'http://localhost:11434/v1',
|
|
96
|
+
model: 'llama3.1',
|
|
97
|
+
maxTokens: 1000,
|
|
98
|
+
temperature: 0.7,
|
|
99
|
+
timeout: 30000,
|
|
100
|
+
retries: 3,
|
|
101
|
+
contextWindow: 8192,
|
|
102
|
+
authConfig: { type: 'none', credentials: {} }
|
|
103
|
+
},
|
|
104
|
+
vllm: {
|
|
105
|
+
baseURL: 'http://localhost:8000/v1',
|
|
106
|
+
model: 'meta-llama/Llama-3.1-8B',
|
|
107
|
+
maxTokens: 1000,
|
|
108
|
+
temperature: 0.7,
|
|
109
|
+
timeout: 30000,
|
|
110
|
+
retries: 3,
|
|
111
|
+
contextWindow: 8192,
|
|
112
|
+
authConfig: { type: 'bearer', credentials: {} }
|
|
113
|
+
},
|
|
114
|
+
'openai-compatible': {
|
|
115
|
+
baseURL: 'http://localhost:11434/v1',
|
|
116
|
+
model: 'gpt-3.5-turbo',
|
|
117
|
+
maxTokens: 1000,
|
|
118
|
+
temperature: 0.7,
|
|
119
|
+
timeout: 30000,
|
|
120
|
+
retries: 3,
|
|
121
|
+
contextWindow: 128000,
|
|
122
|
+
authConfig: { type: 'bearer', credentials: {} }
|
|
123
|
+
}
|
|
124
|
+
};
|
|
76
125
|
|
|
126
|
+
// 配置工具函数
|
|
127
|
+
export namespace ProviderConfigUtils {
|
|
77
128
|
/**
|
|
78
|
-
*
|
|
129
|
+
* 使用默认值填充配置
|
|
79
130
|
*/
|
|
80
|
-
|
|
131
|
+
export function fillDefaults(config: Partial<ProviderConfig>, providerName: string): ProviderConfig {
|
|
132
|
+
const defaults = PROVIDER_DEFAULTS[providerName];
|
|
133
|
+
if (!defaults) {
|
|
134
|
+
throw new Error(`Unknown provider: ${providerName}`);
|
|
135
|
+
}
|
|
81
136
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
137
|
+
return {
|
|
138
|
+
name: config.name || providerName,
|
|
139
|
+
displayName: config.displayName || providerName,
|
|
140
|
+
apiKey: config.apiKey,
|
|
141
|
+
baseURL: config.baseURL || defaults.baseURL,
|
|
142
|
+
model: config.model || defaults.model,
|
|
143
|
+
maxTokens: config.maxTokens ?? defaults.maxTokens,
|
|
144
|
+
temperature: config.temperature ?? defaults.temperature,
|
|
145
|
+
timeout: config.timeout ?? defaults.timeout,
|
|
146
|
+
retries: config.retries ?? defaults.retries,
|
|
147
|
+
authConfig: config.authConfig || defaults.authConfig,
|
|
148
|
+
enabled: config.enabled ?? true,
|
|
149
|
+
contextWindow: config.contextWindow ?? defaults.contextWindow
|
|
150
|
+
};
|
|
151
|
+
}
|
|
86
152
|
|
|
87
153
|
/**
|
|
88
|
-
*
|
|
154
|
+
* 检查配置是否完整(可用于API调用)
|
|
89
155
|
*/
|
|
90
|
-
|
|
156
|
+
export function isConfigComplete(config: ProviderConfig): boolean {
|
|
157
|
+
return !!(
|
|
158
|
+
config.name &&
|
|
159
|
+
config.displayName &&
|
|
160
|
+
// API key 不是必需的(如本地服务)
|
|
161
|
+
(config.apiKey || config.authConfig?.type === 'none') &&
|
|
162
|
+
config.baseURL
|
|
163
|
+
);
|
|
164
|
+
}
|
|
91
165
|
|
|
92
166
|
/**
|
|
93
|
-
*
|
|
167
|
+
* 克隆配置(深拷贝,移除敏感信息)
|
|
94
168
|
*/
|
|
95
|
-
|
|
169
|
+
export function cloneConfig(config: ProviderConfig, maskApiKey = true): ProviderConfig {
|
|
170
|
+
const clone = { ...config };
|
|
171
|
+
if (maskApiKey && clone.apiKey) {
|
|
172
|
+
clone.apiKey = '***MASKED***';
|
|
173
|
+
}
|
|
174
|
+
return clone;
|
|
175
|
+
}
|
|
96
176
|
|
|
97
177
|
/**
|
|
98
|
-
*
|
|
178
|
+
* 获取提供商默认配置
|
|
99
179
|
*/
|
|
100
|
-
|
|
101
|
-
return
|
|
102
|
-
name: this.name,
|
|
103
|
-
displayName: this.displayName,
|
|
104
|
-
version: '1.0.0',
|
|
105
|
-
description: `${this.displayName} AI Provider`,
|
|
106
|
-
capabilities: this.capabilities,
|
|
107
|
-
authConfig: this.authConfig,
|
|
108
|
-
supportedModels: this.config?.model ? [this.config.model] : []
|
|
109
|
-
};
|
|
180
|
+
export function getDefaults(providerName: string): ProviderDefaults | undefined {
|
|
181
|
+
return PROVIDER_DEFAULTS[providerName];
|
|
110
182
|
}
|
|
111
183
|
|
|
112
184
|
/**
|
|
113
|
-
*
|
|
185
|
+
* 获取所有已知提供商名称
|
|
114
186
|
*/
|
|
115
|
-
|
|
116
|
-
return
|
|
187
|
+
export function getKnownProviders(): string[] {
|
|
188
|
+
return Object.keys(PROVIDER_DEFAULTS);
|
|
117
189
|
}
|
|
118
190
|
|
|
119
191
|
/**
|
|
120
|
-
*
|
|
192
|
+
* 检查是否为已知提供商
|
|
121
193
|
*/
|
|
122
|
-
|
|
123
|
-
return
|
|
194
|
+
export function isKnownProvider(name: string): boolean {
|
|
195
|
+
return name in PROVIDER_DEFAULTS;
|
|
124
196
|
}
|
|
125
197
|
}
|
|
126
198
|
|
|
127
|
-
//
|
|
199
|
+
// ==================== 提供商信息 ====================
|
|
200
|
+
|
|
201
|
+
export interface ProviderPricing {
|
|
202
|
+
type: 'free' | 'paid' | 'freemium';
|
|
203
|
+
currency: string;
|
|
204
|
+
unit: string;
|
|
205
|
+
costPerUnit?: number;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface ProviderInfo {
|
|
209
|
+
name: string;
|
|
210
|
+
displayName: string;
|
|
211
|
+
version: string;
|
|
212
|
+
description: string;
|
|
213
|
+
capabilities: ProviderCapability[];
|
|
214
|
+
authConfig: AuthConfig;
|
|
215
|
+
supportedModels: string[];
|
|
216
|
+
configured?: boolean;
|
|
217
|
+
lastHealthCheck?: { status: HealthStatus; timestamp: Date };
|
|
218
|
+
pricing?: ProviderPricing;
|
|
219
|
+
documentation?: string;
|
|
220
|
+
defaults?: ProviderDefaults;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// ==================== 基础AI提供商接口 ====================
|
|
224
|
+
|
|
225
|
+
export interface IBaseAiProvider {
|
|
226
|
+
readonly name: string;
|
|
227
|
+
readonly displayName: string;
|
|
228
|
+
readonly capabilities: ProviderCapability[];
|
|
229
|
+
readonly authConfig: AuthConfig;
|
|
230
|
+
|
|
231
|
+
// 配置与状态
|
|
232
|
+
configure(config: ProviderConfig): void;
|
|
233
|
+
getConfig(): ProviderConfig | null;
|
|
234
|
+
isConfigured(): boolean;
|
|
235
|
+
isEnabled(): boolean;
|
|
236
|
+
|
|
237
|
+
// 核心功能
|
|
238
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
239
|
+
chatStream(request: ChatRequest): Observable<any>;
|
|
240
|
+
generateCommand(request: CommandRequest): Promise<CommandResponse>;
|
|
241
|
+
explainCommand(request: ExplainRequest): Promise<ExplainResponse>;
|
|
242
|
+
analyzeResult(request: AnalysisRequest): Promise<AnalysisResponse>;
|
|
243
|
+
|
|
244
|
+
// 健康与验证
|
|
245
|
+
healthCheck(): Promise<HealthStatus>;
|
|
246
|
+
validateConfig(): ValidationResult;
|
|
247
|
+
|
|
248
|
+
// 信息查询
|
|
249
|
+
getInfo(): ProviderInfo;
|
|
250
|
+
supportsCapability(capability: ProviderCapability): boolean;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ==================== 提供商管理器 ====================
|
|
254
|
+
|
|
128
255
|
export interface ProviderManager {
|
|
129
|
-
registerProvider(provider:
|
|
256
|
+
registerProvider(provider: IBaseAiProvider): void;
|
|
130
257
|
unregisterProvider(name: string): void;
|
|
131
|
-
getProvider(name: string):
|
|
132
|
-
getAllProviders():
|
|
133
|
-
getActiveProvider():
|
|
258
|
+
getProvider(name: string): IBaseAiProvider | undefined;
|
|
259
|
+
getAllProviders(): IBaseAiProvider[];
|
|
260
|
+
getActiveProvider(): IBaseAiProvider | undefined;
|
|
134
261
|
setActiveProvider(name: string): boolean;
|
|
135
262
|
getProviderInfo(name: string): ProviderInfo | undefined;
|
|
136
263
|
getAllProviderInfo(): ProviderInfo[];
|
|
137
264
|
}
|
|
138
265
|
|
|
139
|
-
// 提供商事件
|
|
266
|
+
// ==================== 提供商事件 ====================
|
|
267
|
+
|
|
140
268
|
export interface ProviderEvent {
|
|
141
269
|
type: 'connected' | 'disconnected' | 'error' | 'config_changed' | 'health_changed';
|
|
142
270
|
provider: string;
|
|
@@ -144,5 +272,8 @@ export interface ProviderEvent {
|
|
|
144
272
|
data?: any;
|
|
145
273
|
}
|
|
146
274
|
|
|
147
|
-
// 提供商事件监听器
|
|
148
275
|
export type ProviderEventListener = (event: ProviderEvent) => void;
|
|
276
|
+
|
|
277
|
+
// ==================== 便利类型 ====================
|
|
278
|
+
|
|
279
|
+
export type BaseAiProvider = IBaseAiProvider;
|