主要改进: 1. 实现selectConversation功能,支持点击任务历史列表加载会话 2. 优化会话存储格式,保存完整的segments信息(包括工具调用) 3. 添加旧格式到新格式的自动转换,兼容历史数据 4. 改进错误处理,自动清理无效的空任务目录 5. 优化路径编码逻辑,确保跨平台一致性 6. 前端支持clearChat、addUserMessage、addAiMessage命令 技术细节: - 扩展AiMessage数据结构,添加segments字段 - 修改messageHandler保存逻辑,将完整segments保存到一条消息 - 实现loadTaskSession方法,加载指定任务的完整会话 - 添加自动清理机制,删除无效的空任务目录
752 lines
18 KiB
Markdown
752 lines
18 KiB
Markdown
# IC Coder 会话存储技术文档
|
||
|
||
## 1. 概述
|
||
|
||
IC Coder 的会话存储系统负责持久化保存用户与 AI 的对话历史,支持多项目、多任务的会话管理。系统采用文件系统存储方案,将会话数据按项目和任务组织,便于管理和检索。
|
||
|
||
### 1.1 核心特性
|
||
|
||
- **多项目支持**:不同项目的会话数据独立存储
|
||
- **任务级管理**:每个会话作为独立任务进行管理
|
||
- **分页加载**:支持历史会话的分页查询,提升性能
|
||
- **实时更新**:会话数据实时保存,防止数据丢失
|
||
- **统计信息**:记录 Token 使用量、对话轮次等统计数据
|
||
|
||
### 1.2 技术栈
|
||
|
||
- **存储方式**:文件系统(JSON/JSONL 格式)
|
||
- **存储位置**:`~/.iccoder/projects/{项目路径编码}/{taskId}/`
|
||
- **数据格式**:
|
||
- `meta.json`:任务元数据
|
||
- `conversation.json`:完整对话历史
|
||
- `conversation_meta.jsonl`:对话轮次元数据(JSONL 格式)
|
||
|
||
---
|
||
|
||
## 2. 架构设计
|
||
|
||
### 2.1 目录结构
|
||
|
||
```
|
||
~/.iccoder/
|
||
└── projects/
|
||
└── {项目路径编码}/
|
||
└── {taskId}/
|
||
├── meta.json # 任务元数据
|
||
├── conversation.json # 对话历史
|
||
└── conversation_meta.jsonl # 对话元数据
|
||
```
|
||
|
||
**项目路径编码规则**:
|
||
- 移除冒号 `:`
|
||
- 将斜杠 `/` 和反斜杠 `\` 替换为 `--`
|
||
- 示例:`C:\Users\admin\Documents\Project` → `C--Users--admin--Documents--Project`
|
||
|
||
**任务 ID 格式**:
|
||
- 格式:`task_{date}_{sequence}`
|
||
- 示例:`task_20231226_a3f9k2`
|
||
- `date`:8 位日期(YYYYMMDD)
|
||
- `sequence`:6 位随机字符串
|
||
|
||
### 2.2 核心类:ChatHistoryManager
|
||
|
||
`ChatHistoryManager` 是会话存储的核心管理类,采用单例模式设计。
|
||
|
||
**主要职责**:
|
||
1. 管理会话存储目录
|
||
2. 创建和切换任务
|
||
3. 保存和加载对话历史
|
||
4. 记录统计信息
|
||
5. 提供会话历史查询接口
|
||
|
||
**关键属性**:
|
||
```typescript
|
||
private static instance: ChatHistoryManager;
|
||
private baseDir: string; // ~/.iccoder
|
||
private currentTaskId: string | null; // 当前任务 ID
|
||
private currentProjectPath: string | null; // 当前项目路径
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 数据模型
|
||
|
||
### 3.1 TaskMeta(任务元数据)
|
||
|
||
存储在 `meta.json` 文件中,记录任务的基本信息和统计数据。
|
||
|
||
```typescript
|
||
interface TaskMeta {
|
||
taskId: string; // 任务 ID
|
||
taskName: string; // 任务名称
|
||
projectPath: string; // 项目路径
|
||
createdAt: string; // 创建时间(ISO 8601)
|
||
updatedAt: string; // 更新时间(ISO 8601)
|
||
stats: {
|
||
credits: number; // 消耗的积分
|
||
totalTokens: number; // 总 Token 数
|
||
inputTokens: number; // 输入 Token 数
|
||
outputTokens: number; // 输出 Token 数
|
||
};
|
||
}
|
||
```
|
||
|
||
**示例**:
|
||
```json
|
||
{
|
||
"taskId": "task_20231226_a3f9k2",
|
||
"taskName": "实现计数器功能",
|
||
"projectPath": "C:\\Users\\admin\\Documents\\Project",
|
||
"createdAt": "2023-12-26T10:30:00.000Z",
|
||
"updatedAt": "2023-12-26T11:45:00.000Z",
|
||
"stats": {
|
||
"credits": 0,
|
||
"totalTokens": 15420,
|
||
"inputTokens": 8200,
|
||
"outputTokens": 7220
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.2 ChatMessage(对话消息)
|
||
|
||
存储在 `conversation.json` 文件中,记录完整的对话历史。
|
||
|
||
**消息类型枚举**:
|
||
```typescript
|
||
enum MessageType {
|
||
USER = "USER", // 用户消息
|
||
AI = "AI", // AI 消息
|
||
SYSTEM = "SYSTEM", // 系统消息
|
||
TOOL_EXECUTION_RESULT = "TOOL_EXECUTION_RESULT" // 工具执行结果
|
||
}
|
||
```
|
||
|
||
**用户消息**:
|
||
```typescript
|
||
interface UserMessage {
|
||
type: MessageType.USER;
|
||
contents: Array<{
|
||
type: "TEXT";
|
||
text: string;
|
||
}>;
|
||
}
|
||
```
|
||
|
||
**AI 消息**:
|
||
```typescript
|
||
interface AiMessage {
|
||
type: MessageType.AI;
|
||
text: string;
|
||
toolExecutionRequests?: Array<{
|
||
id: string;
|
||
toolName: string;
|
||
parameters: any;
|
||
}>;
|
||
}
|
||
```
|
||
|
||
**系统消息**:
|
||
```typescript
|
||
interface SystemMessage {
|
||
type: MessageType.SYSTEM;
|
||
text: string;
|
||
}
|
||
```
|
||
|
||
**工具执行结果消息**:
|
||
```typescript
|
||
interface ToolExecutionResultMessage {
|
||
type: MessageType.TOOL_EXECUTION_RESULT;
|
||
id: string;
|
||
toolName: string;
|
||
text: string;
|
||
}
|
||
```
|
||
|
||
### 3.3 ConversationMeta(对话轮次元数据)
|
||
|
||
存储在 `conversation_meta.jsonl` 文件中,每行一条记录(JSONL 格式)。
|
||
|
||
```typescript
|
||
interface ConversationMeta {
|
||
turnId: number; // 对话轮次 ID
|
||
timestamp: string; // 时间戳(ISO 8601)
|
||
usage?: {
|
||
inputTokens?: number;
|
||
outputTokens?: number;
|
||
totalTokens?: number;
|
||
};
|
||
model?: string; // 使用的模型
|
||
duration?: number; // 耗时(毫秒)
|
||
}
|
||
```
|
||
|
||
**示例**:
|
||
```jsonl
|
||
{"turnId":1,"timestamp":"2023-12-26T10:30:15.000Z","usage":{"inputTokens":120,"outputTokens":350,"totalTokens":470},"model":"gpt-4","duration":2500}
|
||
{"turnId":2,"timestamp":"2023-12-26T10:32:30.000Z","usage":{"inputTokens":200,"outputTokens":450,"totalTokens":650},"model":"gpt-4","duration":3200}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 核心功能实现
|
||
|
||
### 4.1 任务创建
|
||
|
||
**方法**:`createTask(projectPath: string, taskName: string): Promise<TaskMeta>`
|
||
|
||
**流程**:
|
||
1. 生成唯一的任务 ID
|
||
2. 创建任务元数据对象
|
||
3. 创建任务目录
|
||
4. 保存 `meta.json`
|
||
5. 初始化空的 `conversation.json`
|
||
6. 设置为当前任务
|
||
|
||
**代码位置**:`chatHistoryManager.ts:114-146`
|
||
|
||
```typescript
|
||
public async createTask(projectPath: string, taskName: string): Promise<TaskMeta> {
|
||
const taskId = this.generateTaskId();
|
||
const now = new Date().toISOString();
|
||
|
||
const meta: TaskMeta = {
|
||
taskId,
|
||
taskName,
|
||
projectPath,
|
||
createdAt: now,
|
||
updatedAt: now,
|
||
stats: {
|
||
credits: 0,
|
||
totalTokens: 0,
|
||
inputTokens: 0,
|
||
outputTokens: 0
|
||
}
|
||
};
|
||
|
||
this.currentTaskId = taskId;
|
||
this.currentProjectPath = projectPath;
|
||
|
||
// 创建任务目录
|
||
const taskDir = this.getTaskDir(projectPath, taskId);
|
||
await this.ensureTaskDir(taskDir);
|
||
|
||
// 保存 meta.json
|
||
await this.saveTaskMeta(meta);
|
||
|
||
// 初始化空的 conversation.json
|
||
await this.saveConversation([]);
|
||
|
||
return meta;
|
||
}
|
||
```
|
||
|
||
### 4.2 消息保存
|
||
|
||
系统提供了四种消息保存方法:
|
||
|
||
#### 4.2.1 添加用户消息
|
||
|
||
**方法**:`addUserMessage(text: string): Promise<void>`
|
||
|
||
**代码位置**:`chatHistoryManager.ts:285-299`
|
||
|
||
```typescript
|
||
public async addUserMessage(text: string): Promise<void> {
|
||
await this.ensureCurrentTask();
|
||
const messages = await this.loadConversation();
|
||
|
||
const userMessage: UserMessage = {
|
||
type: MessageType.USER,
|
||
contents: [{ type: "TEXT", text }]
|
||
};
|
||
|
||
messages.push(userMessage);
|
||
await this.saveConversation(messages);
|
||
|
||
// 更新任务元数据
|
||
await this.updateTaskTimestamp();
|
||
}
|
||
```
|
||
|
||
#### 4.2.2 添加 AI 消息
|
||
|
||
**方法**:`addAiMessage(text: string, toolRequests?: any[]): Promise<void>`
|
||
|
||
**代码位置**:`chatHistoryManager.ts:304-319`
|
||
|
||
#### 4.2.3 添加系统消息
|
||
|
||
**方法**:`addSystemMessage(text: string): Promise<void>`
|
||
|
||
**代码位置**:`chatHistoryManager.ts:324-335`
|
||
|
||
#### 4.2.4 添加工具执行结果
|
||
|
||
**方法**:`addToolExecutionResult(id: string, toolName: string, result: string): Promise<void>`
|
||
|
||
**代码位置**:`chatHistoryManager.ts:340-353`
|
||
|
||
### 4.3 对话元数据记录
|
||
|
||
**方法**:`recordTurnMeta(turnId, usage?, model?, duration?): Promise<void>`
|
||
|
||
**功能**:记录每轮对话的元数据,包括 Token 使用量、模型信息、耗时等。
|
||
|
||
**代码位置**:`chatHistoryManager.ts:358-378`
|
||
|
||
```typescript
|
||
public async recordTurnMeta(
|
||
turnId: number,
|
||
usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number },
|
||
model?: string,
|
||
duration?: number
|
||
): Promise<void> {
|
||
const meta: ConversationMeta = {
|
||
turnId,
|
||
timestamp: new Date().toISOString(),
|
||
usage,
|
||
model,
|
||
duration
|
||
};
|
||
|
||
await this.appendConversationMeta(meta);
|
||
|
||
// 更新任务统计
|
||
if (usage) {
|
||
await this.updateTaskStats(usage);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.4 会话历史查询
|
||
|
||
**方法**:`getConversationHistoryList(projectPath, offset, limit): Promise<{items, total, hasMore}>`
|
||
|
||
**功能**:分页查询项目的会话历史列表。
|
||
|
||
**参数**:
|
||
- `projectPath`:项目路径
|
||
- `offset`:偏移量(从第几条开始,默认 0)
|
||
- `limit`:每页数量(默认 10)
|
||
|
||
**返回值**:
|
||
```typescript
|
||
{
|
||
items: Array<{
|
||
id: string; // 任务 ID
|
||
title: string; // 会话标题(第一句用户消息)
|
||
timestamp: string; // 创建时间
|
||
}>;
|
||
total: number; // 总数
|
||
hasMore: boolean; // 是否还有更多
|
||
}
|
||
```
|
||
|
||
**代码位置**:`chatHistoryManager.ts:525-590`
|
||
|
||
**实现逻辑**:
|
||
1. 获取项目的所有任务列表(按更新时间倒序)
|
||
2. 根据 offset 和 limit 进行分页
|
||
3. 读取每个任务的 `conversation.json`
|
||
4. 提取第一条用户消息作为标题(截取前 50 个字符)
|
||
5. 返回分页结果
|
||
|
||
---
|
||
|
||
## 5. 前端集成
|
||
|
||
### 5.1 会话历史栏组件
|
||
|
||
**文件**:`conversationHistoryBar.ts`
|
||
|
||
**组件结构**:
|
||
- 下拉按钮:显示 "Past Conversations"
|
||
- 下拉菜单:显示会话历史列表
|
||
- 新建按钮:创建新会话
|
||
|
||
**关键功能**:
|
||
|
||
#### 5.1.1 加载会话历史
|
||
|
||
```javascript
|
||
function loadMoreHistory() {
|
||
if (isLoadingHistory || (currentOffset > 0 && !hasMoreHistory)) {
|
||
return;
|
||
}
|
||
|
||
// 检查是否已达到最大数量(100 条)
|
||
if (currentOffset >= MAX_HISTORY_ITEMS) {
|
||
return;
|
||
}
|
||
|
||
isLoadingHistory = true;
|
||
vscode.postMessage({
|
||
command: 'loadConversationHistory',
|
||
offset: currentOffset,
|
||
limit: HISTORY_PAGE_SIZE
|
||
});
|
||
}
|
||
```
|
||
|
||
#### 5.1.2 渲染会话列表
|
||
|
||
```javascript
|
||
function renderConversationHistory(data) {
|
||
isLoadingHistory = false;
|
||
|
||
// 追加新数据
|
||
conversationHistory = conversationHistory.concat(data.items);
|
||
totalHistory = data.total;
|
||
hasMoreHistory = data.hasMore;
|
||
currentOffset += data.items.length;
|
||
|
||
// 渲染所有历史记录
|
||
historyList.innerHTML = conversationHistory.map(item => `
|
||
<div class="history-item" onclick="selectConversation('${item.id}')">
|
||
<div class="history-item-title">${item.title || '未命名会话'}</div>
|
||
<div class="history-item-time">${formatTime(item.timestamp)}</div>
|
||
</div>
|
||
`).join('');
|
||
|
||
// 如果还有更多数据,添加"加载更多"提示
|
||
if (hasMoreHistory && currentOffset < MAX_HISTORY_ITEMS) {
|
||
historyList.innerHTML += `
|
||
<div class="history-load-more">
|
||
<span>滚动加载更多...</span>
|
||
</div>
|
||
`;
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 5.1.3 滚动加载
|
||
|
||
```javascript
|
||
historyDropdownMenu.addEventListener('scroll', () => {
|
||
const menu = historyDropdownMenu;
|
||
const scrollTop = menu.scrollTop;
|
||
const scrollHeight = menu.scrollHeight;
|
||
const clientHeight = menu.clientHeight;
|
||
|
||
// 当滚动到距离底部 50px 时,加载更多
|
||
if (scrollHeight - scrollTop - clientHeight < 50) {
|
||
loadMoreHistory();
|
||
}
|
||
});
|
||
```
|
||
|
||
#### 5.1.4 时间格式化
|
||
|
||
```javascript
|
||
function formatTime(timestamp) {
|
||
const date = new Date(timestamp);
|
||
const now = new Date();
|
||
const diff = now - date;
|
||
|
||
if (diff < 60000) return '刚刚';
|
||
if (diff < 3600000) return Math.floor(diff / 60000) + '分钟前';
|
||
if (diff < 86400000) return Math.floor(diff / 3600000) + '小时前';
|
||
if (diff < 604800000) return Math.floor(diff / 86400000) + '天前';
|
||
|
||
// 超过7天显示具体日期
|
||
return date.toLocaleDateString('zh-CN', {
|
||
year: 'numeric',
|
||
month: '2-digit',
|
||
day: '2-digit'
|
||
});
|
||
}
|
||
```
|
||
|
||
### 5.2 后端消息处理
|
||
|
||
**文件**:`ICHelperPanel.ts`
|
||
|
||
**消息处理流程**:
|
||
|
||
```typescript
|
||
case "loadConversationHistory":
|
||
// 加载会话历史(支持分页)
|
||
loadConversationHistory(panel, message.offset || 0, message.limit || 10);
|
||
break;
|
||
|
||
case "selectConversation":
|
||
// 选择会话(暂未实现)
|
||
break;
|
||
|
||
case "createNewConversation":
|
||
// 创建新会话 - 在当前编辑器组中打开新标签页
|
||
showICHelperPanel(context, panel.viewColumn);
|
||
break;
|
||
```
|
||
|
||
**加载会话历史实现**:
|
||
|
||
```typescript
|
||
async function loadConversationHistory(
|
||
panel: vscode.WebviewPanel,
|
||
offset: number = 0,
|
||
limit: number = 10
|
||
) {
|
||
try {
|
||
const historyManager = ChatHistoryManager.getInstance();
|
||
const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
|
||
|
||
if (!workspacePath) {
|
||
// 没有打开的工作区,返回空历史
|
||
panel.webview.postMessage({
|
||
command: "conversationHistory",
|
||
items: [],
|
||
total: 0,
|
||
hasMore: false,
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 获取会话历史列表(支持分页)
|
||
const result = await historyManager.getConversationHistoryList(
|
||
workspacePath,
|
||
offset,
|
||
limit
|
||
);
|
||
|
||
// 发送会话历史到前端
|
||
panel.webview.postMessage({
|
||
command: "conversationHistory",
|
||
items: result.items,
|
||
total: result.total,
|
||
hasMore: result.hasMore,
|
||
});
|
||
} catch (error) {
|
||
console.error("加载会话历史失败:", error);
|
||
// 发生错误时返回空历史
|
||
panel.webview.postMessage({
|
||
command: "conversationHistory",
|
||
items: [],
|
||
total: 0,
|
||
hasMore: false,
|
||
});
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 使用示例
|
||
|
||
### 6.1 创建新任务并保存对话
|
||
|
||
```typescript
|
||
const historyManager = ChatHistoryManager.getInstance();
|
||
|
||
// 创建新任务
|
||
const task = await historyManager.createTask(
|
||
'C:\\Users\\admin\\Documents\\Project',
|
||
'实现计数器功能'
|
||
);
|
||
|
||
// 添加用户消息
|
||
await historyManager.addUserMessage('请帮我生成一个4位计数器');
|
||
|
||
// 添加 AI 消息
|
||
await historyManager.addAiMessage(
|
||
'好的,我来帮你生成一个4位计数器...',
|
||
[{ id: '1', toolName: 'generateCode', parameters: {} }]
|
||
);
|
||
|
||
// 添加工具执行结果
|
||
await historyManager.addToolExecutionResult(
|
||
'1',
|
||
'generateCode',
|
||
'代码生成成功'
|
||
);
|
||
|
||
// 记录对话元数据
|
||
await historyManager.recordTurnMeta(
|
||
1,
|
||
{ inputTokens: 120, outputTokens: 350, totalTokens: 470 },
|
||
'gpt-4',
|
||
2500
|
||
);
|
||
```
|
||
|
||
### 6.2 查询会话历史
|
||
|
||
```typescript
|
||
const historyManager = ChatHistoryManager.getInstance();
|
||
|
||
// 获取第一页(前10条)
|
||
const page1 = await historyManager.getConversationHistoryList(
|
||
'C:\\Users\\admin\\Documents\\Project',
|
||
0,
|
||
10
|
||
);
|
||
|
||
console.log('总数:', page1.total);
|
||
console.log('是否还有更多:', page1.hasMore);
|
||
console.log('会话列表:', page1.items);
|
||
|
||
// 获取第二页(第11-20条)
|
||
const page2 = await historyManager.getConversationHistoryList(
|
||
'C:\\Users\\admin\\Documents\\Project',
|
||
10,
|
||
10
|
||
);
|
||
```
|
||
|
||
### 6.3 切换任务
|
||
|
||
```typescript
|
||
const historyManager = ChatHistoryManager.getInstance();
|
||
|
||
// 切换到指定任务
|
||
const success = await historyManager.switchTask(
|
||
'C:\\Users\\admin\\Documents\\Project',
|
||
'task_20231226_a3f9k2'
|
||
);
|
||
|
||
if (success) {
|
||
// 获取当前任务会话
|
||
const session = await historyManager.getCurrentTaskSession();
|
||
console.log('任务元数据:', session.meta);
|
||
console.log('对话历史:', session.messages);
|
||
console.log('对话元数据:', session.conversationMeta);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 性能优化
|
||
|
||
### 7.1 分页加载
|
||
|
||
- 前端默认每页加载 10 条记录
|
||
- 最多显示 100 条历史记录
|
||
- 滚动到底部时自动加载下一页
|
||
|
||
### 7.2 懒加载
|
||
|
||
- 只在打开下拉菜单时才加载会话历史
|
||
- 避免不必要的文件读取操作
|
||
|
||
### 7.3 缓存机制
|
||
|
||
- 前端缓存已加载的会话列表
|
||
- 避免重复请求相同数据
|
||
|
||
### 7.4 文件格式优化
|
||
|
||
- 使用 JSONL 格式存储对话元数据,支持追加写入
|
||
- 避免频繁读写整个文件
|
||
|
||
---
|
||
|
||
## 8. 错误处理
|
||
|
||
### 8.1 目录不存在
|
||
|
||
系统会自动创建不存在的目录:
|
||
|
||
```typescript
|
||
private async ensureTaskDir(taskDir: string): Promise<void> {
|
||
try {
|
||
const uri = vscode.Uri.file(taskDir);
|
||
try {
|
||
await vscode.workspace.fs.stat(uri);
|
||
} catch {
|
||
// 目录不存在,创建它
|
||
await vscode.workspace.fs.createDirectory(uri);
|
||
console.log(`创建任务目录: ${taskDir}`);
|
||
}
|
||
} catch (error) {
|
||
console.error("创建任务目录失败:", error);
|
||
throw error;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 8.2 文件读取失败
|
||
|
||
读取失败时返回默认值:
|
||
|
||
```typescript
|
||
private async loadConversation(): Promise<ChatMessage[]> {
|
||
try {
|
||
const uri = vscode.Uri.file(conversationPath);
|
||
const content = await vscode.workspace.fs.readFile(uri);
|
||
const data = Buffer.from(content).toString('utf-8');
|
||
return JSON.parse(data);
|
||
} catch (error) {
|
||
// 文件不存在或读取失败,返回空数组
|
||
return [];
|
||
}
|
||
}
|
||
```
|
||
|
||
### 8.3 无工作区处理
|
||
|
||
没有打开工作区时,自动创建默认任务:
|
||
|
||
```typescript
|
||
private async ensureCurrentTask(): Promise<void> {
|
||
if (!this.currentTaskId || !this.currentProjectPath) {
|
||
const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
|
||
if (workspacePath) {
|
||
await this.createTask(workspacePath, "默认任务");
|
||
} else {
|
||
throw new Error("没有打开的工作区,无法创建任务");
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 未来扩展
|
||
|
||
### 9.1 会话切换功能
|
||
|
||
目前 `selectConversation` 功能暂未实现,未来可以支持:
|
||
- 点击历史会话,加载该会话的完整对话历史
|
||
- 在新标签页中打开历史会话
|
||
- 继续历史会话的对话
|
||
|
||
### 9.2 会话搜索
|
||
|
||
- 支持按关键词搜索会话
|
||
- 支持按时间范围筛选
|
||
- 支持按 Token 使用量排序
|
||
|
||
### 9.3 会话导出
|
||
|
||
- 导出为 Markdown 格式
|
||
- 导出为 JSON 格式
|
||
- 导出为 PDF 格式
|
||
|
||
### 9.4 会话统计
|
||
|
||
- 显示总对话轮次
|
||
- 显示总 Token 使用量
|
||
- 显示平均响应时间
|
||
|
||
### 9.5 云端同步
|
||
|
||
- 支持将会话数据同步到云端
|
||
- 支持多设备访问
|
||
- 支持团队协作
|
||
|
||
---
|
||
|
||
## 10. 总结
|
||
|
||
IC Coder 的会话存储系统采用文件系统存储方案,具有以下优势:
|
||
|
||
1. **简单可靠**:无需额外的数据库依赖
|
||
2. **易于备份**:直接复制文件即可备份
|
||
3. **跨平台**:支持 Windows、macOS、Linux
|
||
4. **可扩展**:易于添加新的数据字段
|
||
5. **高性能**:分页加载,避免一次性加载大量数据
|
||
|
||
系统已经实现了核心的会话管理功能,包括任务创建、消息保存、历史查询等,为用户提供了完整的会话历史管理体验。
|