Files
ycode/docs/落地方案.md
T

8.5 KiB
Raw Blame History

YCode 落地方案

历史初始方案。当前运行架构优先使用 OMP RPC sidecar,自建网关保留为回退;现行目标是借助 REA 进行视觉、交互与功能 1:1 复刻。实际完成度见 接手状态-2026-10-15.md;本文件旧里程碑和排除项不作为缩减范围的依据。

日期:2026-10-14 范围:Electron 桌面应用 · 第一个里程碑 = 最小端到端闭环(能对话 + 能跑一个工具)· 自建 OpenAI 兼容网关


0. 前置决策(已确认)

项 决策 理由
产品形态 Electron 桌面应用 与对标形态一致,可复用同批开源 UI 栈
首里程碑 最小端到端闭环 一次打通 UI ↔ Agent ↔ 网关 ↔ 工具,最快验证价值
模型接入 自建网关(自有 API Key,OpenAI 兼容) 协议可控、供应商可换、密钥不出主进程
产物策略 clean-room 不复制对标产品的源码 / CSS / 资源,只用其公开架构与交互模式

1. 目标架构

┌──────────────────────────────────────────────────────┐
│ Renderer(React 19 + Zustand)                        │
│   对话区 · 右栏上下文 · 设置弹窗                          │
│   ⚠ 无 Node / fs / 网络能力                            │
└───────────────┬──────────────────────────────────────┘
                │ contextBridge(preload 白名单 API)
                │ invoke: config/session/chat
                │ event : chat:event(流式增量)
┌───────────────▼──────────────────────────────────────┐
│ Main(Electron 主进程 · ESM)                          │
│  ├ ipc.ts        唯一对外边界                          │
│  ├ config.ts     safeStorage 加密 Key                 │
│  ├ sessions.ts   会话与消息持久化                       │
│  ├ agent/loop.ts Agent 循环(模型 ↔ 工具)              │
│  └ gateway/      自建网关(OpenAI 兼容 + SSE)          │
└───────────────┬──────────────────────────────────────┘
                │ HTTPS Bearer(Key 只在此处出现)
                ▼
        自有上游(OpenAI 兼容 /chat/completions)

关键设计点

  1. 单向分层:renderer → preload → ipc → agent → gateway → 上游。反向只有 chat:event 一条流式通道。
  2. 密钥不出主进程:渲染进程只能拿到 { hasApiKey, keyStorage },永远拿不到明文。
  3. 循环与工具解耦:loop.ts 只管编排,工具是纯函数 (args, ctx) => ToolResult,新增工具只需改 tools/index.ts 注册表。
  4. 网关只管协议:模型路由、上下文裁剪、重试策略不放网关,后续可独立演进。

2. 一次回合的完整链路

用户按 Enter
  → renderer: chat.send({sessionId, text})
  → ipc: 落库用户消息 + 占位助手消息,返回 {runId, assistantMessageId}
  → loop: 拼 system + 历史 + 本轮 → gateway.stream()
  → gateway: POST /chat/completions (stream:true) → 解析 SSE
       ├ delta.content      → emit {type:'text'}      → 界面逐字追加
       └ delta.tool_calls   → 按 index 归并分片
  → 若产生工具调用:
       emit tool_call → 执行工具 → emit tool_result
       → 把 assistant(tool_calls) + tool(result) 回填上下文 → 继续下一轮
  → 无工具调用 → emit done → 更新助手消息终态

取消:chat:cancel(runId) → AbortController.abort() → 网关抛 AbortError → emit cancelled。


3. 里程碑拆解

M1 · 最小端到端闭环(本次已落地)

  • Electron 壳(contextIsolation: true / sandbox: true / 无 nodeIntegration)
  • preload 白名单 API(CJS,因为沙盒要求)
  • 自建网关:OpenAI 兼容 + SSE 流式 + 流式工具调用组装
  • Agent 循环:多轮工具调用、终止条件、取消
  • 工具:list_dir、read_file(只读 + 工作区逃逸防护)
  • 配置持久化:safeStorage 加密 Key,明文降级时 UI 告警
  • 会话持久化 + 首条消息自动命名
  • 界面:会话列表 / 对话区 / 右栏上下文 / 设置弹窗 / 明暗主题
  • 类型检查 + 构建通过

