From 89d024a2003c8a2c613acaeb424aee647b8abf57 Mon Sep 17 00:00:00 2001 From: brother7 <7brother7@gmail.com> Date: Wed, 12 Aug 2026 23:47:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E6=A1=A3=EF=BC=9A=E9=9B=86=E6=88=90?= =?UTF-8?q?=E9=A6=96=E6=AC=A1=E4=BC=9A=E8=AF=9D=E5=BB=B6=E8=BF=9F=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=A5=91=E7=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .project-docs/20-architecture/data-flow.md | 5 ++ .project-docs/20-architecture/module-map.md | 6 ++ .project-docs/30-worklog/current-state.md | 5 ++ .../20260812-integrate-first-chat-fix-c31e.md | 80 +++++++++++++++++++ .project-docs/50-evidence/evidence-index.md | 1 + .project-docs/80-commitments/commitments.md | 1 + 6 files changed, 98 insertions(+) create mode 100644 .project-docs/30-worklog/tasks/20260812-integrate-first-chat-fix-c31e.md diff --git a/.project-docs/20-architecture/data-flow.md b/.project-docs/20-architecture/data-flow.md index 6297cda..46004af 100644 --- a/.project-docs/20-architecture/data-flow.md +++ b/.project-docs/20-architecture/data-flow.md @@ -12,6 +12,8 @@ | 运营发布 | Works Square 审核与交付 | 公共 `play_url` | 客户端只消费服务端发布结果;真实合同校验 → OSS/CDN 生产链仍待整链验收 | | 可信发布门禁 | source+built+artifact contract | 服务端逐字节重算/合同校验 → 不可变 Release 固化 → 人工审核 | 服务端不运行项目 Vite;仍是不可绕过权威,未来 runtime 强门禁需可信 verifier | | 真机预览 | 项目空间 | Main → Owner preview / `play_url` | 核对 app、version、release 和同源 HTTPS;`runtime_url` 仅一版本兼容回退 | +| AI 编程首次发送 | ChatPanel 当前 Agent | Renderer Store → Host API → Main → OpenCode session / prompt | 新建 session 已知为空时直接提交 prompt,不在关键路径等待空历史;历史未知或普通历史会话仍按默认路径加载消息 | +| AI 编程模型代理错误 | OpenCode provider 请求 | Main Host AI proxy → Works 模型上游 | 配额耗尽保持独立终止态;只有明确的分组上游饱和才投影为 OpenCode 终止状态,通用限速仍保留 `429` | | 设计会话创建/切换 | AI 绘画页面或侧栏 | Renderer API → Main → Workspace Conversation API | 新会话属于现有 Workspace;读取独立消息、Brief、Quote 和 `turnRevision` | | 设计消息与确认 | 当前 Conversation | Main → 持久 Agent Gateway Session → Conversation 快照 | 请求和流式结果同时绑定 Workspace + Conversation | | 设计任务同步 | 任一 Conversation 的事件流 / REST | Renderer Workspace 任务列表 | Task 和 Asset 按 Workspace 归并,切换 Conversation 后仍可见 | @@ -26,11 +28,14 @@ - AI 绘画 Conversation 持有消息、Brief、Quote、`turnRevision` 和服务端 Session 绑定;Workspace 持有 Conversation 列表、生成任务和资产。 - 本地开发适配器将旧单会话 schema v2 原子迁移为带默认 Conversation 的 schema v3;打包应用不使用该本地适配器作为云端失败回退。 - 注销和退出会关闭本地事件流并清除本机 Conversation Session-id 缓存;服务端持久 Session 保留,下一次访问从 Conversation API 重新读取。 +- AI 编程 Store 的 `sessionMessagesBySessionId` own-key 是加载状态契约:键缺失表示历史未知,存在且值为 `[]` 表示已知为空。只有后者可使用不读取历史的快速选择;普通历史会话选择继续刷新消息。 +- Main Host AI proxy 可为固定 OpenCode 重试契约做窄化的内部状态投影:配额耗尽投影为 `402`,明确上游分组饱和的 `429` 投影为终止 `400`,其他 `429` 原样保留;升级 OpenCode 时必须重新验证该契约。 ## External Interfaces - Works Square 项目创建、版本上传、构建状态、Owner 状态与 Release preview API。 - 本机 Host API 的发布与真机预览路由;发布路由要求 Renderer capability。 +- 本机 Host API 的 OpenCode session、history 与 prompt 路由,以及 Main-owned AI 模型代理。 - 服务端安全投影后的公共 `play_url`;只接受同源 HTTPS、精确 App 路径和可信版本状态。 - Works Square Workspace/Conversation API、每个 Conversation 的 Agent Gateway Session 与单次 WebSocket ticket。 diff --git a/.project-docs/20-architecture/module-map.md b/.project-docs/20-architecture/module-map.md index 56c87ce..a25a738 100644 --- a/.project-docs/20-architecture/module-map.md +++ b/.project-docs/20-architecture/module-map.md @@ -16,6 +16,10 @@ | `electron/services/works-submission-binding.ts` | submission binding v2 持久化与旧 schema 迁移 | 旧中间态终止为 `legacy_retired`;文件名暂作安装兼容 | | `electron/api/works-play-url.ts` | 公共播放与 Owner preview URL 的共享安全校验 | 公共 `play_url` 必须同源 HTTPS 且精确匹配 App 路径 | | `electron/api/routes/device-preview.ts` | 精确提交版本的待审/已发布真机预览解析 | 待审使用短时 Release preview,已发布优先 `play_url` | +| `src/pages/Chat/OpencodeChatPanel.tsx` | AI 编程 Agent 选择、首次 session 创建与 prompt 提交流程 | 新 session 仅在消息缓存 own-key 已知时使用不读取历史的快速选择 | +| `src/stores/opencode.ts` | OpenCode runtime、session、消息缓存与提交状态 | `sessionMessagesBySessionId` 键缺失表示未知,存在空数组表示已知为空;普通选择默认刷新历史 | +| `electron/api/routes/ai-proxy.ts` | Main-owned 模型代理、凭据边界与上游响应投影 | 仅对明确上游分组饱和做终止态兼容投影,通用限速保持 `429` | +| `shared/opencode-error-details.ts` | OpenCode 上游饱和错误的窄化共享分类 | 不以通用 `rate_limit_exceeded` 单独判定饱和 | | `shared/image-workspace.ts` | AI 绘画 Workspace、Conversation、Task、Asset 与事件共享契约 | Conversation 状态与 Workspace 任务归属必须分离 | | `electron/api/routes/image-workspace.ts` | AI 绘画 Host API 与本地事件流投影 | Renderer 只通过该路由访问 Main-owned workspace adapter | | `electron/image-workspace/works-square-workspace.ts` | Works Square 多 Conversation 云端适配器与 Gateway 事件映射 | 使用服务端持久 Session;本地清理不 DELETE 远端 Session | @@ -27,6 +31,7 @@ ## Dependency Direction - Renderer UI → Renderer API contract → Main Host routes → Main services → Works Square;Renderer 不反向读取 Main 凭据、文件系统或归档。 +- AI 编程 Renderer → Host API → Main OpenCode routes/runtime;OpenCode provider 请求再经 Main AI proxy 访问模型上游,Renderer 不直接持有上游凭据或本地 runtime URL。 - Project configuration 决定产品分流;Main release builder 生成 source/built/contract,服务端独立重算和校验决定发布安全,本地 `ProjectType` 不是授权结论。 - Built artifact preflight 检查最终上传的同字节快照,但客户端可被绕过且不产生可信 receipt;服务端仍是合同、摘要和不可变 Release 安全权威。 @@ -37,6 +42,7 @@ - `electron/agent-browser/module.ts` 的预检必须继续拒绝外域访问、隔离临时 partition 并清理所有 view/listener;不能因本地通过而跳过服务端逐字节校验。生产 opaque-origin 行为不由该 loopback 检查覆盖。 - `works-cloud-deploy.json` 是兼容文件名;不得因名称重新引入自动部署协调语义。 - `runtime_url` 是一个客户端版本的迁移回退;删除前必须确认服务端和存量数据稳定提供 `play_url`。 +- `ai-proxy.ts` 的上游饱和状态投影依赖当前固定 OpenCode 的重试语义和窄化错误文案;升级 runtime 或调整上游错误格式时必须复核,不能把所有 `429` 统一终止。 - 多 Conversation 事件处理必须区分对话快照与 Workspace 任务更新;不得用任务时间戳推进 Conversation 流水位,也不得让旧会话的迟到流覆盖当前会话。 - `closeEventSessions` 只负责本地流和缓存生命周期;远端 Conversation Session 是服务端持久资源。 diff --git a/.project-docs/30-worklog/current-state.md b/.project-docs/30-worklog/current-state.md index 70711fe..7fbd233 100644 --- a/.project-docs/30-worklog/current-state.md +++ b/.project-docs/30-worklog/current-state.md @@ -12,6 +12,7 @@ This file is the integrated default-branch snapshot. Feature tasks record progre - `4980894` / `03dae62`:AI 绘画 Enter 发送及同一 Workspace 下的多 Conversation 客户端模型。 - `926056a`:Makelore 内置 Electron WebContents/CDP 发布前本地预览检查。 - `5b44864`:Main-owned 本地 npm/Vite 构建、同字节 Electron 双视口预检、source+built 双归档与 artifact contract 上传。 +- `08da976` / `0ee5254`:AI 编程首次发送已知空 session 快速路径与明确上游饱和终止态投影。 ## Current Focus @@ -19,6 +20,8 @@ This file is the integrated default-branch snapshot. Feature tasks record progre AI 绘画的一个 Workspace 可包含多条 Conversation。消息、Brief、Quote 和 `turnRevision` 随 Conversation 隔离;生成任务和资产保持 Workspace 级共享。每条 Conversation 使用服务端持久 Agent Gateway Session,切换会话只重连对应事件流。 +AI 编程首次发送在新建 OpenCode session 已知为空时不再等待冗余历史读取,prompt 可直接进入 Host API;普通历史会话仍刷新消息。Main AI proxy 只把明确的上游分组饱和投影为当前 OpenCode 的终止状态,配额耗尽保持独立终止态,通用限速继续保留 `429`。 + ## Recently Completed - 2026-08-08:合并登录续期、一键发布和真机预览;发布成功后保存精确 app/version/review 映射,Renderer 不接触 Token、ZIP 或本地路径。 @@ -28,6 +31,7 @@ AI 绘画的一个 Workspace 可包含多条 Conversation。消息、Brief、Quo - 2026-08-11:AI 绘画支持在同一设计项目内创建和切换多条独立 Conversation;保留项目级任务/资产,并使用 Workspace + Conversation 身份保护异步与流式更新。退出时关闭本地流并清除本地 Session-id 缓存,不删除服务端持久 Conversation Session。 - 2026-08-12:一键提交前复用当前项目的内置浏览器 loopback preview,以 fresh 临时 Electron WebContents/CDP 执行桌面/移动 UX 预检;服务端仍执行唯一受控构建、不可变 Release 安全门禁和人工审核。 - 2026-08-12:发布架构反转为 Main-owned 本地构建;固定 npm 11.6.2 按项目 lockfile 安装并执行项目 Vite,Electron 预检最终上传同字节产物,再上传 source+built 双归档和严格 contract。服务端仅校验并固化不可信字节,不再承担项目 Vite 构建。 +- 2026-08-12:AI 编程新 session 的首条 prompt 不再被已知空历史读取阻塞;明确上游分组饱和会快速终止,通用 `429` 仍保持原有限速语义。 ## In Progress @@ -57,6 +61,7 @@ AI 绘画的一个 Workspace 可包含多条 Conversation。消息、Brief、Quo - AI 绘画消息、Brief、Quote 和 `turnRevision` 必须按 Workspace + Conversation 隔离;任务事件仍按 Workspace 归并,迟到的异步结果不得污染已切换的会话。 - 服务端持久 Conversation Session 不由客户端在注销或退出时删除;Main 只关闭本地流、清除本机缓存并撤销本地凭据。 - 客户端对最终构建字节的 loopback 检查没有可信 receipt,且不复刻生产 opaque-origin;服务端必须独立重算 source/built/contract、校验不可变 Release,人工审核仍不可绕过。如未来需要不可绕过的 runtime gate,必须引入可信 verifier 并绑定精确构建产物。 +- AI proxy 的明确饱和 `429 → 400` 是与当前 OpenCode 重试契约匹配的内部投影;升级 OpenCode 或上游饱和错误文案变化时必须复核。不得把通用 `429` 或仅含 `rate_limit_exceeded` 的响应误分类为终止饱和。 ## Last Updated diff --git a/.project-docs/30-worklog/tasks/20260812-integrate-first-chat-fix-c31e.md b/.project-docs/30-worklog/tasks/20260812-integrate-first-chat-fix-c31e.md new file mode 100644 index 0000000..ac56708 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260812-integrate-first-chat-fix-c31e.md @@ -0,0 +1,80 @@ +# Task: Integrate first conversation latency fix + +## Identity + +- Task ID: 20260812-integrate-first-chat-fix-c31e +- Mode: Integration +- Branch: codex/20260812-integrate-first-chat-fix-c31e-integrate-first-chat-fix +- Worktree: D:\Datas\OthersProjects\makelore-integrate-first-chat-fix-c31e +- Base commit: a7340a20a1183550be3f70067611b6fa0ef5bef8 +- Owner: codex +- Status: Completed + +## Scope + +- Merge source commit `08da976` into the latest clean `main` baseline `a7340a2` through this isolated integration branch. +- Preserve the first-send known-empty session fast path, the narrow upstream-saturation terminal projection, and their focused unit/Electron E2E coverage. +- Promote the durable session-cache and Host AI proxy contracts into canonical project memory, then advance `main` only after verification and independent review. + +## Intent And Constraints + +- Treat source task `20260812-first-chat-fix-b84fd29c` as read-only evidence; do not rewrite its record during integration. +- Preserve the existing Renderer -> Host API -> Electron Main -> OpenCode ownership boundary and generic `429` behavior. +- Do not claim that every source of cold-start latency is eliminated: this integration removes the redundant known-empty history wait and stops indefinite retries only for explicitly classified upstream saturation. +- Preserve `main` commit `a7340a2` and all unrelated in-flight task work; no remote push is authorized by this task. +- Revalidate the status projection whenever the bundled OpenCode retry contract changes. + +## Project Context Loaded + +- `.project-docs/05-agent-entry/memory-index.md` +- `.project-docs/30-worklog/current-state.md` +- `.project-docs/00-brief/project-positioning.md` +- `.project-docs/10-decisions/decision-index.md` +- `.project-docs/20-architecture/system-overview.md` +- `.project-docs/20-architecture/module-map.md` +- `.project-docs/20-architecture/data-flow.md` +- `.project-docs/40-domain/business-rules.md` +- `.project-docs/00-brief/success-criteria.md` +- `.project-docs/50-evidence/evidence-index.md` +- `.project-docs/60-reflection/reflection-index.md` +- `.project-docs/80-commitments/commitments.md` +- `.project-docs/90-maintenance/stale-items.md` +- `.project-docs/05-agent-entry/integration-gate.md` +- Source task record `20260812-first-chat-fix-b84fd29c` +- Active peer task Scope / Intent And Constraints / Promotion Candidates sections required by the planning gate. + +## Plan + +1. Merge `08da976` without rewriting source history and inspect the combined diff against `a7340a2`. +2. Record the durable OpenCode session-cache and Host AI proxy contracts in canonical memory. +3. Run focused unit tests, typecheck, scoped lint, Vite build, Electron E2E, full-suite baseline comparison, and documentation checks. +4. Obtain an independent read-only PASS/FAIL review, complete integration documentation, and fast-forward `main` through a clean promotion task. + +## Outcome + +- Merged source commit `08da976` into the latest `main` baseline with integration merge `0ee5254`, preserving both parents while keeping the source task record read-only on its source branch. +- Integrated the known-empty session fast path: first prompt submission no longer waits for a redundant empty-history request, while unknown and ordinary historical sessions retain defensive loading/refresh behavior. +- Integrated the narrow Host AI proxy saturation projection: quota exhaustion remains `402`, explicit upstream-group saturation becomes terminal `400` for bundled OpenCode 1.18.9, and generic rate limits remain `429`. +- Promoted the session-cache own-key contract, proxy retry boundary, verification evidence, and OpenCode-upgrade revalidation commitment into canonical project memory. + +## Verification + +- Focused unit tests: 4 files / 228 tests passed. +- `pnpm run typecheck`: passed. +- ESLint over all changed product, unit, and Electron E2E files: passed. +- `pnpm run build:vite`: passed for Renderer, Electron Main, and Preload. +- `pnpm exec playwright test tests/e2e/opencode-first-chat.spec.ts`: passed, 1/1 in 4.7 seconds on the stable build output. An earlier attempt ran concurrently with `build:vite` and timed out during Electron launch before test logic; the serial rerun passed. +- `pnpm test`: 1548/1551 tests passed. The same three failures were independently reproduced on pre-integration `main`: two timing/generation cases in `opencode-manager.test.ts` and the missing repository `.opencode/agent` fixture in `youth-plain-language-skill.test.ts`. +- `check_project_docs.py`: passed. +- `check_doc_drift.py --task-id 20260812-integrate-first-chat-fix-c31e`: passed after the integration merge was amended so the source task record remains only in source history. +- `git diff --check`: passed with only the repository's normal LF/CRLF checkout warnings. +- Independent final read-only Sol review: PASS with no blocking findings; it independently reran all 228 related unit tests and confirmed merge ancestry, source-tree equality, cache/error semantics, and canonical documentation accuracy. + +## Follow-ups + +- Revalidate or remove the internal saturation status projection when bundled OpenCode or the upstream error contract changes. +- Treat duplicate cold bootstrap work and coarse global loading state as separate optimization candidates; this integration does not claim that all runtime cold-start latency is eliminated. + +## Promotion Candidates + +- None recorded. diff --git a/.project-docs/50-evidence/evidence-index.md b/.project-docs/50-evidence/evidence-index.md index a900ed2..f7c26ab 100644 --- a/.project-docs/50-evidence/evidence-index.md +++ b/.project-docs/50-evidence/evidence-index.md @@ -8,6 +8,7 @@ Use this index for searchable, traceable evidence records. | 2026-08-10 | 客户端静态发布唯一链路 | 本地验证通过 | `30-worklog/tasks/20260810-static-release-only-a91c.md`、`4df0477`、`8dd99c1` | 227 项聚焦回归、typecheck、Vite/Electron build、实际 Electron E2E 与 13 files / 21 tests 收集通过;不等同于真实生产部署验收 | | 2026-08-12 | Makelore 内置浏览器发布前预检 | 本地功能验证通过;不构成可信发布证明 | `30-worklog/tasks/20260812-client-browser-preflight-c8e2.md`、`926056a` | 121 项聚焦回归、typecheck、scoped lint、三端 build 与真实 Electron 双视口 E2E 通过;loopback UX 预检无 receipt/provenance/opaque-origin parity,服务端门禁仍需生产整链验收 | | 2026-08-12 | Makelore Main-owned 本地静态 Release 构建 | 本地功能与 Windows 安装产物验证通过;安装器未发布 | `30-worklog/tasks/20260812-client-built-release-makelore-7e5b.md`、`5b44864` | 6 files / 129 focused tests、typecheck、scoped lint、Vite build、真实 Electron 双视口 E2E 与实际 npm/Vite smoke 通过;安装器 223,547,912 bytes,SHA-256 `08A0BB7BC66EE4AD8B120E8955B149951CD86AF53CC966C7973AD4D77A5815C1`,内置 npm 11.6.2 已由 packaged verifier 验证,但未上传或发布 | +| 2026-08-12 | AI 编程首次会话等待与上游饱和重试 | 本地功能验证通过;真实冷启动各阶段耗时尚未遥测 | 源任务 `20260812-first-chat-fix-b84fd29c`、`08da976`、`0ee5254` | 4 个相关单测文件 228/228、typecheck、scoped lint、Vite build 与真实 Electron E2E 通过;全量单测的 3 个失败与 `main` 基线一致,修复证明 prompt 不等待已知空历史,但不宣称消除所有 runtime 冷启动耗时 | ## When To Add Evidence diff --git a/.project-docs/80-commitments/commitments.md b/.project-docs/80-commitments/commitments.md index 5cedc0a..07be42b 100644 --- a/.project-docs/80-commitments/commitments.md +++ b/.project-docs/80-commitments/commitments.md @@ -8,6 +8,7 @@ Track future-facing memory: promised follow-ups, unfinished loops, timed checks, | 2026-08-12 | Windows 发布流水线保留固定 npm 运行时产物门禁 | 每次生成正式 Windows 安装器时 | 客户端发布 | Pending | 运行 `pnpm verify:publish-runtime` 和 `pnpm verify:artifact:win`;当前 223,547,912-byte / SHA-256 `08A0BB7BC66EE4AD8B120E8955B149951CD86AF53CC966C7973AD4D77A5815C1` 安装器仅为本地证据,尚未发布 | | 2026-08-10 | 删除客户端 `runtime_url` 兼容回退 | 一个客户端兼容版本结束,且服务端与存量数据稳定提供 `play_url` | 客户端 | Pending | 删除类型字段、读取分支和对应回归测试 | | 2026-08-11 | 部署并验收 AI 绘画多 Conversation 服务端契约 | 发布包含多会话客户端之前 | 客户端/服务端集成 | Pending | 确认迁移 `0033`、Conversation list/create/read/turn/confirm API、持久 Agent Session 与事件字段已上线 | +| 2026-08-12 | 复核 AI 编程上游饱和终止态投影 | 升级 bundled OpenCode 或上游饱和错误格式时 | 客户端/OpenCode 集成 | Pending | 重新验证 retry contract;继续区分配额耗尽、明确分组饱和与通用 `429`,必要时调整或移除 `429 → 400` 内部投影 | ## Use