feat(context): 优化对话压缩系统
- 添加独立摘要模型配置支持(SUMMARY_PROVIDER/MODEL/API_KEY/BASE_URL) - 添加 CompressionStatus 枚举和 DetailedCompressionResult 详细返回类型 - 实现压缩失败检测(空摘要、token膨胀) - 添加首条 user-assistant 对保护,确保上下文连贯性 - CompressionManager 支持独立摘要模型(优先使用小模型降低成本) - Agent 自动压缩时显示详细状态信息 - 更新相关测试用例
This commit is contained in:
@@ -23,6 +23,13 @@ interface StoredConfig {
|
||||
visionApiKey?: string;
|
||||
/** Vision 专用的 Base URL(用于 OpenAI 兼容的 Vision 服务) */
|
||||
visionBaseUrl?: string;
|
||||
// Summary 配置(用于对话压缩摘要生成)
|
||||
summaryProvider?: ProviderType;
|
||||
summaryModel?: string;
|
||||
/** Summary 专用的 API Key(可选,不设置则使用对应 provider 的 key) */
|
||||
summaryApiKey?: string;
|
||||
/** Summary 专用的 Base URL(用于 OpenAI 兼容的 Summary 服务) */
|
||||
summaryBaseUrl?: string;
|
||||
}
|
||||
|
||||
// Vision 配置接口
|
||||
@@ -34,6 +41,15 @@ export interface VisionConfig {
|
||||
baseUrl?: string;
|
||||
}
|
||||
|
||||
// Summary 配置接口(用于对话压缩摘要生成)
|
||||
export interface SummaryConfig {
|
||||
provider: ProviderType;
|
||||
apiKey: string;
|
||||
model: string;
|
||||
/** 自定义 Base URL(用于 OpenAI 兼容的 Summary 服务) */
|
||||
baseUrl?: string;
|
||||
}
|
||||
|
||||
// 默认模型配置
|
||||
const DEFAULT_MODELS: Record<ProviderType, string> = {
|
||||
anthropic: 'claude-sonnet-4-20250514',
|
||||
@@ -48,6 +64,13 @@ const DEFAULT_VISION_MODELS: Record<ProviderType, string> = {
|
||||
openai: 'gpt-4o',
|
||||
};
|
||||
|
||||
// 默认 Summary 模型(推荐使用成本较低的模型)
|
||||
const DEFAULT_SUMMARY_MODELS: Record<ProviderType, string> = {
|
||||
anthropic: 'claude-3-5-haiku-20241022',
|
||||
deepseek: 'deepseek-chat',
|
||||
openai: 'gpt-4o-mini',
|
||||
};
|
||||
|
||||
// 默认系统提示词
|
||||
const DEFAULT_SYSTEM_PROMPT = `你是一个运行在终端中的 AI 编程助手。你可以帮助用户:
|
||||
- 读取和写入文件
|
||||
@@ -200,6 +223,75 @@ export function loadVisionConfig(): VisionConfig | null {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载 Summary 配置
|
||||
* Summary 用于对话压缩时生成摘要,推荐使用成本较低的小模型
|
||||
* 优先级:环境变量 > 配置文件 > null(使用主模型)
|
||||
*/
|
||||
export function loadSummaryConfig(): SummaryConfig | null {
|
||||
// 从环境变量获取
|
||||
const summaryProvider = process.env.SUMMARY_PROVIDER as ProviderType | undefined;
|
||||
const summaryModel = process.env.SUMMARY_MODEL;
|
||||
const summaryApiKey = process.env.SUMMARY_API_KEY;
|
||||
const summaryBaseUrl = process.env.SUMMARY_BASE_URL;
|
||||
const anthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
||||
const deepseekApiKey = process.env.DEEPSEEK_API_KEY;
|
||||
const openaiApiKey = process.env.OPENAI_API_KEY;
|
||||
|
||||
// 从配置文件读取
|
||||
const storedConfig = getConfig();
|
||||
|
||||
// 如果没有任何 summary 相关配置,返回 null(使用主模型)
|
||||
const hasSummaryConfig =
|
||||
summaryProvider ||
|
||||
summaryModel ||
|
||||
summaryApiKey ||
|
||||
storedConfig.summaryProvider ||
|
||||
storedConfig.summaryModel ||
|
||||
storedConfig.summaryApiKey;
|
||||
|
||||
if (!hasSummaryConfig) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 确定 summary provider(默认使用主配置的 provider)
|
||||
const mainProvider = (process.env.AI_PROVIDER as ProviderType) || storedConfig.provider || 'anthropic';
|
||||
const finalProvider = summaryProvider || storedConfig.summaryProvider || mainProvider;
|
||||
|
||||
// 获取 Summary 专用的 API Key(优先级:环境变量 > 配置文件专用 key > provider 对应的 key)
|
||||
let finalApiKey: string | undefined;
|
||||
finalApiKey = summaryApiKey || storedConfig.summaryApiKey;
|
||||
|
||||
// 如果没有专用 key,回退到对应 provider 的 key
|
||||
if (!finalApiKey) {
|
||||
if (finalProvider === 'anthropic') {
|
||||
finalApiKey = anthropicApiKey || storedConfig.apiKey;
|
||||
} else if (finalProvider === 'deepseek') {
|
||||
finalApiKey = deepseekApiKey || storedConfig.deepseekApiKey;
|
||||
} else if (finalProvider === 'openai') {
|
||||
finalApiKey = openaiApiKey || storedConfig.openaiApiKey;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有 API Key,返回 null
|
||||
if (!finalApiKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 确定模型
|
||||
const finalModel = summaryModel || storedConfig.summaryModel || DEFAULT_SUMMARY_MODELS[finalProvider];
|
||||
|
||||
// 确定 baseUrl(Summary 专用)
|
||||
const finalBaseUrl = summaryBaseUrl || storedConfig.summaryBaseUrl;
|
||||
|
||||
return {
|
||||
provider: finalProvider,
|
||||
apiKey: finalApiKey,
|
||||
model: finalModel,
|
||||
baseUrl: finalBaseUrl,
|
||||
};
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
export function saveConfig(config: Partial<StoredConfig>): void {
|
||||
// 确保目录存在
|
||||
|
||||
Reference in New Issue
Block a user