Compare commits

..
7 Commits
Author SHA1 Message Date
brother7 d7f936db94 docs(集成): 记录微信运行状态与执行默认值修复
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
2026-09-14 15:54:52 +08:00
brother7 4f2caf7dbd fix(云智能体): 修复微信失败运行状态投影并提高默认执行步数 2026-09-14 15:39:35 +08:00
brother7 9044f7dd8c docs: record Agents entry merge into main 2026-09-14 14:20:23 +08:00
brother7 9317d0acc7 ui: show Agents first in module chooser 2026-09-14 14:11:39 +08:00
brother7 4e33d6ade6 ui: update Agents entry slogan 2026-09-14 14:08:49 +08:00
brother7 10df9fd740 ui: match Agents entry artwork to module cards 2026-09-14 14:05:52 +08:00
brother7 da6684b03e docs(wechat): 记录合并工作区清理结果 2026-09-14 13:13:47 +08:00
18 changed files with 323 additions and 24 deletions

No files matched your search

@@ -4,6 +4,10 @@ This file is the integrated default-branch snapshot. Feature tasks record progre
## Integrated Through
- 2026-09-14:任务 `20260914-merge-ppt-makelore-2e8ec5dc` 经用户授权移交主目录登记,将已独立审查的 `4f2caf7` 从 `9044f7d` 无冲突快进合入本地 `main`。新建云智能体默认 300 步,保留显式 40/自定义设置;微信会话优先展示原生 Run 状态及失败原因,再显示部分正文,涵盖关闭历史会话与仅排队状态。产品树与已验证源一致,沿用 42 项回归、类型检查、lint、Vite 构建及 Electron 验收,详见[源任务](tasks/20260914-makelore-ppt-failure-7c4a.md)。原有三份未跟踪文档保留;未推送、打包、安装或部署。需配套更新 Yuxi API/worker,已有智能体调整限制后重新发布。
- 2026-09-14:任务 `20260914-merge-agents-entry-aecd607d` 经用户确认主目录登记移交,将源 `9317d0acc7cfa6eab2379ab37acefbac8e435fad` 无冲突快进合入本地 `main`。Agents 入口换为蓝紫色全息智能体插画,标语为“打造你想象中的AI助手”,顺序为 Agents、Code、Canvas、Robot;源记录原样导入,产品树与已验证源一致,沿用其类型检查、相关单测、构建和 Electron 双窗口验证。原有 3 份未跟踪文档保持原样;未推送、打包、安装或部署。详见[源任务](tasks/20260914-agents-entry-art-0242f8f3.md)。
- 2026-09-14:任务 `20260914-land-scan-account-ml-8fb88137` 经用户确认登记移交,将已独立审查源 `21e707d` 无冲突快进合入本地 `main`。微信渠道统一按扫码账号使用,删除使用范围、邀请与调用者管理;历史受邀内容不改归属、不继续入站/恢复/投递。源记录原样导入,产品树与已验证源保持一致,证据及限制见[源任务](tasks/20260914-wechat-scan-owner-ml-b4169ea9.md)。本次无新 SQL/环境变量;未推送、部署或清理工作区。
- 2026-09-14:任务 `20260914-merge-user-channels-ml-e672b0c4` 经用户授权移交主目录,将已审查源 `b7d8b1298f02e4b10b6d0089594d48720efc03e7` 无冲突快进合入本地 `main`。用户级多微信账号、先扫码后选择目标、多个账号路由同一智能体及切换保留登录已集成;智能体发布页使用渠道摘要/入口。产品树与已审查源一致,源记录只读导入,验证和实际部署边界见[源任务](tasks/20260913-user-channels-ml-8d61e4a9.md)。原有 3 份未跟踪文档保留;未推送、部署或清理工作区。
@@ -0,0 +1,75 @@
# Task: Replace Agents entry artwork
## Identity
- Task ID: 20260914-agents-entry-art-0242f8f3
- Mode: Feature
- Branch: codex/20260914-agents-entry-art-0242f8f3-agents-entry-art
- Worktree: D:\Datas\OthersProjects\.codex-worktrees\makelore\20260914-agents-entry-art-0242f8f3
- Base commit: da6684b03e8ef7be17cb35b8b42130f11b3bc797
- Owner: codex
- Status: Ready for Integration
## Scope
- Replace the Agents module chooser placeholder with a generated cinematic illustration in `src/assets/module-agents.webp`.
- Follow-up: replace the Agents description in `src/lib/ai-modules.ts` with the user's corrected exact slogan `打造你想象中的AI助手`.
- Ordering follow-up: place Agents first in the module catalog; remaining visual/DOM order is Code, Canvas, Robot. Preserve ID-based navigation and the new artwork/slogan.
- Reuse the existing module image container, center crop, accessibility text, disabled grayscale and navigation. Require artwork for all four module entries and remove the now-unused placeholder branch.
- Update existing module navigation unit/Electron coverage and this task record only.
## Intent And Constraints
- Same-task ordering follow-up: official check/start/status passed in this clean worktree; reused already loaded project/peer context and confirmed module catalog consumers. Planning Gate Passed. Only chooser ordering changes; `getAiModuleForPath` still returns the same IDs and default Code route. Extend the existing UI order assertions and rerun the existing Electron layout test to verify the now-first Agents card at both window sizes.
- Same-task slogan follow-up: official check/start/status passed and reused this clean feature worktree and the already loaded project/peer context. Planning Gate Passed. User corrected `想像` to `想象`; use the corrected text verbatim, without extra spaces or quotation marks in the UI. This is a copy-only change; existing tests are sufficient and no new interaction test is needed.
- Concurrent Task Gate and Planning Gate passed. Official start exited 0 and status matched the task ID, feature mode, branch, absolute worktree and base above. All subsequent operations use this isolated worktree; primary `main` has other ownership and three pre-existing untracked task records.
- Loaded the planning entry, own task, memory index, integrated current state, positioning, decision index, architecture, relevant domain/success criteria, accepted personal-cloud-Agent ADR, README and peer scope/intent/promotion sections. Registry holds 28 other planning tasks and 162 ready tasks; historical placeholder scopes remain unknown coordination state. The recent WeChat diagnosis is read-only, and prior Agents entry/platform work is integrated. No concrete semantic dependency on this artwork was identified.
- Older three-module prose and positioning placeholders are stale; README, accepted cloud Agent decision and current source confirm four entries. No architecture, backend, route, configuration or product-direction change is required.
- User requested matching the three existing image entry styles. Built-in imagegen produced a full-bleed dark blue/violet holographic digital companion. Preserve the source PNG outside the repository and ship only the 960x540 WebP, matching the other entry asset dimensions. No subagents were used.
- Plan: generate and inspect artwork; wire the existing image rendering; verify image decoding/layout, module navigation, type checking and production asset bundling; finish task documentation.
## Outcome
- Ordering follow-up completed: final chooser order is Agents, Code, Canvas, Robot in both DOM and visual layout. Real Electron screenshot confirms the first card uses the generated Agent image and `打造你想象中的AI助手`. Module routes remain ID-based and unchanged.
- Slogan follow-up completed: the Agents entry description and its accessible button label now use `打造你想象中的AI助手`, matching the user's spelling correction. Existing generated artwork is retained.
- Generated and connected the blue/violet holographic Agent artwork. All four entries use the same bundled-image rendering; obsolete violet placeholder markup is removed. Existing card spacing, image crop, labels, policy state and routes are preserved.
- Visually inspected the real 1280x800 Electron chooser screenshot: the central figure remains recognizable inside the same 164x132 image region as its neighbors. The existing E2E also verifies the layout after resizing to 1100x700.
- Result is in this isolated feature branch. The occupied primary main checkout and installed application were not updated. No push, package, deployment or subagents.
## Verification
- Ordering follow-up: 12/12 module navigation/access unit tests, typecheck, scoped ESLint and all Vite production targets passed. Existing Electron layout test passed 1/1 with explicit four-entry order, first-card slogan, image decode and 1280x800/1100x700 checks. Inspected its refreshed screenshot and full cumulative changes since base; whitespace and task documentation boundary checks passed.
- Slogan follow-up: typecheck and all Vite production targets passed; existing module navigation/access tests passed 12/12. Reviewed the single source-string diff; no interaction or layout rule changed.
- Frozen install succeeded using the exact pinned pnpm 10.33.4. Generated WebP is 960x540, 90,688 bytes.
- `pnpm run typecheck`: passed.
- `pnpm exec vitest run tests/unit/module-navigation.test.tsx tests/unit/module-access.test.ts tests/unit/cloud-agents-page.test.tsx --maxWorkers=2`: 25 tests across 3 files passed; covers artwork rendering, module access, navigation and Agents entry behavior.
- Scoped ESLint on the changed page and unit/E2E files: passed.
- `pnpm run build:vite`: passed for Renderer/Main/Preload/utility; production bundle contains the local WebP. Existing Browserslist and chunk warnings remain.
- `pnpm exec playwright test tests/e2e/main-navigation.spec.ts --grep 'keeps the four module entries' --workers=1`: 1 passed. All four images decoded; proportional layout and hover/focus remain stable across window resizing.
- Visual evidence is the ignored test output `test-results/main-navigation-Makelore-m-77439-k-while-resizing-the-window/module-entry-artwork.png`; no reports/build/cache files belong to the source handoff.
- Task Documentation Gate: inspected the complete source diff and new asset since the recorded base; `git diff --check` and task-aware documentation drift check passed. No canonical-memory promotion is required; README's existing unified horizontal-card description remains accurate.
## Follow-ups
- Integrate this feature branch when the primary worktree ownership is available. An installed client needs a later build/install to display the new artwork.
## Promotion Candidates
- None. This is a presentation-only replacement within the existing module chooser design.
## Image Generation Prompt
- Tool: built-in `image_gen` (no fallback CLI).
- Final asset: `src/assets/module-agents.webp`.
- Original: `C:/Users/7brot/.codex/generated_images/01a09e7c-53f0-79d1-afe0-fb9435d77854/exec-6bd2ccdf-d601-44d4-a80f-6fb1444efbde.png`.
```text
Use case: stylized-concept.
Asset type: a finished landscape raster illustration for the Makelore Agents AI assistant module entry thumbnail, matching adjacent cinematic sci-fi game art and a photoreal dark robotics workshop. Generate only the image asset, no UI mockup.
Primary request: a visually striking intelligent digital companion, an elegant translucent holographic humanlike head and shoulders made of luminous violet and cyan light, facing three-quarter toward the viewer, focused and approachable, actively orchestrating a few floating abstract task panels and connected glowing knowledge nodes. It must read immediately as a software AI agent.
Scene/backdrop: deep navy futuristic digital workspace, restrained atmospheric depth, a few flowing luminous connections and softly blurred screens; full bleed richly rendered scene.
Style/medium: premium cinematic 3D concept art with realistic light, fine materials, detailed but strong readable silhouette, matching sophisticated sci-fi game key art; no flat vector symbol.
Composition/framing: landscape 16:9, 1536x864 output if possible. Main head and upper torso large, occupying the central 55% of the canvas; eyes/head entirely inside central 55% for a center crop to a 164x132 thumbnail. Key accents remain near the center. Leave breathing room around the silhouette, clear foreground/background separation.
Lighting/palette: saturated electric cyan and violet highlights, dark indigo and midnight blue environment, controlled bright rim light, subtle warm highlights, balanced exposure so the face reads at small size. The character is luminous rather than metallic hardware.
Constraints: no text, letters, numerals, brand, logo, watermark, border, rounded corners, white margins, sparkles icon, cartoon mascot, weapons or threatening expression. A single coherent illustration, no panels or collage.
```
@@ -16,6 +16,7 @@
## Intent And Constraints
- 清理续接:用户确认仅清理已列明的 MakeLore b4169ea9 与 Yuxi 3798efa6 源工作区。MakeLore 本集成任务已由官方 start/status 恢复;沿用已加载规划上下文,重新确认两源仍 ready、managed、干净且最新分支在各自主线 ancestry 中,Planning Gate Passed。Yuxi 主目录现由 7f2c9b41 拥有,其源码与任务记录不修改;只以该仓库上下文运行官方 retire 删除获准源登记与目录,结果统一记录于本任务。没有额外创建工作区。
- 用户授权合并及旧登记移交,官方 release/start/status 成功。旧邀请规则按用户决定替代,创建者计费与历史内容隔离保持。不创建额外子智能体,不推送、部署或清理。
## Project Context Loaded
@@ -39,7 +40,9 @@
- 已将源 21e707d 无冲突快进合入本地 main;产品代码与已审查源完全一致,源任务及支持记录原样导入。
- 已同步扫码账号规则的 ADR、索引、架构与集成快照,补充渠道域规则。原有 3 份未跟踪文档未修改、未提交。
- 未推送、部署、操作生产数据或删除工作区;本次实现仅涉及 MakeLore 与 Yuxi,AgentBus/Works Square 无改动。
- 合并阶段未推送、部署、操作生产数据或删除工作区;本次实现仅涉及 MakeLore 与 Yuxi,AgentBus/Works Square 无改动。后续授权清理结果见下方。
- 2026-09-14 用户确认清理两个源工作区后,官方 retire 成功移除 Yuxi `20260914-wechat-scan-owner-yx-3798efa6`,保留分支与 `00810f244771da394c00ecb36205131c2e388e51`。
- MakeLore `20260914-wechat-scan-owner-ml-b4169ea9` 的官方 retire 被 Git “Directory not empty” 中断。目录仍有部分源码、node_modules 与测试产物,但 `.git` 和 Git worktree 登记已被 Git 移除;本地任务 owner/reservation 未因失败自动清除。未手工删除、重建登记或绕过 retire,残余保留。分支与 `21e707d9c43b2db3622d21358546f1734d70b2db` 完整。
## Verification
@@ -49,7 +52,7 @@
## Follow-ups
- 本次已合入且干净的源工作区保留,清理等待单独确认。部署后真实微信扫码/收发和文件交付仍需验收。本批无新 SQL/环境变量。
- Yuxi 源工作区已清理;MakeLore 残余 `D:\Datas\OthersProjects\.codex-worktrees\makelore\20260914-wechat-scan-owner-ml-b4169ea9` 因 Git 部分删除失败保留,需要后续有界恢复流程。此问题不影响两源已合入的主分支与保留提交。部署后真实微信扫码/收发和文件交付仍需验收。本批无新 SQL/环境变量。
## Promotion Candidates
@@ -0,0 +1,49 @@
# Task: Fix MakeLore failed run projection and agent default
## Identity
- Task ID: 20260914-makelore-ppt-failure-7c4a
- Mode: Feature
- Branch: codex/20260914-makelore-ppt-failure-7c4a-makelore-ppt-failure
- Worktree: D:\Datas\OthersProjects\.codex-worktrees\makelore\20260914-makelore-ppt-failure-7c4a
- Base commit: 9044f7dd8ce199ca57cbe0bc7be1abd1bca2a9bd
- Owner: codex-ppt-failure
- Status: Ready for Integration
## Scope
- Change the MakeLore cloud-agent client default `max_execution_steps` from 40 to 300 for newly materialized configuration defaults.
- Project the existing authoritative WeChat conversation run status and error visibly in the selected conversation, including historical/closed sessions and queued-only state.
- Add focused renderer/unit and consumer-seam Electron E2E regression coverage for failed runs and the required status labels.
- Keep the implementation inside MakeLore; do not change Yuxi, AgentBus, Works Square, backend contracts, billing, privacy, retry/resume controls, or published version data.
## Intent And Constraints
- Confirmed facts: `shared/cloud-agents.ts` defines the fallback configuration with `max_execution_steps: 40`; `electron/services/cloud-agent-operations.ts` already projects `CloudRun.status` and bounded `error.type/message`; `CloudChannelConversations` currently prioritizes the closed-session copy over run status and does not render `run.error`.
- Decision: use 300 only when the configuration field is absent. Preserve explicit saved 40/custom values and published versions because Main's configuration projection overlays present response fields.
- Decision: keep partial assistant messages, but render a prominent authoritative run-status/error block before them so partial output cannot conceal a terminal failure.
- Confirmed contract: the existing channel-conversation response includes `run.status`, `run.output`, `run.error.type/message`, and `queued_requests[].status`; Main's `projectConversation` preserves those bounded fields. Yuxi now maps the graph execution limit to `execution_step_limit` with a user-facing explanation, and its thread history already merges run/messages/queued requests. No MakeLore API change is required.
- No deployment, push, or merge is part of this task; hold the reversible commit until the independent review completes. No paid retry, automatic resume, or new framework is included.
## Outcome
- Completed implementation in the MakeLore client. New configuration defaults materialize at 300 execution steps while explicit saved values remain unchanged. The selected WeChat conversation now shows the authoritative run status for active, terminal, closed, and queued-only states, and shows the authoritative error before retaining any partial assistant transcript. The settings help explains that execution steps count model calls, tools, graph nodes, and middleware steps. No billing, privacy, scanner identity, published-version, retry, or resume behavior changed.
- Independent review completed with no product-executable issues and approval to commit. The reviewer confirmed the 300 default, preservation of explicit 40/custom limits and published versions, failed-run error with partial output, and queued-status precedence.
## Verification
- Before the fix, the component had no status/error regression assertion; closed sessions rendered only the historical-session copy and `run.error` was absent from the view. The 42 regression tests were run only against the fixed implementation; the old implementation was not executed to produce a red test. The baseline was verified from the pre-change source. The first focused test attempt was blocked by an uninstalled workspace (`vitest: command not found`), then `pnpm install --frozen-lockfile` restored the pinned dependencies.
- Passing: `pnpm exec vitest run tests/unit/cloud-channel-conversations.test.tsx tests/unit/cloud-agents-main.test.ts --maxWorkers=1` (42 tests); `pnpm run typecheck`; `pnpm exec eslint shared/cloud-agents.ts src/pages/CloudAgents/CloudChannelConversations.tsx src/pages/CloudAgents/ConfigurationFields.tsx tests/unit/cloud-agents-main.test.ts tests/unit/cloud-channel-conversations.test.tsx tests/e2e/cloud-agent-channels.spec.ts`; `pnpm run lint:check`; `pnpm run build:vite`; `pnpm run test:e2e -- tests/e2e/cloud-agent-channels.spec.ts` (1 test). `git diff --check` also passed. Build output contained only existing Browserslist, chunk-size, and dynamic-import warnings.
- Review limitation: the production WeChat E2E was not executed. The available Electron E2E and Main projection regression cover the client consumer seam; Yuxi's independent real-chain validation supplied the upstream contract confirmation.
## Follow-ups
- No implementation follow-up remains before integration. Keep the production WeChat E2E limitation visible when promoting this change.
## Promotion Candidates
- None. The default and status/error behavior are client changes covered by this task; no canonical project-memory or backend contract promotion is needed.
## Status
Ready for Integration
@@ -0,0 +1,44 @@
# Task: Merge Agents entry presentation into main
## Identity
- Task ID: 20260914-merge-agents-entry-aecd607d
- Mode: Integration
- Branch: main
- Worktree: D:\Datas\OthersProjects\makelore
- Base commit: da6684b03e8ef7be17cb35b8b42130f11b3bc797
- Owner: codex
- Status: Ready for Integration
## Scope
- Fast-forward local main to the verified Agents entry source `9317d0acc7cfa6eab2379ab37acefbac8e435fad`, including new artwork, exact slogan `打造你想象中的AI助手` and order Agents / Code / Canvas / Robot.
- Synchronize the integrated snapshot and concise README presentation description. Keep imported source records unchanged.
## Intent And Constraints
- User explicitly authorized merging to main, then confirmed transfer of the completed old main task `20260914-land-scan-account-ml-8fb88137` and preservation/adoption of the three existing untracked task records. Official release/start/status passed; this integration task holds the main worktree and integration lock.
- Concurrent and Planning Gates Passed. Read the planning entry, own record, memory index, positioning, integrated snapshot, decisions, system overview and planning gate, plus source outcome/verification/promotion and previous main ownership record; reused already loaded domain/ADR/README and peer scope/intent/promotion context. There are 28 other planning and 162 ready owners; historical placeholder peer scope remains unknown, with no concrete semantic dependency on this presentation-only merge.
- Base main equals the verified source base; source branch is clean and ready. Merge with `--ff-only`, then verify product equality to reuse its exact-source checks; any unexpected difference requires investigation. No backend/config/route change, source record rewrite, push, deployment, package or installation.
- Preserve `.project-docs/30-worklog/tasks/20260901-package-122-c5e8.md`, `20260901-package-123-d7f3.md` and `20260902-client-hang-diagnosis-a47c9e2b.md` in their adopted unchanged untracked states.
## Outcome
- Fast-forwarded local main from `da6684b03e8ef7be17cb35b8b42130f11b3bc797` to the exact source `9317d0acc7cfa6eab2379ab37acefbac8e435fad` without conflicts. All three source commits and the unchanged source task record are included.
- Final entry order is Agents, Code, Canvas, Robot. Agents uses the generated blue/violet artwork and `打造你想象中的AI助手`. Updated README and the integrated snapshot; no API, route or architecture change.
- The three explicitly adopted pre-existing records remain untracked and unchanged. No remote push, package, install or deployment.
- Source worktree cleanup is awaiting separate user confirmation; the merge is complete independently of that choice.
## Verification
- Main was an ancestor of the clean source. `git merge --ff-only` succeeded and the immediate `git diff --exit-code 9317d0acc7cfa6eab2379ab37acefbac8e435fad` was empty, proving exact tracked source equality before integration-only documentation edits.
- Reuse the exact source's final typecheck, scoped lint, 12/12 module navigation/access tests, Vite production build, Electron layout 1/1 and inspected screenshot. Earlier artwork coverage also passed 25/25 tests; unchanged product code does not require another full test run.
- Task Documentation Gate checks the cumulative diff, whitespace and official task-aware documentation boundary, including preservation of adopted foreign records.
## Follow-ups
- Cleanup candidate: source task `20260914-agents-entry-art-0242f8f3`, worktree `D:\Datas\OthersProjects\.codex-worktrees\makelore\20260914-agents-entry-art-0242f8f3`, branch `codex/20260914-agents-entry-art-0242f8f3-agents-entry-art`. It is managed, clean and ready, and the latest result is included in main. Await explicit approval before official retirement; retain the branch and commits. The primary checkout is not a cleanup candidate.
## Promotion Candidates
- None recorded.
@@ -0,0 +1,43 @@
# Task: 合并微信运行状态与执行默认值修复
## Identity
- Task ID: 20260914-merge-ppt-makelore-2e8ec5dc
- Mode: Integration
- Branch: main
- Worktree: D:\Datas\OthersProjects\makelore
- Base commit: 9044f7dd8ce199ca57cbe0bc7be1abd1bca2a9bd
- Owner: codex
- Status: Ready for Integration
## Scope
- 无冲突快进合入本批已独立审查的 PPT 执行与失败反馈修复;只补充集成状态及相关 canonical memory。
## Intent And Constraints
- Concurrent Task Gate 与 Planning Gate Passed。官方 start/status 已验证本任务、Integration 模式、主目录、主分支和基线;用户明确同意旧登记移交及合并。
- 已读入口、本人记录、memory-index、定位、当前状态、决策、架构、领域规则、证据/反思/承诺索引及源任务结果。逐项检查 peer task 的 Scope、Intent And Constraints、Promotion Candidates;历史占位作用域为未知,但不影响本次只消费已审查源的快进合并。渠道、扫码身份与工具直接执行已在基线,无语义冲突。
- 项目仍为个人创作者云智能体平台,Yuxi 原生执行、账号隔离及创建者付费。保留显式步数、版本快照、源任务原记录和已确认接管的无关未跟踪文档。只做本地合并;不推送、部署、重试生产任务或清理工作区。
- 复用最终已审查源的测试,以合入后的产品树与源完全一致为前提;若出现产品差异则停止并重新验证。生产微信链路仍待配套部署验收。
## Outcome
- 已从 9044f7d 无冲突快进至已审查源 4f2caf7,源产品与任务记录原样导入。记录新建 300 步与微信会话原生状态/失败原因展示的集成事实,保留关闭历史会话、仅排队状态及部分正文。
- 原有 3 份未跟踪文档逐项读取比较,内容完全不变;未推送、部署、修改生产记录或删除工作区。
## Verification
- 合入后 git diff --exit-code 4f2caf7 -- . ':(exclude).project-docs' 通过,确认所有产品、测试、公开文档与最终已审查源完全一致,因此复用源验证而不重复运行相同产品测试。
- MakeLore 源验证 42 项相关测试、typecheck、scoped ESLint、lint:check、build:vite 和 1 项真实 Electron E2E 通过;独立 Reviewer 最终允许提交。Electron 使用 Host fixture,不能替代真实微信验收。
- git diff --check 通过;现有无关文档内容与接管前保存文本完全相同。
- 官方 check_doc_drift.py 通过,新增 canonical 链接均可解析至实际文件。此次额外改动仅为 .project-docs 集成记录,公开文档与源构建输入完全一致,复用已通过的构建证据。
## Follow-ups
- 配套部署 Yuxi API/worker 与新版 MakeLore;已有智能体若仍为 40 步,需调整限制、保存并重新发布。旧失败运行不自动续跑,生产微信完整链路仍待验收;本次不声称解决旧 output_persistence_error。
- 依据 skill 在最终交付时另行确认源任务工作区清理,分支与提交保留;未得到清理授权前保留目录。
## Promotion Candidates
- 本次 Integration Gate 已记录源提交及验证边界;记录新建 300 步与微信会话原生状态/失败原因展示的集成事实,保留关闭历史会话、仅排队状态及部分正文。 无新产品方向冲突,源记录保持只读。
+1 -1
View File
@@ -4,7 +4,7 @@
平台托管模型的图片输入与思考选项由 Works Square 的 `model_capabilities_v2` 下发。未知能力保持未知;会话保存“模型默认 / 关闭 / 开启及原生强度”,Pi 请求前按冻结的选择写入供应商参数。配置刷新后失效的选择会在发送前提示重新选择;BYOK 模型沿用自身配置。
Makelore 是一个面向软件、视觉创作、智能机器人与个人云智能体的 AI 桌面工作台。当前版本为 `2.0.0`,源码提供四个模块入口;云智能体需配套配置 WS/Yuxi 服务。模块入口页采用统一的横向卡片视觉,工作区左上角入口点击后返回模块入口页:
Makelore 是一个面向软件、视觉创作、智能机器人与个人云智能体的 AI 桌面工作台。当前版本为 `2.0.0`,源码提供四个模块入口;云智能体需配套配置 WS/Yuxi 服务。模块入口页按 Agents、Code、Canvas、Robot 排列,统一采用横向插画卡片;Agents 标语为“打造你想象中的AI助手”。工作区左上角入口点击后返回模块入口页:
- `Makelore Code|AI 编程`:管理本地项目、项目智能体、对话、文件上下文、代码变更和运行时。
- `Makelore Agents|AI 智能体`:配置个人云智能体并试聊,发布后正式对话、按账号分享或创建应用 API Key。支持流式回复、审批、排队请求、附件与产物、自动任务和活动历史;重新进入时恢复最近智能体与对话,未确认操作可按原输入重试。聊天可提出日程建议,由创建者核对能力、时间和费用后启用。知识库支持上传、索引、替换、删除及导入本人会话附件;个人 MCP 凭据、Skills、子智能体可自助管理。支持智能体和会话归档、发布版本比较及恢复为草稿。所有模型调用由创建者个人词元点数支付,可按智能体设置每次任务和每日上限,费用按时间、来源、应用分页统计;分享/API 调用者保有自己的内容空间。Main 管理云会话和本机文件,Renderer 通过 Host API 操作。配套服务接入见 [Yuxi MakeLore 说明](https://xerrors.github.io/Yuxi/advanced/makelore-agents.html)。 编辑采用全高桌面分栏,支持拖动调整与展开、独立滚动、小窗口配置/试用切换。配置分为指令、能力、知识、限制;草稿明确保存(Ctrl/⌘+S),保存与切换页面保留当前试用及未发送文字,新试用明确使用最新保存版本。费用上限在限制中独立保存。Enter 发送、Shift+Enter 换行,F6 切换面板焦点、Esc 恢复分栏。
+1 -1
View File
@@ -48,7 +48,7 @@ export interface CloudAgentConfiguration {
export const EMPTY_CLOUD_CONFIGURATION: CloudAgentConfiguration = {
model: '', tools: [], knowledges: [], mcps: [], skills: [], preload_skills: [], subagents: [],
tool_approval_mode: 'default', max_execution_steps: 40, max_output_tokens: 4096, max_run_seconds: 600,
tool_approval_mode: 'default', max_execution_steps: 300, max_output_tokens: 4096, max_run_seconds: 600,
};
export interface CloudAgentEntry {
Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

+10 -10
View File
@@ -18,6 +18,16 @@ export type AiModuleDefinition = {
};
export const aiModules: readonly AiModuleDefinition[] = [
{
id: 'cloud_agents',
title: 'Makelore Agents',
subtitle: 'AI 智能体',
description: '打造你想象中的AI助手',
route: '/cloud-agents',
enabled: true,
Icon: Sparkles,
switcherLabel: 'Agents 智能体',
},
{
id: 'programming',
title: 'Makelore Code',
@@ -46,16 +56,6 @@ export const aiModules: readonly AiModuleDefinition[] = [
Icon: Bot,
switcherLabel: 'Robot 机器',
},
{
id: 'cloud_agents',
title: 'Makelore Agents',
subtitle: 'AI 智能体',
description: '配置专属智能体,从定义用途与角色开始',
route: '/cloud-agents',
enabled: true,
Icon: Sparkles,
switcherLabel: 'Agents 智能体',
},
];
const moduleAccessKeyById: Record<AiModuleId, ModuleAccessKey> = {
@@ -112,7 +112,7 @@ function ChannelSession({ sessionId, visible, refreshRevision, onBusy, onNewSess
return () => { live = false; clearTimeout(timer); };
}, [sessionId, visible, revision, refreshRevision]);
const runId = data?.run?.agent_run_id;
const runStatus = data?.run?.status;
const runStatus = data?.run?.status ?? data?.queued_requests?.[0]?.status;
const threadId = data?.thread_id;
useEffect(() => {
if (!visible || !threadId) return;
@@ -169,8 +169,13 @@ function ChannelSession({ sessionId, visible, refreshRevision, onBusy, onNewSess
{file.is_dir ? <Button variant="ghost" disabled={busy} className="min-w-0 justify-start" onClick={() => setPath(file.directory_path)}><Folder className="mr-2 h-4 w-4" /><span className="truncate">{file.name}</span></Button>
: <><span className="min-w-0 break-all">{file.name}</span><Button variant="outline" size="sm" disabled={busy} aria-label={'保存 ' + file.name} onClick={() => void save(file)}><Download className="mr-2 h-4 w-4" />保存文件</Button></>}
</div>);
const statusText = runStatus ? cloudStatus(runStatus) : data?.session_state === 'closed' ? '历史会话 · 可以查看消息和保存文件' : '等待微信消息';
const runError = data?.run?.error;
return <div className="space-y-4">
<div className="flex flex-wrap items-center justify-between gap-3"><p role="status" className="text-sm text-muted-foreground">{data?.session_state === 'closed' ? '历史会话 · 可以查看消息和保存文件' : runStatus ? cloudStatus(runStatus) : '等待微信消息'}</p>
<div className="flex flex-wrap items-center justify-between gap-3"><div data-testid="wechat-run-status" className="space-y-1 text-sm">
<p role="status" aria-label="微信任务状态" className="text-muted-foreground">任务状态:{statusText}</p>
{runError?.message && <p role="alert" aria-label="微信任务错误" className="text-destructive">任务错误:{runError.type ? runError.type + ' · ' : ''}{runError.message}</p>}
</div>
{controllable && <div className="flex gap-2"><Button variant="outline" size="sm" disabled={locked} onClick={() => void control({ session_id: sessionId, operation_id: crypto.randomUUID(), action: 'stop' }).catch(() => undefined)}>停止本次任务</Button>
<Button variant="ghost" size="sm" disabled={locked || running} onClick={() => void control({ session_id: sessionId, operation_id: crypto.randomUUID(), action: 'new-session' }).catch(() => undefined)}>开始新对话</Button></div>}</div>
{pending.map(operation => <div key={operation.id} className="space-y-2 rounded-lg border border-amber-200 p-3 text-sm"><p>上次会话操作的结果尚未确认。恢复会核对同一次操作。</p>
@@ -75,7 +75,7 @@ export function ConfigurationFields({ slug, value, disabled, onChange, section =
</div>
<div hidden={section !== 'all' && section !== 'limits'} className="space-y-6">
<CloudBudgetEditor slug={slug} />
<h2 className="font-medium">运行限制</h2><p className="text-xs text-muted-foreground">以下设置随草稿保存;费用上限独立保存,对后续调用生效。</p>
<h2 className="font-medium">运行限制</h2><p className="text-xs text-muted-foreground">以下设置随草稿保存;费用上限独立保存,对后续调用生效。执行步数会统计模型调用、工具、图节点和中间件步骤。</p>
<label className="block space-y-2 text-sm"><span>工具审批</span>
<select className="h-10 w-full rounded-md border border-input bg-background px-3" disabled={disabled}
value={value.tool_approval_mode} onChange={e => change('tool_approval_mode', e.target.value === 'always_trust' ? 'always_trust' : 'default')}>
+5 -6
View File
@@ -1,5 +1,6 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import moduleAgentsImage from '@/assets/module-agents.webp';
import moduleCanvasImage from '@/assets/module-canvas-neon.webp';
import moduleGameImage from '@/assets/module-game.webp';
import moduleRobotImage from '@/assets/module-robot.webp';
@@ -12,8 +13,8 @@ import { cn } from '@/lib/utils';
import { useAuthStore } from '@/stores/auth';
import { getUserProfileDisplayName } from '@/stores/user-profile';
const moduleSelectionContent: Record<AiModuleId, { label: string; image?: string; imageAlt: string }> = {
cloud_agents: { label: 'Agents 智能体', imageAlt: '个人云智能体' },
const moduleSelectionContent: Record<AiModuleId, { label: string; image: string; imageAlt: string }> = {
cloud_agents: { label: 'Agents 智能体', image: moduleAgentsImage, imageAlt: '个人云智能体' },
programming: { label: 'Code 编程', image: moduleGameImage, imageAlt: '游戏创作工作台' },
painting: { label: 'Canvas 设计', image: moduleCanvasImage, imageAlt: '数位板设计创作' },
robot: { label: 'Robot 机器', image: moduleRobotImage, imageAlt: '青少年管理机器人硬件与设备绑定' },
@@ -90,14 +91,12 @@ export function ModuleSelection({ authRequired = true }: { authRequired?: boolea
<span className="module-option-card-frame" aria-hidden="true" />
<div className="module-option-card-surface relative flex h-full w-full rounded-lg bg-background">
<div className="module-option-card-image relative shrink-0">
{content.image ? <img
<img
src={content.image}
alt={content.imageAlt}
className={cn('module-option-card-image-media h-full w-full object-cover', !enabled && 'grayscale')}
draggable="false"
/> : <div className="flex h-full w-full items-center justify-center bg-violet-50 text-violet-600">
<module.Icon className="h-12 w-12" strokeWidth={1.25} />
</div>}
/>
</div>
<div className="module-option-card-content relative min-h-0 flex-1">
<p className="module-option-card-title font-medium tracking-[-0.02em]">{content.label}</p>
+2
View File
@@ -84,8 +84,10 @@ test('own WeChat conversation approval and generated PPT delivery in the desktop
await page.getByRole('button', { name: /我的创作助手/ }).click();
await page.getByRole('button', { name: '微信对话', exact: true }).click();
const own = page.getByRole('region', { name: '微信会话', exact: true });
await expect(own.getByTestId('wechat-run-status')).toContainText('任务状态:等待你的确认');
await own.getByRole('button', { name: '允许执行', exact: true }).click();
await expect(own.getByRole('heading', { name: '演示文稿已完成' })).toBeVisible();
await expect(own.getByTestId('wechat-run-status')).toContainText('任务状态:已完成');
await own.getByRole('button', { name: '保存 创作建议.pptx', exact: true }).click();
await expect(own.getByText('已保存 创作建议.pptx', { exact: true })).toBeVisible();
await page.screenshot({ path: testInfo.outputPath('wechat-own-deliverables.png') });
+9
View File
@@ -89,6 +89,15 @@ test.describe('Makelore module navigation without setup flow', () => {
await expect(page.getByTestId('ai-module-selection-page')).toBeVisible();
const moduleCards = page.locator('[data-testid^="ai-module-option-"]');
await expect(moduleCards.locator('.module-option-card-title')).toHaveText([
'Agents 智能体', 'Code 编程', 'Canvas 设计', 'Robot 机器',
]);
await expect(moduleCards.first().locator('.module-option-card-description')).toHaveText('打造你想象中的AI助手');
await expect(moduleCards.locator('img')).toHaveCount(4);
await expect.poll(async () => await moduleCards.locator('img').evaluateAll((images) =>
images.every((image) => image.complete && image.naturalWidth > 0),
)).toBe(true);
await page.screenshot({ path: test.info().outputPath('module-entry-artwork.png') });
const readCardMetrics = async () => await moduleCards.evaluateAll((elements) => elements.map((element) => {
const bounds = element.getBoundingClientRect();
const image = element.querySelector('.module-option-card-image')?.getBoundingClientRect();
+25
View File
@@ -155,6 +155,16 @@ describe('Main cloud Agents boundary', () => {
expect(JSON.parse(fetchImpl.mock.calls[1][1].body)).toEqual({ request_id: 'request', thread_id: 'thread', query: 'hello' });
});
it('defaults omitted execution steps to 300 while preserving an explicit saved limit', async () => {
const { max_execution_steps: _omitted, ...configurationWithoutSteps } = EMPTY_CLOUD_CONFIGURATION;
const fetchImpl = vi.fn().mockResolvedValueOnce(session())
.mockResolvedValueOnce(json({ ...draft, configuration: { ...configurationWithoutSteps, max_execution_steps: 40 } }))
.mockResolvedValueOnce(json({ ...draft, configuration: configurationWithoutSteps }));
const module = moduleFor(fetchImpl);
expect((await module.get(draft.slug)).configuration.max_execution_steps).toBe(40);
expect((await module.get(draft.slug)).configuration.max_execution_steps).toBe(300);
});
it('uses the WS credential directly for the creator ledger and never exchanges it into Renderer data', async () => {
const fetchImpl = vi.fn().mockResolvedValueOnce(json({ unit: '词元点数', items: [], access_token: 'private' }));
const result = await moduleFor(fetchImpl).execute({ operation: 'costs', input: { slug: draft.slug } });
@@ -222,6 +232,21 @@ describe('Main cloud Agents boundary', () => {
});
});
it('preserves a failed channel run status, partial output, and authoritative error', () => {
const plan = operationPlan({ operation: 'channelConversation', input: { session_id: 'session-1' } });
expect(plan.project({
session_id: 'session-1', thread_id: 'thread-1', messages: [], queued_requests: [], next_offset: null,
run: { agent_run_id: 'run-1', request_id: 'request-1', thread_id: 'thread-1', agent_slug: draft.slug,
status: 'failed', output: 'PPT 只写入了一部分。', version: '1',
error: { type: 'execution_step_limit', message: '本次运行已达到执行步数上限,尚未完成。可在智能体设置中提高上限后重试。' } },
})).toEqual({
session_id: 'session-1', thread_id: 'thread-1', messages: [], queued_requests: [], next_offset: null,
run: { agent_run_id: 'run-1', request_id: 'request-1', thread_id: 'thread-1', agent_slug: draft.slug,
status: 'failed', output: 'PPT 只写入了一部分。', version: '1',
error: { type: 'execution_step_limit', message: '本次运行已达到执行步数上限,尚未完成。可在智能体设置中提高上限后重试。' } },
});
});
it('routes user-level channel accounts without requiring an Agent slug', () => {
const list = operationPlan({ operation: 'channelAccounts', input: {} });
expect(list.path).toBe('/api/makelore/channel-accounts');
@@ -43,6 +43,40 @@ it('approves the actual action batch through the self-session endpoint and autom
expect(api.call.mock.calls.some(call => ['resume', 'run', 'files', 'submit'].includes(call[0]))).toBe(false);
});
it.each([
['running', '运行中'],
['completed', '已完成'],
['cancelled', '已停止'],
['interrupted', '等待你的确认'],
] as const)('renders the authoritative %s WeChat run status', async (status, label) => {
const base = api.call.getMockImplementation()!;
api.call.mockImplementation(async (operation, input) => operation === 'channelConversation'
? { ...history, run: { ...run, status } } : base(operation, input));
render(<CloudChannelConversations slug={session.agent_slug} />);
expect(await screen.findByTestId('wechat-run-status')).toHaveTextContent('任务状态:' + label);
});
it('keeps partial assistant output visible while surfacing a closed run failure and its authoritative error', async () => {
const base = api.call.getMockImplementation()!;
api.call.mockImplementation(async (operation, input) => operation === 'channelConversation'
? { ...history, session_state: 'closed', grant_state: 'revoked', run: { ...run, status: 'failed', error: {
type: 'unexpected_error', message: 'Recursion limit of 40 reached',
} }, messages: [{ id: 1, role: 'assistant', content: 'PPT 只写入了一部分。' }] } : base(operation, input));
render(<CloudChannelConversations slug={session.agent_slug} />);
const status = await screen.findByTestId('wechat-run-status');
expect(status).toHaveTextContent('任务状态:失败');
expect(screen.getByRole('alert', { name: '微信任务错误' })).toHaveTextContent('unexpected_error · Recursion limit of 40 reached');
expect(screen.getByText('PPT 只写入了一部分。')).toBeVisible();
});
it('shows a queued request status before the authoritative run is exposed', async () => {
const base = api.call.getMockImplementation()!;
api.call.mockImplementation(async (operation, input) => operation === 'channelConversation'
? { ...history, run: null, queued_requests: [{ request_id: 'queued-request', thread_id: session.thread_id, run_id: null, status: 'running', version: '1' }] } : base(operation, input));
render(<CloudChannelConversations slug={session.agent_slug} />);
expect(await screen.findByTestId('wechat-run-status')).toHaveTextContent('任务状态:运行中');
});
it('retries an uncertain stop with the identical operation ID and keeps other controls disabled', async () => {
const base = api.call.getMockImplementation()!;
let original: unknown;
+8 -1
View File
@@ -71,7 +71,12 @@ describe('AI module navigation', () => {
for (const moduleId of ['programming', 'painting', 'robot', 'cloud_agents'] as const) {
expect(screen.getByTestId(`ai-module-option-${moduleId}`).querySelector('.module-option-artwork')).toBeNull();
}
expect(screen.getAllByTestId(/^ai-module-option-/u)).toHaveLength(4);
expect(screen.getAllByTestId(/^ai-module-option-/u).map((option) => option.dataset.testid)).toEqual([
'ai-module-option-cloud_agents',
'ai-module-option-programming',
'ai-module-option-painting',
'ai-module-option-robot',
]);
expect(screen.queryByTestId('ai-module-option-learning')).not.toBeInTheDocument();
expect(screen.queryByText('先选一个入口。进入后,你还可以从左下角随时切换到其他模块。')).not.toBeInTheDocument();
expect(screen.queryByText('选择创作空间。你可以随时从侧边栏切换。')).not.toBeInTheDocument();
@@ -90,6 +95,8 @@ describe('AI module navigation', () => {
expect(robotOption).toHaveTextContent('Robot 机器');
expect(robotOption).toHaveTextContent('制作你的第一个机器人小伙伴');
expect(screen.getByAltText('青少年管理机器人硬件与设备绑定')).toBeInTheDocument();
expect(screen.getByAltText('个人云智能体')).toHaveAttribute('src', expect.stringContaining('module-agents.webp'));
expect(screen.getByAltText('个人云智能体')).toHaveClass('module-option-card-image-media', 'object-cover');
fireEvent.click(screen.getByTestId('ai-module-option-painting'));
expect(await screen.findByTestId('location-path')).toHaveTextContent('/image-canvas');