merge: fix opencode model switching runtime refresh
Some checks failed
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled

This commit is contained in:
2026-08-21 01:48:01 +08:00
15 changed files with 258 additions and 96 deletions

View File

@@ -4,6 +4,15 @@ This file is the integrated default-branch snapshot. Feature tasks record progre
## Integrated Through
- OpenCode model-switch runtime correction source commit `cce7722` from feature
task `20260821-model-switch-runtime-fix-a83d6c91` is integrated on local
`main` by task `20260821-integrate-model-switch-fix-8f2d6c41`. The Main-owned
client now maps Makelore's internal `modelID` to OpenCode 1.18.9's wire field
`id`. An owned fresh runtime receives the current per-process Host API token
when its local-proxy provider config is built, so persisting that already
active token no longer creates a false manual-restart requirement;
attached/unknown generations and timeout/partial persistence remain
fail-closed. A rebuilt-client real local smoke is still pending.
- Login-layout source commit `4d512b1` from feature task
`20260821-remember-below-login-4a7c91d2` was merged into local `main` as
`22f4bbc` by integration task `20260820-integrate-remember-password-5d7e3a1c`.
@@ -122,7 +131,7 @@ Makelore 在会话恢复、登录和刷新后由 Electron Main 请求 Works `/ap
AI 学习现在是已启用的运营精选项目目录,并继续受登录和 `module_access.learning` 控制。Renderer 通过 Main-owned Host API 获取分页项目卡片和 README 详情;Markdown 支持 GFM、禁用原始 HTML。服务端发布时只校验图片 URL 为无凭据、默认端口、无 fragment 且当前 DNS 结果全部为公网地址的 HTTPS URL,保留地址而不下载、识别格式、转码或镜像;客户端仅为 README 图片节点启用直连,因此 SVG 和 Electron 支持的其他格式可直接显示,单图失败不阻断详情。封面和历史发布媒体继续走受控路径。详情页的下载按钮打开系统保存对话框;Main 将 ZIP 流式写入临时文件,只允许最多五跳同 Works origin 重定向,不校验 `Content-Length`、`archiveBytes`、实际流字节数或客户端大小上限,校验 SHA-256 和 ZIP 签名后原子保存,Renderer 只接收 `saved` 或 `cancelled`。课程生成、进度、本地课程库、OpenMAIC player、Agent、ASR、课堂 runtime、Learning IPC 和 player artifact 打包已删除且没有兼容读取路径;历史课程数据保留但不再读取。服务端和客户端源码契约已完成,不代表生产部署或真实账号安装包联调已经完成。
AI 编程首次发送在新建 OpenCode session 已知为空时不再等待冗余历史读取,prompt 可直接进入 Host API;普通历史会话仍刷新消息。伙伴模型只作为新 Session 默认值,现有 Session 的 active model 由 OpenCode 持有;页面选择器和 `/models` / `/model` 走同一个 native Session 切换动作,后续 prompt、项目命令和上下文压缩不再用伙伴默认值覆盖选择。每个 Session 独立持有 model、run、loading、error 与内部队列;一个 Session 的回复或终止不会锁住、改写或重放另一个 Session。Host 接受或用户消息落库不算启动确认,只有明确 busy/retry、assistant、question、permission 或 typed terminal event 才确认/终结启动;独立的 10 秒 watchdog 到期时仅以 `SESSION_START_UNCONFIRMED` 终止该 Session。Main 按 Agent id 维护 desired/applied 内容状态与 runtime generation provenance;owned fresh generation 中首次出现的唯一 id 可在 live registry 暴露后启用且不阻断已有 Agent,同 id 编辑、删除后重建及 attached/unknown generation 仍保持 pending。provider/runtime 或 Agent 未应用时在执行前返回 typed `409` 且 `promptSent:false`。普通 message、command、summarize 和后台 provider sync 不自动重启、reload 或 dispose 共享 runtime;只有显式用户 apply/lifecycle 操作可以推进运行时刷新。Main AI proxy 只把明确的上游分组饱和投影为当前 OpenCode 的终止状态,配额耗尽保持独立终止态,通用限速继续保留 `429`。上下文压缩以每个 Session 的持久时间线事件呈现:自动与手动压缩使用不同文案,运行态原位弱化显示,完成后静态保留并可从历史恢复;`session.compacted` 只完成对应事件,只有真实 idle 才结束 run 和释放排队消息。
AI 编程首次发送在新建 OpenCode session 已知为空时不再等待冗余历史读取,prompt 可直接进入 Host API;普通历史会话仍刷新消息。伙伴模型只作为新 Session 默认值,现有 Session 的 active model 由 OpenCode 持有;页面选择器和 `/models` / `/model` 走同一个 native Session 切换动作,Main 在 OpenCode client 边界把内部 `modelID` 映射为 1.18.9 `ModelRef.id`,后续 prompt、项目命令和上下文压缩不再用伙伴默认值覆盖选择。每个 Session 独立持有 model、run、loading、error 与内部队列;一个 Session 的回复或终止不会锁住、改写或重放另一个 Session。Host 接受或用户消息落库不算启动确认,只有明确 busy/retry、assistant、question、permission 或 typed terminal event 才确认/终结启动;独立的 10 秒 watchdog 到期时仅以 `SESSION_START_UNCONFIRMED` 终止该 Session。Main 按 Agent id 维护 desired/applied 内容状态与 runtime generation provenance;owned fresh generation 中首次出现的唯一 id 可在 live registry 暴露后启用且不阻断已有 Agent,同 id 编辑、删除后重建及 attached/unknown generation 仍保持 pending。fresh runtime 的本地 AI proxy provider 在构建时使用当前 Main Host API token;后续将该已生效 token 持久化不构成 provider/runtime 变更,attached/unknown generation 或不确定写入仍保持 pending。provider/runtime 或 Agent 未应用时在执行前返回 typed `409` 且 `promptSent:false`。普通 message、command、summarize 和后台 provider sync 不自动重启、reload 或 dispose 共享 runtime;只有显式用户 apply/lifecycle 操作可以推进运行时刷新。Main AI proxy 只把明确的上游分组饱和投影为当前 OpenCode 的终止状态,配额耗尽保持独立终止态,通用限速继续保留 `429`。上下文压缩以每个 Session 的持久时间线事件呈现:自动与手动压缩使用不同文案,运行态原位弱化显示,完成后静态保留并可从历史恢复;`session.compacted` 只完成对应事件,只有真实 idle 才结束 run 和释放排队消息。
Updater 仍由 Electron Main 选择目标 feed、记录原始诊断并保持失败语义。正式稳定源缺少对应平台 manifest 时,设置页只显示一条简洁中文提示并允许重试,不把缺包误报为已是最新版,也不向普通界面暴露堆栈、URL、路径或错误码;签名产物发布和真实升级安装仍属于外部 Release Gate。
@@ -197,10 +206,10 @@ Robot 绑定设备默认先显示“引导配网 / 已有激活码”路径选
- AI proxy 的明确饱和 `429 → 400` 是与当前 OpenCode 重试契约匹配的内部投影;升级 OpenCode 或上游饱和错误文案变化时必须复核。不得把通用 `429` 或仅含 `rate_limit_exceeded` 的响应误分类为终止饱和。
- AI 编程压缩事件必须按 Session、run token、runtime generation 与 native Part/event identity 关联;`session.compacted` 不等于 `session.idle`,历史 hydration 不得把 completed 降回 running,失败或中止必须清理本 run 的未完成事件。
- AI 编程多 Session 隔离只证明应用提交、状态、错误、超时和队列互不污染,不证明 bundled OpenCode 或真实 provider 会并行执行两个模型 turn。任何产品或性能结论都必须保留上游可能串行、限流或拒绝的边界。
- 项目 Agent 与 provider/runtime freshness 必须在 Main 的 bounded acceptance 临界区内验证。新增唯一 id 的 live discovery 只在 owned fresh generation 可接受;同 id 不能证明同内容已经加载,删除后重建及 attached/unknown runtime generation 必须 fail closed。普通 message、command、summarize、Session 模型切换和后台同步不得自动重启、reload 或 dispose 共享 runtime。
- 项目 Agent 与 provider/runtime freshness 必须在 Main 的 bounded acceptance 临界区内验证。新增唯一 id 的 live discovery 只在 owned fresh generation 可接受;同 id 不能证明同内容已经加载,删除后重建及 attached/unknown runtime generation 必须 fail closed。普通 message、command、summarize、Session 模型切换和后台同步不得自动重启、reload 或 dispose 共享 runtime。升级 OpenCode 时必须复核 native Session model wire schema;不得把已注入 fresh generation 的 Main 临时 proxy token 误判为上游 provider credential rotation。
- AI 绘画单图选择器仍精确匹配 quick reply `从作品列表选择图片`,用途再从当前 Brief medium 推断;本地化或协议文案变化可能破坏入口。扩展更多素材输入前应升级为结构化 action/purpose。
- Updater 源码错误提示不能代替发布正式签名产物;稳定 feed 缺 manifest 必须保持失败,Renderer 不得展示原始堆栈、URL、路径或错误码。升级链只有在旧版本完成发现、下载、重启和安装 smoke 后才可视为生产就绪。
## Last Updated
2026-08-20
2026-08-21

View File

@@ -0,0 +1,99 @@
# Task: Integrate model switch runtime fix into main
## Identity
- Task ID: 20260821-integrate-model-switch-fix-8f2d6c41
- Mode: Integration
- Branch: main
- Worktree: D:\Datas\OthersProjects\makelore
- Base commit: 605fef417fe2e7a5d23d4994fbd109cdfb38efcb
- Owner: codex
- Status: Blocked
## Scope
- Merge verified source commit `cce7722` into local `main` with normal
no-fast-forward history.
- Integrate the OpenCode Session model wire correction and fresh-runtime local
proxy Host API token binding without changing partner Agent hot-add behavior.
- Reconcile the source task's accepted promotion candidate into canonical
current state, architecture/data flow, evidence, and the pending real-client
smoke commitment.
- Preserve the separately owned untracked packaging task record unchanged.
## Intent And Constraints
- Keep page selection and `/models` / `/model` on OpenCode's native per-Session
mutation and prevent false runtime-refresh requirements for an owned fresh
runtime that already uses the current Main-owned proxy token.
- Preserve attached/unknown fail-closed behavior, sticky timeout/partial-write
uncertainty, true provider/model shape refreshes, and existing Agent runtime
acceptance rules.
- Treat the source feature task record as read-only source history. Do not edit
it; keep integration notes in this task record and canonical documents.
- Do not modify or commit
`.project-docs/30-worklog/tasks/20260819-package-learning-off-115-9c4d.md`.
- Merge only into local `main`; do not push, package, or claim a rebuilt-client
smoke that has not been run.
## Outcome
- With explicit user authorization, force-released the blocked legacy
integration ownership `20260820-integrate-remember-password-5d7e3a1c` and
adopted the known dirty `main` worktree without modifying its separately
owned untracked packaging task record.
- Merged source commit `cce7722` into the local `main` integration tree with
normal no-fast-forward history and no code conflicts. The source task record
remains read-only source history and was not added to the canonical tree.
- Integrated the OpenCode 1.18.9 Session model `id` wire mapping, current Host
API token injection for a fresh managed local-proxy runtime, and the
fresh/attached runtime acceptance distinction. Partner Agent hot-add and true
provider/runtime refresh semantics are unchanged.
- Promoted the accepted source candidate into current state, module ownership,
data flow, evidence, and a pending rebuilt-client local smoke commitment.
- Kept the merge local. No push, package, paid-provider request, or claim of a
real rebuilt-client smoke was made.
## Verification
- Integrated focused OpenCode client/provider config/provider route/OpenCode
route suite — 4 files, 171 tests passed.
- `corepack pnpm run typecheck` — passed.
- `corepack pnpm run lint:check` — passed with 0 errors and 6 existing warnings
in unrelated Renderer files.
- The first parallel full-test/build attempt exhausted worker/V8 process
resources: Vitest reported one unexpected worker exit after 176 files / 2047
tests passed, and the concurrent Vite process terminated with a V8 fatal
check. Rerunning the commands independently resolved the execution failure.
- Sequential `corepack pnpm test` — 177 files, 2074 tests passed.
- Sequential `corepack pnpm run build:vite` — passed for
Renderer/Main/Preload/utility; only existing dynamic-import and large-chunk
advisory warnings were reported.
- `node ./node_modules/@playwright/test/cli.js test
tests/e2e/opencode-multichat-runtime.spec.ts` — 1 Electron E2E passed. An
earlier `pnpm exec playwright` attempt selected the separate `playwright` CLI
and failed during collection because the fixture used `@playwright/test`; no
test body ran in that attempt.
- `git diff --check` — passed with configured LF-to-CRLF notices only.
- Task-aware documentation drift remains blocked solely because the explicitly
adopted, pre-existing untracked
`.project-docs/30-worklog/tasks/20260819-package-learning-off-115-9c4d.md`
is another task's owned record. It was not modified, staged, or committed.
The checker also lists the expected nine merged source code/test files as
non-document changes.
## Follow-ups
- Build and relaunch a desktop application containing source `cce7722`, then
repeat page-selector and `/model` switching against the real local OpenCode
runtime without a manual runtime restart. This is recorded in canonical
commitments and remains outside this source-only integration.
- Resolve the project-docs drift-check handling for the explicitly adopted
pre-existing foreign task record before marking this integration complete or
releasing its ownership. Do not delete, edit, move, or commit that record as
part of this integration.
## Promotion Candidates
- Applied the source task's Session model wire and fresh-runtime local-proxy
token candidate; none remain pending for this integration.