Commit 0ddb0a2e authored by edy's avatar edy

文档提交

parent bb9bdf66
Pipeline #18500 failed
...@@ -42,3 +42,7 @@ skills/**/api_key.txt ...@@ -42,3 +42,7 @@ skills/**/api_key.txt
workspace/ workspace/
# 备份缓存目录 # 备份缓存目录
backup-cache/ backup-cache/
# 文档目录
docs/
docs-backup-*/
This diff is collapsed.
# QianjiangClaw Commercial Product Blueprint
Updated: 2026-03-23
## 1. Product Direction
Current commercial direction is:
- The Windows installer remains the single user-facing entry point.
- Bundled OpenClaw runtime ships inside the installer.
- The first real delivery milestone in Stage D is not full business cloud integration.
- The first real delivery milestone is: installer can become truly usable by letting the user bind an OpenClaw employee `api_key`, fetch runtime config from cloud, and start bundled runtime automatically.
## 2. Product Principles
Current fixed principles:
- The user must first bind an OpenClaw employee `api_key` before OpenClaw can be used.
- This `api_key` is the runtime employee identity key, not the upstream model vendor key.
- The user should not manually enter provider, model, base_url, model vendor api_key, local Node path, OpenClaw entry path, or Gateway token in the normal product flow.
- The desktop app stores the employee `api_key` in Electron Main secret storage.
- Renderer remains a UI layer only and does not own raw credentials.
## 3. First Real Usable Flow
Stage D step 1 user flow should be:
1. User installs the Windows app.
2. User opens the desktop app.
3. User goes to settings or first-run activation view.
4. User binds an OpenClaw employee `api_key`.
5. Electron Main calls `POST /openclaw-employee-config` with `{ api_key, action: "init" }`.
6. Main receives cloud runtime payload.
7. Main generates local managed runtime config.
8. Bundled runtime starts.
9. Gateway becomes available.
10. User can start using the installer product.
## 4. Required Runtime Cloud APIs
Current required runtime-side APIs are:
- `POST /openclaw-employee-config`
- `POST /openclaw-heartbeat`
- `POST /openclaw-employee-events`
For Stage D step 1, only the first endpoint is required for initial delivery.
## 5. Runtime Config Strategy
The current runtime config strategy is:
- user provides employee `api_key`
- cloud returns runtime payload
- desktop app writes local managed config
- bundled runtime starts from that managed config
The `openclaw-employee-config` payload should provide business-controlled runtime fields such as:
- `persona_prompt`
- `welcome_message`
- `work_hours`
- `auto_reply_rules`
- `resource_quota`
- `llm.model_id`
- `llm.temperature`
- `llm.max_tokens`
- `llm.provider.base_url`
- `llm.provider.api_key`
- `skills`
- `channels`
- `config_version`
- `endpoints.heartbeat`
- `endpoints.events`
The desktop app should still add local machine-specific values such as:
- workspace path
- runtime state/log paths
- bundled Gateway bind and port
- local managed config output path
## 6. Security Rules
- Employee `api_key` stays in Electron Main and secret storage.
- Raw `api_key` must not be exposed to Renderer.
- Diagnostics export must not dump raw credentials.
- If employee `api_key` is missing, bundled runtime must not pretend to be available.
- If `openclaw-employee-config` fetch fails, bundled runtime must not start.
## 7. What Is Not Stage D Step 1 Yet
Not part of this first delivery slice:
- full product-side login, account, credits, and Skills production integration
- heartbeat and event reporting implementation
- full entitlement or billing product UX
- final release polish such as icon, signing, and upgrade path
## 8. Acceptance for This First Delivery Slice
Stage D step 1 should only be considered complete when:
- user can bind an OpenClaw employee `api_key`
- app can successfully call `POST /openclaw-employee-config`
- app can generate managed runtime config from real cloud payload
- bundled runtime starts from that config
- installer becomes truly usable without manual provider/model/base_url configuration
# QianjiangClaw Product Roadmap
Updated: 2026-03-23
## 1. Final Goal
The final product goal is locked as:
- Deliver a `Windows installer`
- The installer `bundles OpenClaw runtime`
- End users do `not` need to preinstall OpenClaw, Node, WSL2, or use the command line
- After install, users only need to:
- open the desktop app
- sign in with a company account
- fetch profile, credit status, and skills through cloud APIs
- start chatting and using skills directly
This means the final product is:
- not a Gateway connector only
- not a dev-only desktop shell
- not a "bring your own OpenClaw" tool
- not a desktop shell that expects users to configure provider/model/API keys by default
The final product is:
- a non-technical-user-friendly Windows desktop AI app
- with OpenClaw runtime bundled and managed by the installer
- with login, credits, and skills driven by cloud APIs
## 2. Fixed Product Decisions
These decisions are considered locked unless explicitly changed later:
- Use `Electron + React + TypeScript + pnpm workspace`
- Keep process boundaries:
- `Renderer -> preload -> Electron Main -> GatewayClient / RuntimeManager / AuthClient / ProfileClient / CreditClient / SkillClient`
- Current external-Gateway mode is a transition phase, not the final form
- The final runtime delivery model is:
- `installer bundles OpenClaw runtime`
- The target bundled runtime direction is:
- `native Windows runtime`
- `runtime-manager` will return to the main path in the bundled-runtime phase
- The desktop app remains the single user-facing entry point
- The default product path does not require customer-provided API keys
- Profile, credit status, skill catalog, and skill availability are fetched from `cloud APIs`
- Platform credits are the default consumption model, and model usage is platform-managed
## 3. Current State
What is already true now:
- Desktop shell starts successfully
- Real preload/IPC path works
- The UI can connect to local OpenClaw Gateway
- Sessions/history work
- One real `chat.send` from the Electron UI path has already succeeded
- Smoke harness is now gated behind explicit smoke mode
Current reality:
- The desktop app is no longer just a skeleton
- The transition-phase desktop client is already functional on this machine
- The remaining work is about installer delivery, commercial API integration, and eventually bundled runtime
## 4. Delivery Stages
### Stage A: Transition MVP Cleanup
Goal:
- Turn the current desktop client into a stable, clean MVP baseline
Required outcomes:
- UI has:
- loading state
- error state
- empty state
- reconnect guidance
- chat sending state
- Logs are readable enough for debugging
- Secret storage is upgraded from dev-file fallback to `keytar`
- Diagnostics export exists
- Smoke harness stays opt-in only and does not affect normal usage
Success criteria:
- On a machine with local OpenClaw already running, the app can:
- launch
- connect
- show status
- list sessions
- show history
- send chat
- export diagnostics
### Stage B: Installer MVP
Goal:
- Prove the Windows installer delivery path before bundled runtime is introduced
Required outcomes:
- Build a working Windows installer
- Installer installs the desktop app correctly
- Installed app launches correctly
- Installed app still works against an already installed OpenClaw environment
- Installed app can also complete:
- login
- entitlement checks
- profile fetch
- credit fetch
- skill catalog and availability fetch
Success criteria:
- On a test machine with existing OpenClaw:
- install succeeds
- app launches after install
- preload and renderer assets load correctly
- login and entitlement work
- profile, credits, and skills load from APIs
- connection and chat still work
### Stage C: Bundled Runtime PoC
Goal:
- Prove that bundled native Windows OpenClaw runtime can be shipped and started by the desktop app
Required outcomes:
- Define a fixed bundled runtime directory layout
- `runtime-manager` supports:
- detect
- resolve paths
- start
- stop
- restart
- health
- tail logs
- Desktop app can run in bundled-runtime mode
- Desktop app no longer depends on user-installed OpenClaw in this mode
- Login, credits, and skills continue to work through APIs in bundled-runtime mode
Success criteria:
- On a clean Windows machine without OpenClaw preinstalled:
- installer installs successfully
- bundled runtime can be detected
- bundled runtime can start
- desktop app can connect to its bundled Gateway
- login, profile, credits, and skills still work
- chat works
- failures are diagnosable
### Stage D: One-Click Product Version
Goal:
- Turn the bundled-runtime PoC into the real end-user product
Required outcomes:
- Installer includes runtime payload
- First launch handles initialization automatically
- Desktop app defaults to bundled-runtime mode
- Versioning and diagnostics are stable enough for user delivery
- Login, profile, credits, and skills are fully cloud-driven
Success criteria:
- A non-technical user can:
- install the app
- open it
- sign in
- see profile, credits, and available skills
- use chat and skills
- without manually installing any OpenClaw dependency
- without configuring provider/model/API keys manually
## 5. Execution Order
Do the work in this order:
1. Finish Stage A cleanup
2. Build and verify Stage B installer MVP
3. Implement and validate Stage C bundled-runtime PoC
4. Turn the PoC into Stage D production-style bundled delivery
Do not skip ahead:
- Do not make bundled runtime the immediate next step before installer MVP is stable
- Do not promise one-click install until bundled-runtime PoC passes on a clean machine
- Do not move secret, entitlement, credits, or skill API logic into renderer
## 6. Stage A Implementation Checklist
This is the next practical work queue:
1. UI state completion
- gateway loading state
- gateway error state
- no-session state
- no-message state
- chat sending state
- reconnect hint text
2. Logs cleanup
- strip ANSI escape codes
- strip control characters
- normalize noisy log text
- prefer readable summary text over raw noisy payloads when possible
3. SecretManager upgrade
- replace dev-file secret storage with `keytar`
- keep a safe fallback strategy only when absolutely needed for development
4. Diagnostics export
- export config summary
- export gateway/runtime status
- export recent logs
- export version/path metadata
5. Keep smoke tooling opt-in only
## 7. Stage B Implementation Checklist
1. Finalize `electron-builder` config
2. Verify install paths and asset paths
3. Verify installed app launch behavior
4. Integrate and verify login / entitlement / profile / credits / skills APIs
5. Verify installed app can still connect to an existing OpenClaw environment
6. Record installer smoke-test checklist and failure cases
## 8. Stage C Implementation Checklist
1. Define bundled runtime layout
2. Restore `runtime-manager` as a primary runtime subsystem
3. Add bundled-runtime mode detection and boot flow in Electron Main
4. Add runtime health and lifecycle UI exposure
5. Keep login, credits, and skills APIs working in bundled-runtime mode
6. Validate bundled runtime on a clean Windows machine
## 9. Acceptance Criteria
### Transition MVP accepted when:
- Desktop UI is stable enough for repeated local use
- Errors and empty states are understandable
- Secrets are not stored in the current dev-file-only path
- Diagnostics export works
### Installer MVP accepted when:
- Installer installs cleanly
- Installed app launches
- Installed app works with an already-installed OpenClaw environment
- Installed app displays profile, credits, and skills from APIs correctly
### Bundled Runtime PoC accepted when:
- A clean machine without OpenClaw can use the app after install
- Runtime lifecycle is manageable from the app
- Runtime failures can be diagnosed
- Login, credits, and skills do not regress in bundled-runtime mode
### Final product accepted when:
- User installs once and can use the app directly
- User does not need to install OpenClaw separately
- User does not need to provide model/API keys
- Desktop app is the only visible entry point
## 10. Important Boundaries For Future AI Work
Any future AI agent continuing this project should assume:
- The current external-Gateway implementation is transitional
- The final business/product direction is bundled runtime inside the installer
- The desktop app is not meant to stay a connector-only tool
- `runtime-manager` must come back as a first-class subsystem later
- Electron Main remains responsible for:
- runtime process management
- config management
- auth/session token management
- diagnostics
- API client orchestration
- Renderer should stay UI-only and not directly own secrets, runtime control, or cloud entitlement logic
- Skill catalog and availability should come from APIs, not be hardcoded into the installer
## 11. Recommended Next Task
The recommended next implementation task is:
- finish Stage A productization work, then move directly into installer smoke testing plus commercial API integration
Concrete next steps:
1. installer smoke test
2. login / entitlement API integration
3. profile / credits / skills API integration
4. then move to bundled-runtime work
# QianjiangClaw Product Roadmap
Updated: 2026-03-23
## 1. Current Delivery Order
Current delivery order should be treated as:
- Stage A: complete
- Stage B: complete
- Stage C technical PoC: complete
- Stage D step 1: make the installer truly usable through runtime cloud config integration
- later Stage D work: heartbeat, events, business cloud APIs, and full commercial UX
## 2. Stage D Step 1 Goal
Stage D step 1 goal is now fixed as:
- the installer becomes truly usable
- bundled OpenClaw starts from real cloud-fetched runtime config
- user first binds an OpenClaw employee `api_key`
- app automatically pulls runtime config and starts bundled runtime
This means the current top priority is not full business API integration.
The top priority is runtime usability for the installer.
## 3. Must-Integrate Runtime APIs for Step 1
Current must-integrate runtime API for this first slice:
- `POST /openclaw-employee-config`
Later runtime APIs:
- `POST /openclaw-heartbeat`
- `POST /openclaw-employee-events`
## 4. Step 1 Implementation Order
Implementation should happen in this order:
1. add user-facing binding flow for OpenClaw employee `api_key`
2. store that key in `SecretManager/keytar`
3. implement `OpenClawConfigClient` for `POST /openclaw-employee-config`
4. fetch config with `{ api_key, action: "init" }`
5. transform returned payload into managed local runtime config
6. start bundled runtime from that generated config
7. verify installer startup and usable state
## 5. What Comes After Step 1
Only after installer usability is proven, continue with:
- `POST /openclaw-heartbeat`
- `POST /openclaw-employee-events`
- product-side login/profile/credits/Skills real production integration
- entitlement and billing UX
- clean-machine validation and formal release polish
## 6. Acceptance Gates for Step 1
Stage D step 1 is complete only when:
- user can bind an OpenClaw employee `api_key`
- missing key prevents runtime startup with a clear UI message
- `POST /openclaw-employee-config` succeeds with a real key
- managed runtime config is generated from returned payload
- bundled runtime starts from that config
- installer is usable without manual provider/model/base_url/vendor api_key setup
## 7. Key Product Rule
The product rule is now:
- users still should not manually configure provider, model, base_url, or vendor model api_key
- but users must first bind the OpenClaw employee `api_key` that activates their runtime instance
# QianjiangClaw Architecture
Updated: 2026-03-23
## 1. Stable Desktop Boundary
The stable boundary remains:
- Renderer
- UI only
- does not own raw runtime credentials
- does not directly start runtime processes
- preload
- exposes controlled desktop APIs to Renderer
- Electron Main
- owns secret access
- owns runtime cloud fetch
- owns managed runtime config generation
- owns bundled runtime lifecycle
- GatewayClient / RuntimeManager / cloud clients
## 2. Current Runtime-Cloud Design
Stage D step 1 uses a runtime-first cloud integration model.
The current key rule is:
- the user must first bind an OpenClaw employee `api_key`
- Electron Main uses that key to call `POST /openclaw-employee-config`
- the returned payload becomes the source of truth for runtime business configuration
This `api_key` is not the LLM vendor key. It is the OpenClaw employee identity credential.
## 3. Required Runtime-Side Clients
Main should include or add these runtime-side pieces:
- `OpenClawConfigClient`
- calls `POST /openclaw-employee-config`
- fetches runtime payload for startup
- later:
- heartbeat client for `POST /openclaw-heartbeat`
- event client for `POST /openclaw-employee-events`
## 4. Startup Flow for Stage D Step 1
Installer startup should follow this order:
1. Desktop app loads local settings.
2. Desktop app reads stored employee `api_key` from secret storage.
3. If missing, runtime startup is blocked and UI asks the user to bind the key.
4. If present, Main calls `POST /openclaw-employee-config` with:
- `api_key`
- `action = "init"`
5. Main validates returned runtime payload.
6. Main merges cloud payload with local machine-specific fields.
7. Main writes local managed runtime config.
8. `RuntimeManager.start()` launches bundled runtime using that managed config.
9. Gateway becomes available for the desktop product.
## 5. Runtime Config Responsibility Split
Cloud payload should provide runtime business configuration such as:
- `persona_prompt`
- `welcome_message`
- `work_hours`
- `auto_reply_rules`
- `resource_quota`
- `llm.model_id`
- `llm.temperature`
- `llm.max_tokens`
- `llm.provider.name`
- `llm.provider.base_url`
- `llm.provider.api_key`
- `skills`
- `channels`
- `config_version`
- runtime reporting endpoints
Desktop Main should still provide local host-specific fields such as:
- workspace path
- runtime state dir
- runtime logs dir
- managed config output path
- bundled Gateway bind and port
- generated gateway auth token for local control path
## 6. Security Rules
- Employee `api_key` lives in `SecretManager/keytar`.
- Renderer never receives raw `api_key`.
- Managed runtime config may contain effective runtime credentials, but diagnostics must not export raw sensitive values.
- If cloud config fetch fails, bundled runtime must remain unavailable instead of fake-ready.
## 7. Current State
Already in place:
- installer packaging
- bundled runtime payload delivery
- runtime detect/start/stop/restart/health/tailLogs
- managed config generation path exists locally
- diagnostics and UI pages already exist
Still missing for Stage D step 1:
- user-bound employee `api_key` flow
- `OpenClawConfigClient` wired to `POST /openclaw-employee-config`
- managed config generation from cloud payload
- real installer usability based on cloud-driven startup
This diff is collapsed.
# OpenClaw 客户端自动更新方案
## Summary
为当前 Electron 客户端增加“版本更新自动推送”能力:客户端启动后自动检查版本,云端可按版本、渠道、员工/组织做灰度或强
制更新;用户收到提示后点击下载并安装,体验接近 WorkBuddy。
默认采用“自有云接口 + electron-updater + NSIS 安装包”的方案,优先适配当前 Windows-first 打包链路。
## Key Changes
### 更新发布链路
- 在 apps/desktop 引入 electron-updater。
- 在 apps/desktop/electron-builder.yml 增加 publish/update feed 配置。
- 打包后产物需要包含:
- 千匠问天-Setup-x.y.z.exe
- latest.yml
- 安装包 sha512 校验信息
- 发布流程调整为:
1. 更新根 package.json 和 apps/desktop/package.json 版本号。
2. 执行 corepack pnpm package。
3. 上传 installer 与 latest.yml 到云端文件存储/CDN。
4. 后端登记该版本的元数据。
### 云端版本接口
新增一个产品更新接口,建议路径:
POST /v1/desktop/update/check
请求包含:
{
"appId": "com.qianjiangclaw.desktop",
"currentVersion": "0.1.0",
"platform": "win32",
"arch": "x64",
"employeeId": "xxx",
"channel": "stable"
}
响应包含:
{
"available": true,
"version": "0.2.0",
"channel": "stable",
"mandatory": false,
"releaseNotes": "修复启动问题,优化专家加载。",
"feedUrl": "https://cdn.example.com/qjclaw/stable/latest.yml",
"downloadUrl": "https://cdn.example.com/qjclaw/stable/千匠问天-Setup-0.2.0.exe",
"sha512": "..."
}
云端需要支持:
- stable/beta/dev 渠道。
- 按员工、组织、版本范围灰度。
- 强制更新标记。
- 最低可用版本,用于阻止过旧客户端继续使用。
- 回滚到上一版本。
### 桌面主进程
新增 AppUpdateService,放在 apps/desktop/src/main/services/app-update.ts。
职责:
- 读取当前 app.getVersion()。
- 调用云端更新检查接口。
- 配置 autoUpdater.setFeedURL(...)。
- 管理状态机:
- idle
- checking
- available
- not-available
- downloading
- downloaded
- installing
- error
- 处理 electron-updater 事件:
- checking-for-update
- update-available
- update-not-available
- download-progress
- update-downloaded
- error
- 提供“立即安装”能力:调用 autoUpdater.quitAndInstall()。
- 开发环境不自动安装,只返回 mock/disabled 状态。
### IPC 与共享类型
在 packages/shared-types/src/index.ts 增加:
- UpdateStatus
- UpdateCheckResult
- UpdateProgress
- UpdateState
- IPC channels:
- app-update:get-status
- app-update:check
- app-update:download
- app-update:install
- app-update:event
在 apps/desktop/src/preload/index.ts 暴露:
qjcDesktop.appUpdate.getStatus()
qjcDesktop.appUpdate.check()
qjcDesktop.appUpdate.download()
qjcDesktop.appUpdate.install()
qjcDesktop.appUpdate.onEvent(listener)
### Renderer UI
在 apps/ui/src/App.tsx 增加更新提示入口,保持现有主布局稳定。
建议 UI 行为:
- 普通更新:
- 顶部 toast/notice 显示“发现新版本 x.y.z”。
- 按钮:“立即更新”“稍后”。
- 下载中显示进度。
- 下载完成显示“重启并安装”。
- 强制更新:
- 显示不可关闭的更新弹窗。
- 允许查看更新说明。
- smoke/mock API 中补 mock update 状态,避免开发模式 UI 崩溃。
- Windows 发布前建议接入代码签名证书。
- 下载包必须校验 sha512。
- 更新失败不得破坏现有安装。
- 下载中断后允许重新下载。
- 强制更新只阻止业务入口,不直接杀进程。
- dev 模式默认禁用真实安装,避免误触发本地更新。
## Test Plan
- corepack pnpm typecheck
- corepack pnpm build
- corepack pnpm package
- 新增 smoke:
- mock 云端返回无更新。
- mock 云端返回普通更新。
- mock 云端返回强制更新。
- mock 下载失败时 UI 显示错误。
- 已下载后触发安装 IPC。
- 手工验证:
- 旧版本安装后能检测到新版本。
- 点击更新能下载安装包。
- 点击“重启并安装”后版本变为新版本。
- 强制更新弹窗不可被普通关闭绕过。
- 设置页显示当前版本正确。
## Assumptions
- 首期只支持 Windows NSIS 更新。
- 更新源使用自有云接口控制版本策略,安装包文件放 CDN/对象存储。
- 首期采用轮询检查,不做真正 WebSocket 实时推送:
- 启动后检查一次。
- 登录/绑定成功后检查一次。
- 每 6 小时后台检查一次。
- 真实“服务端主动推送”可作为二期,在现有状态机上增加 WebSocket/SSE 触发检查即可。
- 未签名也能开发测试,但生产发布建议签名后再开放自动更新。
\ No newline at end of file
This diff is collapsed.
排查结论:问题真实存在,根因在 workspace/xhs/workspace_entry.py:859。
事实链:
- 第一次确认后,状态是 awaiting_confirmation。
- 用户说“采集1条就行”不是“确认”,代码会在 workspace/xhs/workspace_entry.py:859 清掉原来的关键词/业务需求/目标人群,重新分类。
- 重新分类时,extract_collect_params("采集1条就行") 实际得到:
{"xhs_action":"collect","keywords":["1条就行"],"total_count":1}
- 所以它随后提示还缺 business_need、target_audience,再补充后就变成“关键词:1条就行”。
影响范围:只影响“确认页之后用户补充/修改采集数量”的多轮采集流程;不是采集执行、生成内容、飞书上传本身的问题。
建议修复点:awaiting_confirmation 状态下,如果用户输入的是“采集1条/改成1条/1条就行”,应合并到原 payload 的 total_count,保留原 keywords/business_need/target_audience,然后重新展示确认页。
## Summary
- 目标:用户在确认页后说“采集1条就行 / 改成3条 / 1条”时,只更新采集数量,不丢失已确认的关键词、业务需求、目标人群。
- 原则:不靠固定句子硬编码,基于“当前会话状态 + 字段级增量解析 + payload 合并”处理。
## Key Changes
- 在 awaiting_confirmation 状态下,除“确认/取消”外,不直接清空状态。
- 对用户新输入做字段级解析:
- 若能解析出 total_count,合并进原 payload。
- 若解析出关键词、业务需求、目标人群,也只覆盖对应字段。
- 未解析出有效字段时,再按现有逻辑结束当前确认状态并重新分类。
- 抽出通用增量解析函数,例如 extract_collect_updates(text):
- 支持数量表达:1条、采集1条、改成1条、一条、只要1条。
- 返回结构化字段,不返回完整新任务,避免把“1条就行”当关键词。
- 调整关键词提取规则:
- 采集动词后如果主体是数量/确认/修改语义,不作为关键词。
- 关键词仍通过原主题句或显式“关键词是...”提取。
## Risks
- 风险 1:过度合并,把用户的新任务误当成修改旧任务。
- 控制方式:只有当前状态是 awaiting_confirmation 且输入解析到明确字段修改时才合并。
- 风险 2:数量中文表达解析不全。
- 控制方式:复用现有中文数字解析 parse_ref_index 思路,扩展为通用 1-20 数量解析。
- 风险 3:影响确认后的重新发起任务。
- 控制方式:如果输入包含新的完整采集主题和关键词,则按新任务重新分类,不合并旧 payload。
- 风险 4:LLM 与本地正则结果不一致。
- 控制方式:确认态下优先使用本地字段级解析;LLM 只用于新任务分类,不用于覆盖完整 payload。
## Test Plan
- 复现原问题:
- 帮我采集 推荐上海平价川味火锅的笔记
- 种草引流涨粉 给热爱美食的人看
- 采集1条就行
- 期望确认页关键词仍是“推荐上海平价川味火锅”,采集数量为 1。
- 数量修改:
- 确认页后输入 改成3条
- 期望只更新 total_count=3。
- 直接确认:
- 确认页后输入 确认
- 期望行为不变,进入采集执行。
- 新任务覆盖:
- 确认页后输入 帮我采集北京烤肉笔记
- 期望按新任务重新进入参数确认,不沿用旧关键词。
- 回归:
- python -m py_compile workspace\xhs\workspace_entry.py
- corepack pnpm smoke:xhs-local-project-package
\ No newline at end of file
# 2026-04-16 桌面端专家入口问题交接
## 背景
本轮处理的是桌面端以下问题:
1. 小红书和抖音专家页不显示
2. 内容账号规划专家、知乎专家是否为独立专家要按项目事实核查
3. 左侧栏多数专家点不了,要求除独立专家外其余专家点击后跳首页对话
4. 左侧专家列表过长,挤占会话管理,需要独立滚动
5. 首页对话发送“你好”仍路由到抖音,且消息马上消失
## 已完成
### 1. 修复首页快捷专家不可点击
文件:
- `apps/desktop/src/main/services/expert-catalog.ts`
改动:
- `promptAvailable` 由“仅检查 promptFile 是否存在”改为:
-`starterPrompt` 即可用
-`promptFile` 文件存在也可用
影响:
- 公众号专家、X 专家、Tiktok 专家、海报专家、GEO 专家、平台精准线索专家恢复可点击
### 2. 修复首页对话串到抖音、消息消失
文件:
- `apps/ui/src/App.tsx`
改动:
- `chat` 视图发送时,优先使用 `home-chat``sessionScopeProjectId`
- 不再优先使用 `workspace.currentProjectId`
- 新增 `openHomeChat()`,保证切回首页对话时同步归一到 `home-chat`
- 左侧“对话”导航点击改为走 `openHomeChat()`
- 首页快捷专家点击也改为走 `openHomeChat(true)`
影响:
- 首页对话不再把消息建进抖音项目
- 消息不会因为会话作用域错位而“发送后消失”
### 3. 恢复专家页真实项目来源
文件:
- `apps/ui/src/App.tsx`
改动:
- 新增 `buildProjectExpertDefinition()`
- 新增 `projectExpertEntries`
- `expertPageProjects` 不再只取 `standaloneExpertEntries`
- 改为基于真实 `visibleProjects` 生成专家页项目
影响:
- 仓库里真实存在的 `xhs` / `douyin` 项目可以重新进入专家页
- 左侧专家栏也改为优先显示真实项目专家,再拼首页快捷专家
### 4. 修复左侧栏滚动布局
文件:
- `apps/ui/src/styles.css`
改动:
- `sidebar-bottom` 改为两段式布局
- 新增 `.sidebar-expert-scroll`
- 新增 `.sidebar-session-section`
- 让专家区和会话区分别滚动
影响:
- 专家列表过长时,不再把会话管理区整体挤没
### 5. 补齐 smoke 类型定义
文件:
- `apps/ui/src/App.tsx`
改动:
- `SmokeUiSnapshot` 新增 `sessionScopeProjectId`
目的:
- 修复 `typecheck` 因 smoke 快照字段缺失导致的编译错误
## 已验证
已通过:
- `corepack pnpm typecheck`
- `powershell -ExecutionPolicy Bypass -File build/scripts/default-chat-smoke.ps1`
- `powershell -ExecutionPolicy Bypass -File build/scripts/project-routing-smoke.ps1`
- `powershell -ExecutionPolicy Bypass -File build/scripts/desktop-expert-entry-smoke.ps1 -SkipMaterializeRuntime`
`desktop-expert-entry-smoke` 已覆盖:
- `content-account-planning`
- `zhihu`
- `wechat-official-account`
- `x-platform`
- `tiktok`
- `poster`
- `geo`
- `precision-leads`
## 关键事实结论
### 1. 小红书 / 抖音专家页消失的主因
不是项目没了,是前端把专家页数据源改成只看 `standalone` 专家定义,导致真实项目 `workspace/xhs``workspace/douyin` 被过滤掉。
### 2. 其他专家点不了的主因
不是按钮组件坏了,是可用性判定错了。首页快捷专家只有 `starterPrompt`,没有 `promptFile`,因此被错误判成不可用。
### 3. 内容账号规划专家 / 知乎专家当前状态
按仓库事实,它们当前仍不是“仓库内已落地的真实独立专家项目”。
说明:
- 当前仓库 `workspace/` 下没有它们对应真实项目目录
- 但 smoke 已经证明:当用户数据里存在对应项目时,UI 入口和会话隔离链路可以工作
结论:
- 现在更准确的说法是:入口机制和隔离路由已支持
- 但仓库内真实项目包还没补齐
## 当前未完成
### 1. 肉眼页面确认未完成
原因不是代码未生效,而是本机存在一个旧的 Electron 进程:
- `PID 20424`
表现:
- 我已执行 `corepack pnpm build`
- 新的 renderer 已成功输出到 `apps/desktop/dist/renderer`
- 但旧进程无法被我当前环境结束,导致用户看到的仍可能是旧界面
### 2. 旧进程状态
用户侧执行过:
```powershell
taskkill /PID 20424 /F /T
```
结果:
- 失败
- 提示该进程属于父进程 `23116` 的子进程
- 原因是 `拒绝访问`
结论:
- 最稳妥处理是重启机器
## 已完成但需要用户重启后确认的点
重启后需要肉眼确认:
1. 左侧或专家页是否能看到“小红书专家”“抖音专家”
2. 点击公众号/X/Tiktok/海报/GEO/平台精准线索,是否跳转首页对话,而不是进入专家页
3. 首页发送“你好”,是否仍会跑到抖音
4. 发送后的消息是否还会消失
5. 左侧专家区和会话区是否都可以独立滚动
## 重启后继续执行顺序
1. 先启动桌面端
2. 先看小红书 / 抖音专家是否出现
3. 再测首页快捷专家跳转是否正确
4. 再测首页发送“你好”
5. 若页面仍不对,先确认是否真的是新进程和新包
## 如果重启后仍异常,优先检查
### A. 是否加载了新 renderer
重点看:
- `apps/desktop/dist/renderer/index.html`
- `apps/desktop/dist/renderer/assets/index-*.js`
### B. 是否仍有旧 Electron 残留
命令:
```powershell
Get-Process | Where-Object { $_.ProcessName -match 'electron|QianjiangClaw' } | Select-Object Id,ProcessName,Path
```
### C. 如果页面还是没有小红书 / 抖音专家
继续检查:
- `workspace.getSummary()` 返回的 `workspace.projects`
- `visibleProjects`
- `projectExpertEntries`
- `expertPageProjects`
## 相关文件
- `apps/ui/src/App.tsx`
- `apps/ui/src/styles.css`
- `apps/desktop/src/main/services/expert-catalog.ts`
## 备注
本轮没有继续接“龙虾密钥真实绑定态页面验证”,因为用户当前首先反馈的是“小红书和抖音专家在页面上仍没看到”,而该现象与旧 Electron 残留更直接相关。后续等重启后再继续做真实页面 smoke。
# 2026-04-17 客户端模型配置打通进度
## 目标
让客户在桌面客户端自行配置项目所使用的模型信息,不依赖项目包内固定写死;项目从云端配置接口拉取 zip 并解压后,实际执行时由客户端把模型配置注入到项目运行时。
## 已完成
### 1. 客户端配置结构已支持 `modelId`
- 已扩展共享类型,`expertModelConfig.image/copywriting/video` 均支持 `modelId`
- 已扩展桌面端配置持久化与归一化逻辑,保存后不会丢失 `modelId`
- 已扩展 IPC 返回值,前端加载配置时可以拿到 `modelId`
涉及文件:
- [packages/shared-types/src/index.ts](D:/qjclaw/packages/shared-types/src/index.ts)
- [apps/desktop/src/main/services/app-config.ts](D:/qjclaw/apps/desktop/src/main/services/app-config.ts)
- [apps/desktop/src/main/ipc.ts](D:/qjclaw/apps/desktop/src/main/ipc.ts)
### 2. 客户端设置页已可配置项目模型
- 已在设置页增加图片模型 `model_id` 输入
- 已在设置页增加文案模型 `model_id` 输入
- 保存设置后,冒烟态和配置回显会校验 `modelId`
涉及文件:
- [apps/ui/src/App.tsx](D:/qjclaw/apps/ui/src/App.tsx)
### 3. 项目运行前注入逻辑已打通
- 新增项目运行时模型注入服务
- 在执行 `workspace_entry.py` 前,根据当前项目 ID 和客户端已保存配置生成 `memory/project.env`
- 同时把生成后的环境变量注入子进程,确保项目执行链路可直接读取
当前已支持:
- `xhs`
- `QWEN_BASE_URL`
- `QWEN_API_KEY`
- `QWEN_MODEL`
- `QWEN_VISION_MODEL`
- `XHS_IMAGE_PROVIDER=env:xhsImage`
- `XHS_IMAGE_BASE_URL`
- `XHS_IMAGE_API_KEY`
- `XHS_IMAGE_MODEL`
- `douyin`
- `DOUYIN_WRITER_LLM_BASE_URL`
- `DASHSCOPE_API_KEY`
- `QWEN_API_KEY`
- `DOUYIN_WRITER_LLM_MODEL`
- `SEEDREAM_ARK_BASE_URL`
- `SEEDREAM_ARK_API_KEY`
- `SEEDREAM_MODEL`
涉及文件:
- [apps/desktop/src/main/services/project-model-runtime.ts](D:/qjclaw/apps/desktop/src/main/services/project-model-runtime.ts)
- [apps/desktop/src/main/services/project-workspace-executor.ts](D:/qjclaw/apps/desktop/src/main/services/project-workspace-executor.ts)
- [apps/desktop/src/main/ipc.ts](D:/qjclaw/apps/desktop/src/main/ipc.ts)
### 4. 打包链路和端到端冒烟已验证通过
- `corepack pnpm typecheck` 通过
- `corepack pnpm package` 通过
- 安装器冒烟通过
- `xhs` 云端 zip -> 解压 -> 激活项目 -> workspace-entry -> `project.env` 注入 冒烟通过
- `douyin` 云端 zip -> 解压 -> 激活项目 -> workspace-entry -> `project.env` 注入 冒烟通过
结果文件:
- [installer-smoke-result.json](D:/qjclaw/.tmp/installer-smoke/20260416-221908/installer-smoke-result.json)
- [xhs result.json](D:/qjclaw/.tmp/xhs-expert-cloud-bundle-smoke/result.json)
- [douyin result.json](D:/qjclaw/.tmp/douyin-expert-cloud-bundle-smoke/result.json)
对应冒烟脚本:
- [build/scripts/installer-smoke.ps1](D:/qjclaw/build/scripts/installer-smoke.ps1)
- [build/scripts/xhs-expert-cloud-bundle-smoke.ps1](D:/qjclaw/build/scripts/xhs-expert-cloud-bundle-smoke.ps1)
- [build/scripts/douyin-expert-cloud-bundle-smoke.ps1](D:/qjclaw/build/scripts/douyin-expert-cloud-bundle-smoke.ps1)
- [apps/desktop/src/main/index.ts](D:/qjclaw/apps/desktop/src/main/index.ts)
## 当前未完成
### 1. 视频模型链路暂未纳入本次范围
- 当前只重点打通了图片模型和文案模型
- `video.modelId` 类型和配置持久化已预留
- 但视频模型的运行时注入、前端独立配置项联动、项目实际消费逻辑,本次未继续展开
### 2. 目前是“客户端本地配置生效”,不是“云端统一下发模型配置”
- 现在已经支持客户在本机客户端配置模型并立即作用于项目执行
- 但还没有把这份模型配置并入远端配置中心做统一下发
- 如果后续要做多端一致、换机继承、后台代运营配置,需要再单独设计云端配置存储和同步
### 3. 还没有单独补业务说明文档
- 当前代码和烟测已齐
- 但还没有补一份给实施/运维/客户的“字段含义、支持项目、配置示例、常见错误”操作文档
## 结论
当前“客户在客户端配置模型 -> 项目从云端拉 zip -> 客户端解压并执行 -> 执行前注入模型环境变量”主链路已经打通,并已通过打包后的端到端冒烟验证。
如果下一步继续推进,优先级建议是:
1. 补一份面向实施和客户的配置说明文档
2. 决定是否要把模型配置接入云端配置中心
3. 视业务需要再补视频模型链路
# 2026-04-21 桌面单实例续接记录
## 目标
本轮要落实的口径是:
- 已有客户端在运行时,再次启动不应继续跑第二个主流程
- 首实例应恢复/显示/聚焦原窗口
- 不应新增一轮 runtime/gateway 启动或冲突日志
对应自动验证命令:
```powershell
corepack pnpm smoke:desktop-single-instance
```
## 已完成
代码侧已落地以下改动:
- `apps/desktop/src/main/index.ts`
- 增加 `app.requestSingleInstanceLock()`
- 增加 `second-instance` 处理
- 增加主窗口跟踪与唤回逻辑:
- `mainWindow`
- `focusMainWindow()`
- `restoreOrCreateMainWindow()`
- `createTrackedMainWindow()`
- 增加单实例 smoke 辅助状态与输出:
- `QJCLAW_SMOKE_SINGLE_INSTANCE`
- `QJCLAW_SMOKE_SINGLE_INSTANCE_READY_PATH`
- `QJCLAW_SMOKE_SINGLE_INSTANCE_EVENT_PATH`
- `runSingleInstanceSmoke()`
- `secondInstanceEventCount`
- `lastSecondInstanceEventSnapshot`
- `activate` 事件改为统一走 `restoreOrCreateMainWindow("activate")`
- `build/scripts/desktop-single-instance-smoke.ps1`
- 已新增单实例 smoke 脚本
- 流程是:
- 起第一个 Electron 实例
- 等首实例写 `ready`
- 起第二个 Electron 实例
- 校验第二个实例快速退出
- 校验首实例收到 `second-instance`
- 校验窗口数仍为 `1`
- 校验 `Launching bundled runtime command` 次数不增加
- 校验日志中没有:
- `gateway already running`
- `Port 18889 is already in use`
- `schtasks /End /TN`
- `package.json`
- 已新增脚本:
- `smoke:desktop-single-instance`
- `build/scripts/README.md`
- 已登记 `desktop-single-instance-smoke.ps1`
## 已验证
- 已通过:
```powershell
corepack pnpm typecheck
```
结果:通过。
## 当前阻塞
自动 smoke 目前还没有跑通,阻塞点不是 TypeScript 编译,而是本机环境残留了多个无法在当前权限下结束的 `electron.exe`
已观察到的残留 PID:
- `10420`
- `19736`
- `23484`
- `23564`
- `23588`
- `23820`
- `24384`
现象:
- `corepack pnpm smoke:desktop-single-instance` 失败
- 失败点是首实例迟迟没有写出 `ready` 文件
- 手工尝试结束残留进程时,`taskkill` / `Stop-Process` 都报 `Access is denied`
- 在残留进程存在时,单实例锁环境不干净,自动验证结果不可信
失败输出里最关键的信息是:
- `First Electron instance never reported single-instance readiness.`
相关失败产物路径:
- `D:\qjclaw\.tmp\desktop-single-instance-smoke\result.json`
- `D:\qjclaw\.tmp\desktop-single-instance-smoke\result.json.trace.log`
- `D:\qjclaw\.tmp\desktop-single-instance-smoke\logs\startup\startup-latest.log`
## 已尝试但未完成
已执行过这些命令,但因为权限问题未能清掉残留进程:
```powershell
taskkill /IM electron.exe /F /T
```
```powershell
Stop-Process -Id 10420,19736,23484,23564,23588,23820,24384 -Force
```
校验残留进程的命令:
```powershell
Get-Process electron -ErrorAction SilentlyContinue
```
当前结论:
- 代码改动已经在仓库里
- 当前最先要解决的是机器上的残留 Electron 进程
- 在这个问题解决前,不要把 smoke 失败直接归因到单实例代码本身
## 下次继续时先做什么
优先顺序:
1. 先清掉所有残留 `electron.exe`
2. 再确认 `Get-Process electron -ErrorAction SilentlyContinue` 没有输出
3. 再跑单实例 smoke
4. 若 smoke 仍失败,再根据 `.tmp` 里的 trace/log 继续定位
推荐命令:
```powershell
Get-Process electron -ErrorAction SilentlyContinue
```
如果仍杀不掉,直接重启机器。
重启或清理完成后先跑:
```powershell
corepack pnpm smoke:desktop-single-instance
```
如果还失败,再补跑:
```powershell
powershell -ExecutionPolicy Bypass -File build/scripts/startup-binding-smoke.ps1
```
目的:
- `desktop-single-instance-smoke` 用来验证单实例口径本身
- `startup-binding-smoke` 用来判断是不是更基础的桌面启动链路也有问题
## 继续排查时要看的文件
- `D:\qjclaw\apps\desktop\src\main\index.ts`
- `D:\qjclaw\build\scripts\desktop-single-instance-smoke.ps1`
- `D:\qjclaw\package.json`
- `D:\qjclaw\build\scripts\README.md`
失败时优先看:
- `D:\qjclaw\.tmp\desktop-single-instance-smoke\result.json`
- `D:\qjclaw\.tmp\desktop-single-instance-smoke\result.json.trace.log`
- `D:\qjclaw\.tmp\desktop-single-instance-smoke\logs\startup\startup-latest.log`
- `D:\qjclaw\.tmp\desktop-single-instance-smoke\logs\runtime-manager.log`
## 当前工作区事实
和这次单实例相关的工作区改动包括:
- `apps/desktop/src/main/index.ts`
- `build/scripts/desktop-single-instance-smoke.ps1`
- `package.json`
- `build/scripts/README.md`
其中:
- `build/scripts/desktop-single-instance-smoke.ps1` 当前是新增文件
- 其余几个文件已有未提交改动
## 一句话结论
单实例代码和 smoke 脚本已经落地,`typecheck` 已通过;下次续接前先解决本机残留的高权限 `electron.exe`,否则自动验证不会有可信结果。
## 2026-04-21 最新进展补充
### 本轮已继续完成的代码侧工作
- `apps/desktop/src/main/index.ts`
- 已把单实例入口继续接完整:
- `app.requestSingleInstanceLock()`
- `second-instance` 接管并聚焦现有主窗口
- `mainWindow` 跟踪
- `focusMainWindow()`
- `restoreOrCreateMainWindow()`
- `createTrackedMainWindow()`
- 已补单实例 smoke 专用信号:
- `QJCLAW_SMOKE_SINGLE_INSTANCE`
- `QJCLAW_SMOKE_SINGLE_INSTANCE_READY_PATH`
- `QJCLAW_SMOKE_SINGLE_INSTANCE_EVENT_PATH`
- `runSingleInstanceSmoke()`
- 已补窗口状态与日志辅助信息:
- `secondInstanceEventCount`
- `lastSecondInstanceEventSnapshot`
- `mainWindowLoadState`
- `window.load-state` 启动日志
- 已在 smoke 模式下加:
- `app.disableHardwareAcceleration()`
- `build/scripts/desktop-single-instance-smoke.ps1`
- 已去掉对 `Start-Process` 返回 PID 的“提前失败”判断
- 现在不会因为 Electron 首个 PID 变化而误判首实例退出
### 本轮已执行的验证
已执行并通过:
```powershell
corepack pnpm --filter @qjclaw/desktop build
```
```powershell
corepack pnpm typecheck
```
已执行但失败:
```powershell
corepack pnpm smoke:desktop-single-instance
```
```powershell
powershell -ExecutionPolicy Bypass -File build/scripts/startup-binding-smoke.ps1
```
### 关键新结论
- 当前问题已经不能再只归因到“单实例 smoke 本身”
- `startup-binding-smoke` 也失败了,说明更底层的桌面启动链路本身就不稳定
- `startup-binding-smoke` 的失败点是:
- Electron 还没写出 smoke output 就退出了
- 退出码是 `-2147483645`
- `desktop-single-instance-smoke` 仍然失败,但现在可以确认:
- 不再是脚本盯着首个 PID 导致的误判
- 更像是首实例窗口/渲染链路没稳定进入可用状态
### 这轮看到的最关键日志现象
- 单实例 smoke 的 trace 只走到:
- `runSingleInstanceSmoke:start`
- 基础启动 smoke 的 trace 走到:
- `runSmokeTest:start`
- `runSmokeTest:renderer-loading`
- `runSmokeTest:loading-renderer-state`
- `startup-latest.log` 里,主窗口 load-state 目前只看到:
- `created`
- 没有继续看到:
- `did-start-loading`
- `dom-ready`
- `did-finish-load`
- `did-fail-load`
- `render-process-gone`
这说明:
- 主窗口创建是发生了的
- 但后续页面加载事件没有稳定落到日志里
- 现象更接近 Electron / Chromium 级别的启动异常或系统态残留干扰
### 运行时相关补充观察
- `runtime-manager.log` 里持续可见:
- `Launching bundled runtime command`
- `Bundled runtime direct spawn was blocked with EPERM; retrying via PowerShell wrapper.`
- `Bundled runtime failed to spawn: spawn EPERM`
这不是本轮唯一问题,但说明当前环境里还有额外权限限制噪音,不能把 smoke 失败简单归因到单实例代码。
### 当前机器状态的新结论
当前机器上确认有一颗高权限残留 `electron.exe`
- PID:`7216`
- Parent PID:`12892`
- 但父进程已经不存在
- `Get-Process` 结果里:
- `HandleCount = 0`
- `Path` 为空
- `StartTime = 2026/4/21 15:30:31`
已尝试但仍失败:
```powershell
taskkill /PID 7216 /F /T
```
```powershell
Stop-Process -Id 7216 -Force
```
以及通过 `schtasks``SYSTEM` 身份触发 `taskkill`
当前判断:
- 这颗进程已经接近“残留/僵尸进程”
- 继续在当前系统态下跑 smoke,结果不可信
- 最稳妥做法仍然是先重启机器
### 更新后的下次继续顺序
1. 先重启机器,清掉 PID `7216`
2. 重启后先确认:
```powershell
Get-Process electron -ErrorAction SilentlyContinue
```
3. 如果没有输出,先跑:
```powershell
powershell -ExecutionPolicy Bypass -File build/scripts/startup-binding-smoke.ps1
```
4. 如果基础启动 smoke 通过,再跑:
```powershell
corepack pnpm smoke:desktop-single-instance
```
5. 如果基础启动 smoke 仍失败,优先看:
- `D:\qjclaw\.tmp\startup-binding-smoke\result.json`
- `D:\qjclaw\.tmp\startup-binding-smoke\result.json.trace.log`
- `D:\qjclaw\.tmp\startup-binding-smoke\logs\startup\startup-latest.log`
- `D:\qjclaw\.tmp\startup-binding-smoke\logs\runtime-manager.log`
### 当前这轮最准确的一句话结论
单实例代码和单实例 smoke 已继续补强,但新的验证结果表明当前主要阻塞已经下沉到更底层的 Electron 启动链路与机器残留进程状态;在重启清掉高权限残留 `electron.exe` 之前,继续跑 smoke 不会有可信结果。
# 2026-04-24 抖音客户端配置接入进度
## 2026-04-25 当前状态
截至 2026-04-25,抖音项目这一轮的主结论如下:
- 客户端真实配置注入链路已打通,运行时以客户端配置为主口径
- `workspace_entry.py` 的 pending intake / continue 主链路已恢复到可验证状态
- `VectCut` 已从本轮阻断项中移除,不再作为抖音运行时必填
- 客户端聊天附件入口已从“仅图片”扩展为“图片 + 通用资料文件”
- PDF 附件已在桌面 smoke 中完成真实落盘验证
当前更准确的表述不是“只差 UI 验收”,而是:
- 配置接入、运行时注入、pending intake 回归、通用附件上传已经完成并有验证
- 下一阶段仍然是客户端真实聊天验收
## 本轮新增完成项
### 1. 客户端真实配置接入
- 客户端设置保存后,抖音项目运行时改为从客户端配置注入 `project.env`
- `QJC_CLIENT_CONFIG_ACTIVE=1` 已在 smoke 中确认
- 抖音相关模型配置已覆盖:
- `VIDEO_LLM_ANALYZER_*`
- `REPLICATION_BRIEF_*`
- `SEEDANCE_*`
- `VOLC_*`
- `QINIU_*`
- `VectCut` 不再是本轮闭环前置阻断项
### 2. Pending Intake 回归修复已稳定
- `run_intake()` 已恢复为可调用主路径
- `workspace_entry.py` 的 pending intake / continue 逻辑已重新验证
- 当前不再继续主动改 `run_from_request.py` / `coordinator.py` 主业务编排
### 3. 客户端通用附件上传已接入
- 共享类型 `ChatAttachment.kind` 已从仅 `image` 扩展为 `image | file`
- 桌面端新增统一附件选择接口 `pickAttachments()`
- 当前聊天附件支持:
- 图片:`png/jpg/jpeg/webp/gif/bmp`
- 文档资料:`pdf/ppt/pptx/xls/xlsx/csv/tsv/doc/docx/txt/md/json`
- 图片继续落到 `inputs/images/main`
- 文档资料落到 `inputs/assets/manual`
- 聊天输入支持多附件发送
### 4. PDF 真实样本 smoke 已通过
本轮使用以下真实样本完成验证:
- `C:\Users\EDY\Desktop\douyin-example\2025欧文酵室招商手册(1).pdf`
已确认的事实:
- smoke 中附件类型为 `file`
- PDF 被真实落盘到项目目录:
- `projects/douyin/inputs/assets/manual/...pdf`
- assistant 回复中已包含 `Project attachments:` 回显
- 说明附件没有停留在 UI 层,而是实际进入了抖音项目工作区
## 已完成范围
- 客户端抖音模型配置读写、保存、注入
- 抖音运行时 `project.env` 注入
- `workspace_entry.py` 的 pending intake / continue 适配
- `run_intake()` 回归修复
- `VectCut` 非阻断化
- 客户端聊天附件从“仅图片”扩展到“通用资料文件”
- PDF 资料落盘到 `inputs/assets/manual`
- smoke 对真实配置和真实 PDF 的验证
## 当前未完成范围
- Pending Intake UI 手工闭环验收
- 三条业务链路聊天闭环验收
- OmniHuman / Seedance 聊天闭环验收
- 验收过程中暴露问题后的针对性回修
## 下一步顺序
1. Pending Intake UI 闭环验收
2. `research_replication + crawler``specified_sample + link``direct_creation + none` 三条链路聊天闭环验收
3. OmniHuman / Seedance 聊天闭环验收
4. 若验收暴露问题,再做最小范围回修
## 边界
- 不主动重写 `run_from_request.py` 三条主链路逻辑
- 不主动重写 `coordinator.py` 主业务编排
- `VectCut` 继续排除在本轮主线通过门槛之外
## 验证记录
- 2026-04-25:`python workspace/douyin/test_intake_integration.py` 28/28 通过
- 2026-04-25:`python workspace/douyin/test_pending_intake.py` 68/68 通过
- 2026-04-25:`corepack pnpm typecheck` 通过
- 2026-04-25:`corepack pnpm build` 通过
- 2026-04-25:`build/scripts/douyin-expert-cloud-bundle-smoke.ps1 -SettingsConfigPath "C:\Users\EDY\Desktop\龙虾密钥&模型配置信息.txt" -AttachmentFixturePath "C:\Users\EDY\Desktop\douyin-example\2025欧文酵室招商手册(1).pdf" -SkipMaterializeRuntime`
- 真实配置注入通过
- PDF 附件落盘通过
- assistant `Project attachments:` 回显通过
- 首次运行仍偶发 `Gateway connection closed (1012)`,重试后通过
## 2026-04-26 最新进度
### 已验证通过
- 客户端真实聊天链路中,上传 PDF 并描述需求后,可以走通纯画面 Seedance 视频生成。
- 已修复 Seedance split 最终视频 0 秒 / 缺音轨问题:
- `run_pipeline.py` 在无 `ffprobe` 时改用 `ffmpeg -i` 兜底解析媒体时长。
- audio compose 前后增加最终产物校验,避免 0 秒视频被写成 success。
- `workspace_entry.py` 已支持读取 `results.video_seedance.manifest` 内的嵌套最终视频字段,并在必要时用 `final_video_concat.mp4 + narration_audio_path` 兜底重新 mux。
- 已用坏产物目录验证修复:
- `E:\testworkspace2\projects\douyin\output\招商\seedance-split-runs\20260426-184026`
- 修复后 `final_video.mp4` 时长约 30 秒,包含视频流和音频流。
- `latest_seedance_split.mp4` 已同步更新。
- `D:\qjclaw\workspace\douyin` 已重新打包上传到云端配置。
- 本地开发版客户端已重启,`5173` 和内置网关 `18889` 正常监听。
### 当前仍有问题
- 数字人口播链路仍待排查。
- 上传音频 + 数字人图片生成链路仍待排查。
- 输入抖音链接并走样本/复刻相关链路仍待排查。
- Seedance 平台返回 `OutputVideoSensitiveContentDetected` 时,目前按平台拒绝生成处理,只提示用户调整需求,不做自动改写 prompt。
### 下一步建议
1. 先验证数字人口播:确认音频、数字人图片、模型配置、输出目录和失败日志。
2. 再验证“传音频 + 数字人图片”链路:区分是附件落盘、参数传递、OmniHuman 调用还是后处理失败。
3. 最后验证抖音链接链路:重点看 crawler/downloader/analyzer/selected sample continue 是否在客户端聊天里闭环。
\ No newline at end of file
# Desktop Startup Handoff (2026-04-07)
## Goal
排查并优化 Windows 安装包首启卡在“正在同步员工配置”的问题,重点处理两件事:
1. 修正启动状态汇总,避免把真实错误或后续阶段统一显示成“正在同步员工配置”
2. 增加首启结构化日志和更完整的 diagnostics 信息,便于现场机器定位卡点
## Current Status
当前不是完成态,但主体改动已经做了大半。
已完成:
- 主进程接入 startup logger 基础能力
- diagnostics 导出内容增强
- workspace summary 逻辑已改,新增 `syncing-projects` 阶段,避免“无项目”覆盖真实错误
- UI 已做最小配套修改:
- 支持 `syncing-projects`
- 导出 diagnostics 后显示 `startupLogPath`
- 启动错误遮罩上增加“导出诊断”按钮
未完成:
- 当前还没跑通整仓 typecheck
- 还没跑桌面端/安装包首启验证
- 日志点已接入到部分关键服务,但还没有做完整的 installer 现场回归
## Current Blocker
最新一次整仓类型检查:
```powershell
$env:COREPACK_HOME='D:\qjclaw\.corepack'; corepack pnpm typecheck
```
结果:
- `packages/shared-types` 通过
- `packages/gateway-client` 通过
- `apps/ui` 失败
当前唯一已确认报错:
- `apps/ui/src/App.tsx:969`
- `nextWorkspace` is possibly `null`
对应代码附近逻辑是启动轮询里的:
```ts
const nextWorkspace = await refresh(false);
const nextShouldPoll = Boolean(nextWorkspace) && (
nextWorkspace.chatLaunchState === "starting"
|| (!nextWorkspace.shellReady && nextWorkspace.bindingRequired)
);
```
这里需要把 `nextWorkspace` 收窄后再访问字段。
## Files Changed For This Task
确认与本任务直接相关的文件:
- `apps/desktop/src/main/index.ts`
- `apps/desktop/src/main/ipc.ts`
- `apps/desktop/src/main/services/cloud-api.ts`
- `apps/desktop/src/main/services/diagnostics.ts`
- `apps/desktop/src/main/services/project-bundle.ts`
- `apps/desktop/src/main/services/startup-logger.ts`
- `packages/shared-types/src/index.ts`
- `apps/ui/src/App.tsx`
## Important Functional Changes
### 1. New startup logger
新增:
- `apps/desktop/src/main/services/startup-logger.ts`
作用:
-`<logsPath>/startup/` 写 JSONL 风格首启日志
- 生成会话日志和 latest 日志
- 对 token / api key / password / URL 做基本脱敏
### 2. Shared types updated
`packages/shared-types/src/index.ts` 已添加:
- `WorkspaceStartupPhase` 新值:`syncing-projects`
- `DiagnosticsExportResult.startupLogPath?: string`
### 3. Diagnostics export enhanced
`apps/desktop/src/main/services/diagnostics.ts` 当前已支持导出更多现场信息:
- `workspaceSummary`
- `bundleSyncStatus`
- `startupLogPath`
- `reason`
并通过 `startupLogger` 写 diagnostics 导出记录。
### 4. Workspace summary fix
`apps/desktop/src/main/ipc.ts` 是本次最关键的修复点。
当前逻辑已经改成:
- `error` 不再被“无项目”覆盖
- 当 runtime cloud ready 但还没有项目时,进入 `syncing-projects`
- 如果 bundle sync 失败,返回明确错误 summary
- summary 变化会写 startup logger
- diagnostics export 时会附带 startup log path / workspace summary / bundle sync status
这部分是本次修复“首页闪一下又被‘正在同步员工配置’盖回去”的核心。
### 5. Index / service wiring
`apps/desktop/src/main/index.ts` 已做的事情:
- 创建 `startupLogger`
- 注入 `DiagnosticsService`
- 注入 `OpenClawConfigClient`
- 注入 `ProjectBundleService`
- 注入 `registerDesktopIpc`
`cloud-api.ts` / `project-bundle.ts` 已开始接入 logger,但后续仍建议在类型检查通过后再补一次日志点覆盖率检查。
### 6. UI minimal support
`apps/ui/src/App.tsx` 当前的目标性修改只有这些:
- `startupCurtainCopy.syncingProjects`
- `getStartupProgress()` 支持 `syncing-projects`
- `getStartupCurtainStatus()` 支持 `syncing-projects`
- diagnostics 成功提示里包含 `startupLogPath`
- 启动错误遮罩新增 diagnostics 导出按钮
## Other Dirty Files In Worktree
当前 `git diff --name-only` 里还有这些未提交改动:
- `apps/desktop/src/main/services/project-store.ts`
- `apps/desktop/src/preload/index.ts`
- `apps/ui/src/styles.css`
- `build/scripts/electron-smoke.ps1`
这些不在我本次“启动日志/状态机”主线修改的核心列表里,可能是已有改动或其他任务改动。
如果另一个 AI 要继续本任务,不要默认回退这些文件。
## Whether This Affects Another Task
会不会影响,取决于另一个任务改哪些文件。
影响较小的情况:
- 另一个任务不改下列文件:
- `apps/desktop/src/main/index.ts`
- `apps/desktop/src/main/ipc.ts`
- `apps/desktop/src/main/services/cloud-api.ts`
- `apps/desktop/src/main/services/diagnostics.ts`
- `apps/desktop/src/main/services/project-bundle.ts`
- `apps/ui/src/App.tsx`
- `packages/shared-types/src/index.ts`
容易冲突的情况:
- 另一个任务要改 `App.tsx`
- 另一个任务要改 desktop main 启动链路
- 另一个任务要改 diagnostics / preload / shared-types IPC 类型
所以如果你只是临时切去改完全无关模块,通常问题不大;如果另一个任务也碰启动、UI 主壳、共享类型或 preload,冲突概率就高。
## Recommended Pause Strategy
如果要先切走做别的任务,建议:
1. 不要继续在当前改动基础上随手混改启动相关文件
2. 让另一个任务尽量避开本任务相关文件
3. 如果另一个 AI 要继续本任务,先读本文件,再跑一次 typecheck,从 UI 的 nullability 报错开始收尾
## Recommended Next Steps For The Next AI
1. 修复 `apps/ui/src/App.tsx:969` 的空值收窄问题
2. 重新运行:
```powershell
$env:COREPACK_HOME='D:\qjclaw\.corepack'; corepack pnpm typecheck
```
3. 如果 typecheck 继续报主进程相关错误,再逐个修:
- `index.ts`
- `cloud-api.ts`
- `project-bundle.ts`
- `ipc.ts`
4. typecheck 通过后,验证桌面端:
- 启动阶段文案是否出现 `syncing-projects`
- diagnostics 导出是否返回 `startupLogPath`
- 启动错误遮罩是否能导出日志
5. 再做安装包/首启验证,重点看是否能区分:
- 员工配置请求失败
- 项目 bundle 同步失败
- runtime 启动失败
- gateway 连接失败
- summary 被覆盖
## Useful Commands
查看工作区变更:
```powershell
git -c safe.directory=D:/qjclaw diff --name-only
```
重新看 UI 变更:
```powershell
git -c safe.directory=D:/qjclaw diff -- apps/ui/src/App.tsx
```
重新跑类型检查:
```powershell
$env:COREPACK_HOME='D:\qjclaw\.corepack'; corepack pnpm typecheck
```
## Notes
- 这个仓库当前在 Windows 环境下,且 `D:\qjclaw` 需要按 safe.directory 方式使用 git
- 我这轮没有做 destructive revert
- 当前最重要的是先保持工作区稳定,不要在 `App.tsx` 上再叠加大改
\ No newline at end of file
This diff is collapsed.
# 安装包瘦身回滚计划
## 当前结论
上一轮回滚不合格:它删除了 runtime cleanup,导致新安装包变成完整 payload,体积超过最近可用备份包。
- 最近可用基线:`dist/installer/backup/千匠问天-20260430-164341.exe`
- 基线大小:`538,315,023 bytes`
- 回滚后的异常包:`dist/installer/千匠问天-Setup-0.1.0.exe`
- 异常包大小:`596,924,319 bytes`
- 增量:`58,609,296 bytes`,约 `55.9 MiB`
## 回滚原则
瘦身失败时,必须回到最近可用小包基线,不能回到更大的完整 runtime payload。
允许保留:
- `ffmpeg/bin/ffmpeg.exe`
- `ffmpeg/bin/ffprobe.exe`
- `playwright-browsers/`
- 当前 runtime 必需 Python 依赖
必须恢复:
- runtime payload cleanup
- cleanup 统计写入 manifest
- OpenClaw docs 裁剪但保留 workspace templates
- Python tests、cache、pyc/pyo、source map 等无运行价值文件清理
## 修正方式
1. 恢复 `build/scripts/materialize-runtime-payload.ps1` 中 cleanup 相关逻辑。
2. 确认 `materializationInputs.schemaVersion` 回到 cleanup 对应版本。
3. 不修改 `apps/desktop/electron-builder.yml`,当前 `compression: store` 是既有状态。
4. 删除并重新生成 runtime payload。
5. 重新打包。
6. 对比新包大小,必须不大于 `538,315,023 bytes`
## 验证命令
```powershell
corepack pnpm materialize:runtime
corepack pnpm package
corepack pnpm typecheck
corepack pnpm smoke:ffmpeg-runtime
```
必要时再运行:
```powershell
corepack pnpm smoke:installer
```
## 接受标准
- `vendor/openclaw-runtime/runtime-manifest.json` 包含 `cleanupSummary``payloadStats`
- 新安装包大小 `<= 538,315,023 bytes`
- `ffmpeg.exe``ffprobe.exe` 仍在 runtime payload 中。
- 抖音视频/ffprobe 相关 smoke 不因瘦身缺少二进制而失败。
## 失败处理
如果新包仍然大于基线,不继续扩大回滚范围;先分析 manifest 的 `topLevelBreakdown``payloadStats`,定位新增体积来源后再补充 cleanup 规则。
# 左侧栏数字员工树形目录与 13/14 寸适配计划
## Summary
在不改业务逻辑的前提下,重构客户端左侧栏的信息密度和响应式表现。目标是:删除顶部 logo 品牌块,让导航和新建对话整体上移;把新建对话下方的专家区改成固定高度的“数字员工”树形目录;同时保持当前蓝紫玻璃质感、浅色渐变、圆角卡片、细描边的原 有
风格,不引入突兀的新视觉语言。
## Design Direction
- 延续现有风格:
- 保留浅色玻璃背景、蓝紫边框、柔和渐变、圆角卡片、轻阴影。
- 不改成纯扁平黑白,也不引入强烈新配色。
- 树形目录使用当前已有的紫蓝高亮、浅底卡片、细滚动条。
- 降低突兀感:
- 分类行高度、字体、圆角接近现有 `nav-item``sidebar-session-card`
- 展开专家项使用现有专家 SVG 图标体系,不用 emoji。
- 动效只保留 150–200ms 的颜色/箭头旋转,不做明显弹层或位移动画。
- 信息层级:
- 顶部:主导航 + 新建对话。
- 中部固定块:标题 `数字员工` + 树形分类。
- 底部弹性块:会话列表。
## Key Changes
- `App.tsx` 结构调整:
- 删除 `<div className="sidebar-logo-block">...千匠问天...</div>`
- 保留 `nav-list``sidebarNewSessionAction` 原 class,避免影响自动化。
-`sidebar-experts-entry` 内新增标题栏:
- 左侧文字:`数字员工`
- 可选右侧轻量计数:专家总数,例如 `8`
- 当前 `CATEGORY_CONFIG` 保留分类 id/name,但移除 emoji icon 依赖。
- 分类头从 `<div onClick>` 改为 `<button type="button">`
- 专家项从 `<div onClick>` 改为 `<button type="button">`
- 展开内容改为行内树结构,不再使用绝对定位弹出层。
- 树形目录行为:
- 点击“内容营销”展开其专家列表,再点收起。
- 点击专家后继续调用现有 `handleExpertSelect(entry)`
- 点击专家后仍关闭所有展开分类,沿用当前 `setExpandedCategories({})` 行为。
- 空分类不展示展开内容;分类行仍显示但可禁用或显示 `0`,推荐显示但禁用展开。
- 样式调整:
- `.sidebar` 改为响应式宽度:`clamp(232px, 19vw, 280px)`
- 删除 logo 后缩小 `.sidebar-top` 的 gap 和顶部 padding,让“对话”区域自然上移。
- `.sidebar-experts-entry` 固定高度:
- 普通桌面:约 `280px`
- 13/14 寸紧凑屏:约 `220–240px`
- `.sidebar-expert-scroll` 只在数字员工块内部滚动:
- `overflow-y: auto`
- `overflow-x: hidden`
- 透明/细滚动条
- `.sidebar-session-section` 保持 `minmax(0, 1fr)`,吃掉剩余高度。
- 13/14 寸适配:
- 增加紧凑断点,推荐条件:
- `@media (max-width: 1440px), (max-height: 820px)`
- 紧凑模式压缩:
- sidebar padding:从约 `24px/16px` 降到 `14–16px/12px`
- nav-item 高度:从 `44px` 降到 `38–40px`
- 新建对话高度:从 `46px` 降到 `40px`
- 数字员工块 padding/gap 下降 2–4px
- 会话卡片高度和间距轻微下降
- 保证主工作区仍使用 `minmax(0, 1fr)`,不产生横向滚动。
- `switchExpert`
- `activateHomeShortcut`
- `openHomeChat`
- `nav-item`
- `conversation-new-session`
- `sidebar-new-session`
- `sidebar-digital-workers-title`
- `expert-tree-list`
- `expert-tree-category`
- `expert-tree-category-trigger`
- `expert-tree-expert`
## Risk Points
- `styles.css` 里侧栏样式重复较多,后面的 `.conversation-shell ...` 规则优先级更高,实际改动应放在后段生效区,避免被覆盖。
- 删除 logo 后,侧栏顶部高度会明显变化,需要检查窗口拖拽区域是否仍可用。
- 固定数字员工高度可能挤压会话列表,必须在 `1366×768` 检查。
- 分类匹配目前依赖正则识别专家 id/name,新增专家可能落到“其他专家”。
- 不要删除核心 DOM class,否则 smoke helper 或自动化选择器可能失效。
- 当前有残留 Electron 进程 PID `32180` 曾拒绝结束,后续跑 smoke 前需确认不会干扰测试。
## Test Plan
- 静态验证:
- `corepack pnpm typecheck`
- `corepack pnpm build`
- 手动视觉检查:
- `1366×768`:13 寸常见低高屏,重点看是否挤压、是否横向滚动。
- `1440×900`:14 寸常见比例。
- `1536×864`:Windows 缩放常见工作区。
- `1920×1080`:标准桌面。
- 功能检查:
- “对话 / 数字员工 / 知识库 / 插件 / 设置”可切换。
- “新对话”可点击。
- “数字员工”标题存在。
- 点击“内容营销”展开专家。
- 点击专家后仍进入对应专家或填入快捷 prompt。
- 会话列表可滚动、切换、关闭。
- 数字员工块内部滚动,不影响整页布局。
- UI 验收:
- 无 logo 和“千匠问天”品牌块。
- 导航和新建对话明显上移。
- 树形目录不浮层遮挡。
- 样式与现有蓝紫玻璃风一致。
- 无横向滚动。
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
报错:
这个是通过上传pdf生成纯画面视频报错:
[ERROR] Generate Seedance split video failed with exit code 1. See E:\testworkspace2\projects\douyin\output\分析一下这个文件\video_seedance_stderr.txt | split_error=Seedance clip 1 failed. See E:\testworkspace2\projects\douyin\output\分析一下这个文件\seedance-split-runs\20260427-095752\shots\shot-01\stderr.txt
=== Douyin Master Workflow ===
Route: 直出创作链
Source mode: 不走样本调研
Core keyword: 分析一下这个文件
Product: 分析一下这个文件
Audience: 加盟创业人群
Type: 纯画面视频
Normalized type: 纯画面视频
Writer type: 知识干货
Requested video engine: auto
Project folder: 分析一下这个文件
Attempt id: 20260427-095748-052712
Output dir: E:\testworkspace2\projects\douyin\output\分析一下这个文件
Direct image Seedance mode: True
Detected image-driven Seedance request without narration; skip preview copywriting stage.
[status] preview_packaging | 33%(2/6) | 文案生成 | 正在整理预览文件
Resolved video engine: seedance
[status] video_seedance | 67%(4/6) | 视频生成 | Generate Seedance split video
[video_seedance] Generate Seedance split video
[status] video_seedance | 67%(4/6) | 视频生成 | Generate Seedance split video 失败
这个是给抖音链接数字人口播视频报错:
修复抖音工作流两个失败:抖音下载器 + Seedance PDF 图片格式 nage
Context
用户运行了两个抖音工作流任务,分别在不同阶段失败:
1. 宣传一下我家面包店 — 在 "样本准备" 阶段失败,douyin downloader 无法下载抖音视频
2. 分析一下这个文件 — 在 "视频生成" 阶段失败,Seedance API 返回 InvalidParameter.UnsupportedImageFormat,因为 PDF 文件被当作参考图传入了只支持 JPG/PNG/WebP 的 API
错误 1:抖音视频下载失败
- 错误: Error: Unable to parse video detail from page; fallback failed:
- 位置: E:\testworkspace2\projects\douyin\skills\douyin-video-downloader\scripts\douyin.js + run_downloader.py
- 原因: Node.js 解析器和 Playwright 备用方案都无法从抖音页面提取视频信息。可能是抖音 HTML 结构变化或反爬措施
错误 2:Seedance PDF 作为图片传入 API
- 错误: Seedance create task failed with HTTP 400. InvalidParameter.UnsupportedImageFormat
- API 请求中的问题 URL: http://tcwwu6wg4.hd-bkt.clouddn.com/omnihuman/reference-image/...pdf
- 根因链:
a. 用户上传了 PDF 文件(2025欧文酵室招商手册(1).pdf)
b. coordinator.py:5486 — 当 seedance_image 为空时,回退使用 self.config.image(即 PDF 路径)
c. coordinator.py:11286 — resolved_seedance_image = self.config.seedance_image or self.config.image
d. 该 PDF 被上传到七牛,但保留 .pdf 扩展名
e. run_seedance.py:normalize_media_input() — 对远程 URL 不做格式验证,直接传入 API
f. Seedance API 拒绝 PDF 格式
修复方案
Fix 1:Seedance 图片格式校验(高优先)
文件: E:\testworkspace2\projects\douyin\skills\douyin-master\scripts\coordinator.py
在 materialize_project_inputs() 方法中(约 line 5399),当 seedance_image 回退到 self.config.image 时,检查文件是否为 Seedance 支持的图片格式。如果是 PDF,则改用 asset_understanding 提取的图片(已有 extracted_images/ 目录,包含从 PDF
提取的 JPG 页面图)。
具体改动:
- 在 line 5484-5487(seedance_image 回退逻辑)之前,添加 PDF 检测:
- 如果 self.config.image 以 .pdf 结尾,查找 asset_understanding/extracted_images/ 下的 JPG 文件
- 使用第一个提取的 JPG 作为 seedance_image
- 如果没有提取图片,保持 seedance_image 为空(让 Seedance 用 prompt 生成首帧图)
同时在 run_seedance.py 的 normalize_media_input() 中添加远程 URL 格式校验(防御性修复):
- 对 media_kind == "image" 的远程 URL,检查扩展名是否为 .jpg/.jpeg/.png/.webp
- 不支持的格式直接跳过(不做 reference),而不是让 API 400 报错
Fix 2:抖音下载器(低优先,需更多调查)
文件: E:\testworkspace2\projects\douyin\skills\douyin-video-downloader\scripts\douyin.js + run_downloader.py
抖音下载器失败是外部依赖问题(抖音反爬/HTML结构变化),需要:
1. 手动测试 douyin.js 能否用新 URL 正常工作
2. 检查 Playwright 浏览器是否正确安装(vendor/openclaw-runtime/ 内的 Chromium)
3. 可能需要更新解析器适配抖音新页面结构
这个修复比较复杂且涉及第三方网站变化,建议先手动下载视频作为替代方案。
关键文件(源码在 D:\qjclaw\workspace\douyin\,运行时副本在 E:\testworkspace2\projects\douyin\)
- D:\qjclaw\workspace\douyin\skills\douyin-master\scripts\coordinator.py — 主要修复点:PDF→JPG 回退逻辑
- D:\qjclaw\workspace\douyin\skills\seedance-2-0-video-generator\scripts\run_seedance.py — 防御性修复:远程 URL 格式校验
- D:\qjclaw\workspace\douyin\skills\douyin-asset-understanding\ — PDF 图片提取(已有功能,直接复用)
修改源码后,需要重新打包 zip 上传到云端或本地替换,让工作流使用修复后的代码。
验证
1. 修改 coordinator.py 后,重新提交一个带 PDF 附件的抖音任务,确认 Seedance 使用提取的 JPG 而非 PDF
2. 检查 task_create.json 中的 image_url 不再包含 .pdf 扩展名
3. 确认 Seedance API 返回成功(HTTP 200/201)而非 400
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment