feat: 添加对话压缩功能和上下文使用情况显示
- 新增 context 模块实现 Prune 和 Compaction 压缩策略 - Prune: 将旧工具调用结果替换为占位符 - Compaction: 使用 AI 生成对话摘要 - CLI 提示符显示上下文使用量 [used/available] - 添加 /compact 命令手动压缩对话 - 添加 /context 命令查看上下文详情 - Agent 集成自动压缩 (85%阈值) 和强制压缩功能
This commit is contained in:
+70
-8
@@ -28,14 +28,36 @@ export class TerminalUI {
|
||||
console.log(chalk.cyan('║') + chalk.gray(' Powered by DeepSeek / Claude ') + chalk.cyan('║'));
|
||||
console.log(chalk.cyan('╚════════════════════════════════════════╝\n'));
|
||||
console.log(chalk.gray('输入你的问题,或使用以下命令:'));
|
||||
console.log(chalk.yellow(' /help') + chalk.gray(' - 显示帮助'));
|
||||
console.log(chalk.yellow(' /clear') + chalk.gray(' - 清空对话历史'));
|
||||
console.log(chalk.yellow(' /exit') + chalk.gray(' - 退出程序'));
|
||||
console.log(chalk.yellow(' /help') + chalk.gray(' - 显示帮助'));
|
||||
console.log(chalk.yellow(' /clear') + chalk.gray(' - 清空对话历史'));
|
||||
console.log(chalk.yellow(' /compact') + chalk.gray(' - 压缩对话历史'));
|
||||
console.log(chalk.yellow(' /context') + chalk.gray(' - 查看上下文使用情况'));
|
||||
console.log(chalk.yellow(' /exit') + chalk.gray(' - 退出程序'));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// 格式化上下文使用情况(带颜色)
|
||||
private formatContextUsage(): string {
|
||||
const usage = this.agent.getContextUsage();
|
||||
const percent = usage.usagePercent;
|
||||
|
||||
// 根据使用率选择颜色
|
||||
let colorFn: (text: string) => string;
|
||||
if (percent < 50) {
|
||||
colorFn = chalk.green;
|
||||
} else if (percent < 80) {
|
||||
colorFn = chalk.yellow;
|
||||
} else {
|
||||
colorFn = chalk.red;
|
||||
}
|
||||
|
||||
const used = usage.input >= 1000 ? `${(usage.input / 1000).toFixed(1)}k` : `${usage.input}`;
|
||||
const limit = `${(usage.available / 1000).toFixed(0)}k`;
|
||||
return colorFn(`[${used}/${limit}]`);
|
||||
}
|
||||
|
||||
// 处理特殊命令
|
||||
private handleCommand(input: string): boolean {
|
||||
private async handleCommand(input: string): Promise<boolean> {
|
||||
const command = input.toLowerCase().trim();
|
||||
|
||||
switch (command) {
|
||||
@@ -47,14 +69,52 @@ export class TerminalUI {
|
||||
console.log(chalk.gray(' • 搜索代码'));
|
||||
console.log(chalk.gray(' • 回答编程问题'));
|
||||
console.log('');
|
||||
console.log(chalk.white(' 命令:'));
|
||||
console.log(chalk.gray(' • /help - 显示此帮助'));
|
||||
console.log(chalk.gray(' • /clear - 清空对话历史'));
|
||||
console.log(chalk.gray(' • /compact - 压缩对话历史,释放上下文空间'));
|
||||
console.log(chalk.gray(' • /context - 显示当前上下文使用情况'));
|
||||
console.log(chalk.gray(' • /exit - 退出程序'));
|
||||
console.log('');
|
||||
return true;
|
||||
|
||||
case '/clear':
|
||||
// clearHistory 现在是异步的
|
||||
void this.agent.clearHistory();
|
||||
await this.agent.clearHistory();
|
||||
console.log(chalk.green('✓ 对话历史已清空\n'));
|
||||
return true;
|
||||
|
||||
case '/compact':
|
||||
console.log(chalk.yellow('正在压缩对话历史...\n'));
|
||||
try {
|
||||
const beforeUsage = this.agent.getContextUsage();
|
||||
const result = await this.agent.compactHistory();
|
||||
const afterUsage = this.agent.getContextUsage();
|
||||
|
||||
if (result.freedTokens > 0) {
|
||||
console.log(chalk.green(`✓ 压缩完成!`));
|
||||
console.log(chalk.gray(` 策略: ${result.type}`));
|
||||
console.log(chalk.gray(` 释放: ${(result.freedTokens / 1000).toFixed(1)}k tokens`));
|
||||
console.log(chalk.gray(` 之前: ${(beforeUsage.input / 1000).toFixed(1)}k`));
|
||||
console.log(chalk.gray(` 之后: ${(afterUsage.input / 1000).toFixed(1)}k`));
|
||||
} else {
|
||||
console.log(chalk.yellow('没有可压缩的内容'));
|
||||
}
|
||||
console.log('');
|
||||
} catch (error) {
|
||||
console.log(chalk.red(`压缩失败: ${error instanceof Error ? error.message : String(error)}\n`));
|
||||
}
|
||||
return true;
|
||||
|
||||
case '/context':
|
||||
const usage = this.agent.getContextUsage();
|
||||
console.log(chalk.cyan('\n📊 上下文使用情况:'));
|
||||
console.log(chalk.gray(` 已使用: ${(usage.input / 1000).toFixed(1)}k tokens`));
|
||||
console.log(chalk.gray(` 可用: ${(usage.available / 1000).toFixed(0)}k tokens`));
|
||||
console.log(chalk.gray(` 上下文限制: ${(usage.contextLimit / 1000).toFixed(0)}k tokens`));
|
||||
console.log(chalk.gray(` 使用率: ${usage.usagePercent.toFixed(1)}%`));
|
||||
console.log('');
|
||||
return true;
|
||||
|
||||
case '/exit':
|
||||
case '/quit':
|
||||
console.log(chalk.cyan('\n👋 再见!\n'));
|
||||
@@ -74,7 +134,9 @@ export class TerminalUI {
|
||||
return;
|
||||
}
|
||||
|
||||
this.rl.question(chalk.green('You > '), (answer) => {
|
||||
// 显示带上下文使用情况的提示符
|
||||
const contextInfo = this.formatContextUsage();
|
||||
this.rl.question(`${contextInfo} ${chalk.green('You >')} `, (answer) => {
|
||||
resolve(answer ?? '');
|
||||
});
|
||||
});
|
||||
@@ -95,7 +157,7 @@ export class TerminalUI {
|
||||
|
||||
// 处理命令
|
||||
if (input.startsWith('/')) {
|
||||
if (this.handleCommand(input)) {
|
||||
if (await this.handleCommand(input)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user