M2 · 体验与可靠性

  • Markdown 渲染(代码高亮、表格、KaTeX)
  • 消息级操作:复制、编辑重发、重新生成
  • 工具卡分组折叠(连续调用合并成摘要)
  • 断流重试与错误分类提示
  • 会话搜索与重命名

M3 · 能力扩展

  • 工具扩展:write_file / edit_file / run_shell(带权限确认)
  • 审批流:写操作与命令执行需用户确认
  • MCP 客户端接入
  • Skill 加载(SKILL.md 约定)

M4 · 平台化

  • 迁移到 SQLite
  • 项目 / 工作目录多实例
  • 右栏真实面板(产物预览、文件树、任务)
  • 打包分发(electron-builder,Windows 优先)

4. 安全基线

风险 处置
渲染进程被注入后提权 sandbox: true、无 nodeIntegration、CSP 限制 script-src 'self'
密钥泄露 只在主进程;safeStorage 加密;日志不打印
工具越权读写 路径解析后做 relative() 逃逸检查,越界直接拒绝
外链钓鱼 setWindowOpenHandler 一律 deny + shell.openExternal
任意命令执行 M1 不提供 shell 工具;M3 引入时必须走审批

5. 视觉对齐依据(对标实测值)

配色与排版不再自拟,全部取自两项实测证据:

  1. 真实 WorkBuddy 运行时布局实测 —— docs/reference/workbuddy-chat-layout.md(CDP computed style / 元素矩形)
  2. 安装包 token 表 —— tokens-Df-i-zsO.css、contexts-BkjwYSZT.css

调色板(浅色)

用途 值
正文 / 主文字 #000
次级 / 三级文字 rgba(0,0,0,.7) / rgba(0,0,0,.5)
主背景 / 次背景 #fff / #f2f2f2
hover / active #ebebeb / #e6e6e6
边框(主/次/三级) #e6e6e6 / #ebebeb / #f2f2f2
品牌 / 成功 / 警告 / 危险 / 信息 #00c29a / #0cbf5b / #ff7800 / #f64041 / #3370ff

注意:UI 主体是中性黑白灰,品牌绿只用于状态点缀,不用于主按钮或大面积色块。

圆角与间距

  • 圆角:sm 4px / md 6px / lg 8px / 气泡 16px / 输入框 24px
  • 间距基准 4px;对话内容列左右内边距 40px

字号

角色 值
caption / body 12px / 14px(行高 18 / 21)
用户气泡 13px / 19px
Markdown 根 17.143px,行高 1.75;段落 .875em → 15px / 26.25px
代码块 12.857px / 22.5px,padding 12px 16px
表头 底色 #f7f7f7,单元格 padding 8px 12px

结构尺寸

  • 左栏 280px;对话内容列 max-width 832px 居中,左右 padding 40px(正文列 752px)
  • 助手头部:24px 圆形标识 + 10px 间距,行高 24.5px,名称 14px/600,下间距 12px
  • 用户气泡:#f2f2f2、padding 8px 12px、圆角 16px 16px 0、min-width 40px、max-height 310px
  • 输入容器:1px solid #e6e6e6、圆角 24px、白底 + 双层轻阴影;编辑区 min-height 64px、横向 padding 16px;工具栏 56px、按钮 32px
  • 滚动:消息列表 flex:1 + min-height:0 + overflow-y:auto,输入区 flex-shrink:0 固定底部

落地方式:CSS 使用自有类名(.msg--assistant、.bubble 等),仅取实测数值, 不复制对标产品的类名与样式表结构。


6. 与对标分析的关系

docs/ 下三份分析报告(WorkBuddy-AI-实现分析报告、WorkBuddy-AI-复刻可行性评估、WorkBuddy-UI复刻可行性评估)用于指导选型与交互模式,不作为复制来源:

  • 可用:组件划分思路、交互状态机、协议约定、开源库清单
  • 不可用:对方源码、CSS、图标与图片资源、文案

7. 首次运行清单

  1. npm install && npm run dev
  2. ⚙ 设置:填 baseUrl / 模型名 / API Key;选工作目录
  3. 提问「列出工作目录里有哪些文件」→ 应看到工具卡出现、执行、结果回填、模型总结