Files
esengine--deepseek-reasonix/docs/SESSION_REFERENCE_ARCHITECTURE.md
2026-07-13 13:00:08 +08:00

14 KiB
Raw Permalink Blame History

会话引用功能架构文档

GitHub Issue: https://github.com/esengine/DeepSeek-Reasonix/issues/3185

1. 功能需求

在当前会话中使用 @ 引用其他会话的聊天记录作为内容发送给 AI。

1.1 用户场景

  • 用户在当前会话中想引用之前会话的对话内容
  • 用户想让 AI 参考之前的对话上下文
  • 用户想合并多个会话的讨论结果

1.2 预期行为(P0-MVP

输入 @
→ 显示原有菜单(文件/目录列表)
→ 菜单顶部新增 "past:chats" 选项
→ 选择 past:chats
→ 切换到历史会话列表
→ 选择一个会话
→ Composer 上方显示"已引用会话"
→ 发送时把该会话历史内容附加到当前 prompt/context

2. 现有代码结构分析

2.1 核心文件

文件 作用
desktop/frontend/src/components/Composer.tsx 输入框组件,包含 @ 功能
desktop/frontend/src/components/FileMenu.tsx @ 文件菜单组件
desktop/frontend/src/components/HistoryPanel.tsx 历史会话面板
desktop/frontend/src/lib/bridge.ts 前后端通信接口
desktop/frontend/src/lib/types.ts 类型定义

2.2 现有 @ 功能实现

Composer.tsx 第 257-337 行 实现了文件引用功能:

// --- @ file references ---
const atRaw = useMemo(() => {
  const m = /(?:^|\s)@([^\s]*)$/.exec(text);
  return m ? m[1] : null;
}, [text]);

// 文件匹配结果
const atMatches = useMemo(() => {
  // 过滤本地目录和搜索结果
}, [atRaw, atFrag, entries, searchEntries]);

// 菜单模式判断
const menuMode: "slash" | "slasharg" | "at" | null = ...;

// 渲染文件菜单
{menuMode === "at" && <FileMenu items={atMatches} ... />}

2.3 已有的会话 API(可复用)

interface AppBindings {
  // 会话列表
  ListSessions(): Promise<SessionMeta[]>;

  // 会话操作(可复用读取历史)
  PreviewSession(path: string): Promise<HistoryMessage[]>;
}

3. P0-MVP 实施方案

3.1 设计思路

在现有的 @ 菜单中添加 "past:chats" 选项,而不是创建新的 @session: 语法。

菜单结构:

@
├── 📁 past:chats        ← 新增:选择后显示历史会话列表
├── 📁 src/
├── 📁 docs/
├── 📄 README.md
└── ...

3.2 实施路线

第一步:后端加搜索接口
    ↓
第二步:前端 bridge.ts 暴露接口
    ↓
第三步:在 @ 菜单中添加 "past:chats" 选项
    ↓
第四步:选择 past:chats 后切换到会话列表
    ↓
第五步:选择会话后添加到引用区域
    ↓
第六步:发送时附加会话上下文

3.3 最小改动文件清单

desktop/frontend/src/lib/types.ts      — 添加 SessionReference 类型
desktop/frontend/src/lib/bridge.ts     — 添加 SearchSessions API
desktop/frontend/src/components/Composer.tsx — 扩展 @ 菜单逻辑
desktop/frontend/src/components/FileMenu.tsx — 扩展菜单支持会话项
desktop/app.go                         — 添加 SearchSessions 方法
desktop/sessions.go                    — 实现会话搜索逻辑

3.4 类型定义

// types.ts
export interface SessionReference {
  path: string;
  title: string;
  preview?: string;
  turns?: number;
  createdAt?: number;
  lastActivityAt?: number;
  messages?: HistoryMessage[]; // P0 先不存,发送时再拉取
}

3.5 API 设计

// bridge.ts
interface AppBindings {
  // 新增:搜索会话
  SearchSessions(query: string): Promise<SessionMeta[]>;

  // 已有:读取会话历史(复用)
  PreviewSession(path: string): Promise<HistoryMessage[]>;
}

3.6 前端逻辑修改

Composer.tsx 修改:

// 1. 添加状态
const [showPastChats, setShowPastChats] = useState(false);
const [pastChats, setPastChats] = useState<SessionMeta[]>([]);
const [sessionRefs, setSessionRefs] = useState<SessionReference[]>([]);

// 2. 修改 @ 菜单渲染
{menuMode === "at" && (
  showPastChats ? (
    // 显示会话列表
    <SessionMenu
      items={pastChats}
      activeIndex={active}
      onPick={pickSession}
      onHover={setActive}
    />
  ) : (
    // 显示文件列表(原有逻辑)
    <>
      <button
        className="slashmenu__item slashmenu__item--special"
        onMouseDown={() => {
          setShowPastChats(true);
          app.ListSessions().then(setPastChats);
        }}
      >
        <MessageSquare size={13} />
        <span className="slashmenu__name">past:chats</span>
        <span className="slashmenu__desc">引用历史会话</span>
      </button>
      <FileMenu items={atMatches} ... />
    </>
  )
)}

// 3. 选择会话后的处理
const pickSession = (session: SessionMeta) => {
  // 添加到引用区域
  setSessionRefs(prev => [...prev, {
    path: session.path,
    title: session.title || session.preview || "Untitled",
    preview: session.preview,
    turns: session.turns,
    createdAt: session.createdAt,
    lastActivityAt: session.lastActivityAt,
  }]);

  // 重置状态
  setShowPastChats(false);
  setText(""); // 清空输入框
};

// 4. 发送时附加会话上下文
const handleSubmit = async () => {
  let context = "";

  if (sessionRefs.length > 0) {
    context = "以下是用户引用的历史会话上下文:\n\n";
    for (const ref of sessionRefs) {
      const messages = await app.PreviewSession(ref.path);
      const limited = limitMessages(messages, 30, 20000);
      context += formatSessionContext(ref.title, limited);
    }
    context += "\n\n当前用户问题:\n";
  }

  onSubmit(context + text);
};

3.7 限制策略

最多引用最近 30 条消息
或最多 20k 字符
超出部分截断,并提示"已截断"

3.8 发送时的消息格式

以下是用户引用的历史会话上下文:

[会话:修复登录 bug]
用户:...
助手:...
用户:...

当前用户问题:
...

4. 架构图

┌─────────────────────────────────────────────────────────────┐
│                      Composer.tsx                           │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  @ 菜单逻辑                                          │   │
│  │  - 原有:文件/目录列表                               │   │
│  │  - 新增:past:chats 选项(在菜单顶部)              │   │
│  └─────────────────────────────────────────────────────┘   │
│                           │                                 │
│                           ▼                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  菜单渲染                                            │   │
│  │  - showPastChats=false → FileMenu + past:chats 按钮 │   │
│  │  - showPastChats=true  → SessionMenu (会话列表)     │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│                      bridge.ts                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  新增 API:                                          │   │
│  │  - SearchSessions(query): Promise<SessionMeta[]>   │   │
│  │                                                     │   │
│  │  复用 API:                                          │   │
│  │  - ListSessions(): Promise<SessionMeta[]>          │   │
│  │  - PreviewSession(path): Promise<HistoryMessage[]> │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│                    desktop/app.go                           │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  新增方法:                                          │   │
│  │  - SearchSessions(query string) []SessionMeta      │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

5. UI 设计

5.1 @ 菜单(showPastChats=false

┌─────────────────────────────────────────────────────────────┐
│  @  ← 用户输入                                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  💬 past:chats        引用历史会话                   │   │
│  ├─────────────────────────────────────────────────────┤   │
│  │  📁 src/                                             │   │
│  │  📁 docs/                                            │   │
│  │  📄 README.md                                        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  [输入消息...]                                    [发送]    │
└─────────────────────────────────────────────────────────────┘

5.2 会话列表(showPastChats=true

┌─────────────────────────────────────────────────────────────┐
│  @past:chats  ← 用户输入                                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  💬 项目架构设计讨论 - 2026-06-04                   │   │
│  │  💬 数据处理方案 - 2026-06-03                       │   │
│  │  💬 API 接口设计 - 2026-06-02                       │   │
│  │  ← 返回文件列表                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  [输入消息...]                                    [发送]    │
└─────────────────────────────────────────────────────────────┘

5.3 引用区域

┌─────────────────────────────────────────────────────────────┐
│  📎 引用的会话:                                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  📄 项目架构设计讨论 (8 轮)               [×]       │   │
│  └─────────────────────────────────────────────────────┘   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  [输入消息...]                                    [发送]    │
└─────────────────────────────────────────────────────────────┘

6. P1 后续优化(暂不实施)

  • 选择单条/多条消息
  • hover 预览会话详情
  • 截断/缓存优化
  • 国际化翻译
  • 搜索会话功能

7. 验收标准

P0 验收

  • 输入 @ 显示菜单,包含 "past:chats" 选项
  • 选择 "past:chats" 显示历史会话列表
  • 选择会话后显示在引用区域
  • 可以删除引用的会话
  • 发送时正确附加会话上下文
  • 引用内容限制在 30 条消息或 20k 字符内
  • 超出部分截断并提示

测试用例

  • 无历史会话时的行为
  • 引用超大会话时的截断
  • 与现有 @ 文件引用同时使用
  • 在不同主题下的显示效果