@leviyuan/lodestar 0.17.1 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -171
- package/dist/dsh-bridge.js +30 -11
- package/dist/lodestar-setup.js +13 -11
- package/dist/lodestar-stop.js +2 -2
- package/dist/lodestar-update.js +7 -4
- package/dist/lodestar-version.js +1 -1
- package/dist/lodestar.js +168 -163
- package/docs/AGENTS.md +14 -0
- package/docs/claude-agent-backend.md +135 -0
- package/docs/configuration.md +55 -0
- package/docs/dsh-testing-report.md +189 -0
- package/docs/models.md +76 -0
- package/docs/usage.md +79 -0
- package/package.json +238 -245
- package/scripts/postinstall.cjs +1 -26
package/docs/AGENTS.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# 文档维护
|
|
2
|
+
|
|
3
|
+
README 只保留项目介绍、快速开始和文档入口。详细内容按主题维护,事实以源码和测试为准。
|
|
4
|
+
|
|
5
|
+
- `configuration.md`:安装、CLI、运行目录、配置与 Agent 自动更新。
|
|
6
|
+
- `usage.md`:群内命令、会话、worktree、文件与生图、本机通知。
|
|
7
|
+
- `models.md`:账号、模型与 effort、OpenRouter 默认列表、DSH 与 GLM 接入。
|
|
8
|
+
- `claude-agent-backend.md`:后端实现、模型路由和会话行为。
|
|
9
|
+
- `dsh-testing-report.md`:注明版本与日期的历史测试记录。
|
|
10
|
+
|
|
11
|
+
- 保留 Codex、Claude、GLM、DeepSeek、OpenRouter、DeepSeek Harness 和 Claude native 的支持说明。
|
|
12
|
+
- 只写已实现的行为。删除失效接口、历史方案、重复规则和无法复现的验证结论;不另建产品规范或计划。
|
|
13
|
+
- 不记录凭据、真实 session id、群成员或本机配置。验证结果需对应实际运行的命令,不保留过期通过数。
|
|
14
|
+
- 文字变更检查引用的路径、方法和命令;伴随实现变化时按对应目录指引运行测试。
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# 后端与模型路由
|
|
2
|
+
|
|
3
|
+
Lodestar 通过 `AgentProcess` 接口连接 Codex app-server、Claude Agent SDK 和 DeepSeek Harness。`Session` 负责群会话、消息排队和卡片;具体进程类负责协议转换。主会话和委派 Agent 共用 `agent-launch.ts` 的启动入口。
|
|
4
|
+
|
|
5
|
+
## 进程与会话
|
|
6
|
+
|
|
7
|
+
| 行为 | Codex | Claude、GLM、DeepSeek、OpenRouter |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| 进程 | `codex app-server --listen stdio://`,通过 JSON-RPC 通信 | SDK `query()`,通过 `AsyncIterable<SDKUserMessage>` 连续输入 |
|
|
10
|
+
| 初始化 | 等待初始化和 thread 启动事务完成 | 首条输入才触发 `system/init`;启动时只检查早期错误 |
|
|
11
|
+
| 恢复与分叉 | `thread/list`、`thread/fork(lastTurnId)` | 同目录 transcript、`forkSession`、`resumeSessionAt` |
|
|
12
|
+
| 澄清提问 | `item/tool/requestUserInput` | `canUseTool` 中处理 `AskUserQuestion` |
|
|
13
|
+
| 主动压缩 | `thread/compact/start` | 向 streaming input 发送 `/compact`,等待 `compact_boundary` |
|
|
14
|
+
| 后台任务 | app-server collab 子 Agent 事件 | SDK `task_*` 事件 |
|
|
15
|
+
|
|
16
|
+
会话引用包含 provider、原生 session id 和 cwd。各后端分别保存恢复记录,切换后端不会共用同一段上下文。Claude fork 在首条输入前持久保存启动意图,获得新 session id 后才清除;历史会话通过原生 fork 接入新群,避免两个群写同一个会话。
|
|
17
|
+
|
|
18
|
+
主动压缩没有固定完成时限,以完成事件为准,进程退出或报错时失败。Claude 明确返回 `Not enough messages to compact` 时视为无需压缩,普通 `result` 事件不能代替完成通知。
|
|
19
|
+
|
|
20
|
+
## 账号和模型
|
|
21
|
+
|
|
22
|
+
Token Source 管理账号凭据、模型目录、启动环境、默认模型、effort 和额度。内置来源如下:
|
|
23
|
+
|
|
24
|
+
| 来源 | 配置和模型目录 |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| Codex subscription | 使用 Codex 登录态,模型来自 app-server `model/list` |
|
|
27
|
+
| GLM Coding Plan | `[token_source.glm]` 或本机 Claude settings;模型来自兼容端点,可补录已验证模型 |
|
|
28
|
+
| DeepSeek | `[token_source.deepseek]` 或本机 Claude settings;模型来自兼容端点,可补录已验证模型 |
|
|
29
|
+
| OpenRouter | `[token_source.openrouter]` 或本机 Claude settings;默认十一家各一模型,账号目录验证能力,MD 面板维护增删 |
|
|
30
|
+
| DeepSeek Harness | `[token_source.deepseek-harness]`;模型、effort 与上下文容量来自当前自动更新的 DSH 原生目录 |
|
|
31
|
+
| DSH GLM Coding Plan | `[token_source.dsh-glm]` 或复用 `glm`;账号接口返回模型,DSH 原生适配器提供能力和推理档位 |
|
|
32
|
+
| Claude native | 沿用本机 Claude 配置,目录来自 SDK `supportedModels()`;有其他已启用的 Claude 侧来源时让位 |
|
|
33
|
+
|
|
34
|
+
`model` 首页用独立的展开式折叠面板展示 Claude Code、Codex、DeepSeek Harness,模型行右侧窄按钮用单字,补录、返回和翻页等宽按钮保留完整文字。两个 Agent 下的 DeepSeek 来源都显示为 DeepSeek,协议 id 保持不变。每组使用浅蓝标题背景、蓝色边框及 `Agent · 名称` 标题,Token Source 行放在组内,避免两层名称混成同级列表;组 ID 由 `ELEMENTS.modelAgentGroup` 生成。选择账号后进入模型列表,行间加分隔线;多个档位才展示 effort 卡,只有一个档位(含原生默认)直接应用,获取失败显示 `MISS`。同 provider/source 的切换调用 `setModelSettings`:Claude 和 DSH 从后续 turn 使用,Codex 保存选择并在重启进程后应用。跨 provider/source 或需要变更项目启动配置时,只能在空闲状态更换进程。
|
|
35
|
+
|
|
36
|
+
2026-09-10 已在授权测试群验证该分组样式的真实卡片:原始结构保留 `blue-50` 标题背景、粗体 Agent 名称和 `blue-100` 边框,原有账号选择回调正常,当前模型设置未改变。
|
|
37
|
+
|
|
38
|
+
除 OpenRouter 保留默认十一项的显式列表外,所有来源由 `withModelVisibility` 在真实接口目录上应用 `hidden_models`。接口项通过显示/隐藏调整可见性,新增上游模型自动进入列表。所有来源都支持用 `custom_models` 补录列表外模型,`origin` 区分接口项和补录项;GLM / DeepSeek 会先做端点验证,补录模型可直接选择请求档位使用,DSH 原生解析目录外模型,其余来源使用 Agent 请求档位;不能用目录白名单挡住用户补录。接口收录同名模型后按接口项管理,不重复展示。
|
|
39
|
+
|
|
40
|
+
`tokenSourceRuntimeModel(s)` 使用完整能力目录,隐藏不修改会话、`model`、`effort`、slots 或启动配置指纹。`model_custom_remove` 只删除补录项,拒绝删接口项;删除前要求会话不再选用该项,并清理默认模型和 slots 的悬空引用。补录/删除和显示/隐藏均串行写配置,旧面板失效。
|
|
41
|
+
|
|
42
|
+
大模型目录每页 20 项,`model_page` 回调携带 `panel_id`、`source_id`、`page`,只使用服务端保存的目录快照并校验页码。切页后只接受当前页的模型选择;过期面板拒绝操作。
|
|
43
|
+
|
|
44
|
+
`md` 等待模型目录刷新完成后生成账号卡。刷新开始会清空能力数据,不能先取此时的空数组生成“0 个模型”卡片;失败状态显示 `MISS`,用户明确清空的就绪列表才显示零项。面板记录实际 `message_id`,在模型列表、添加目录和分页间保持一致。
|
|
45
|
+
|
|
46
|
+
活跃、续卡和结束 footer 的模型标识共用 `footerModelLabel`,固定为 `agent · 模型名/effort`,Agent id 小写,模型名剥除 `claude:`、`[1m]`;模型或 effort 缺失时显示对应的 `MISS`。footer 的窗口额度保留原格式 `4.1h·7%·[6.9d·17%]`,即重置倒计时与已用百分比,周窗口放在方括号中;不添加“额度 5h 已用”等标签或月度工具明细。结构化余额通过 `unifiedUsageSummary` 显示 `余额 $…` / `余额 ¥…`,控制台仍可展示完整窗口明细。失败明确显示 MISS。
|
|
47
|
+
|
|
48
|
+
`[claude.models.<name>].model` 保留旧 `claude:<name>` 路由的解析。账号、显示名和模型目录由 Token Source 管理;Claude 槽位映射使用账号的 `slots`。
|
|
49
|
+
|
|
50
|
+
## Claude 启动配置
|
|
51
|
+
|
|
52
|
+
GLM、DeepSeek、OpenRouter 等来源先清除冲突的 Anthropic 环境变量(含模型角色、OAuth 和云供应商选择),再注入各自凭据;默认读取 `project`、`local` settings。Claude native 沿用本机环境并读取 `user`、`project`、`local`。Token Source 指定的 settings 来源优先;未绑定 Token Source 时才使用项目 `setting_sources`。给注入凭据的来源加上 `user` 会重新引入本机 settings 中的路由。
|
|
53
|
+
|
|
54
|
+
`[projects.<name>]` 的 `cwd` 对两个后端生效;`tools`、`setting_sources`、`strict_mcp`、`load_project_mcp` 用于 Claude。主会话默认发现项目 `.mcp.json`。排除 user settings 的 Claude 会话通过 SDK 本地插件加载 daemon 管理的 Skill,安装内容统一由 `managed-skills.ts` 生成。
|
|
55
|
+
|
|
56
|
+
`[claude].bin` 可指定包装器,路径无效时启动失败。未指定时由 `resolveClaudeExecutableConfig()` 查找本机 Claude 或 SDK native binary,Windows `.cmd`/`.bat` 通过 shell shim 启动。
|
|
57
|
+
|
|
58
|
+
Claude 使用 `permissionMode: default`:普通工具在 `canUseTool` 中放行,`AskUserQuestion` 等待用户回答。不能改成 `bypassPermissions`,否则 SDK 会绕开提问回调。
|
|
59
|
+
|
|
60
|
+
## OpenRouter
|
|
61
|
+
|
|
62
|
+
- 来源 id 为 `openrouter`,通过 factory 注册 `openrouter-setup`。默认根地址 `https://openrouter.ai/api`,粘贴的 `/api/v1` 会规范成 SDK 根地址。API key 注入 `ANTHROPIC_AUTH_TOKEN`,`ANTHROPIC_API_KEY` 显式置空,模型 slug 完整透传,不自动追加 `[1m]`。
|
|
63
|
+
- 主会话和委派共用 `agent-launch.ts`,将所选模型传给 `spawnEnv`。辅助角色在进程启动时绑定所选模型,可用 `slots` 配置 opus/sonnet/haiku;主模型后续切换不改动进程启动时的辅助角色。
|
|
64
|
+
- 默认列表由 `src/openrouter-defaults.ts` 固定为 Arena Agent Labs 的 2026-09-08 前 12 家代表模型,扣除 OpenAI、Z.ai / GLM、DeepSeek 后共九项,详见[账号与模型](models.md#openrouter)。账号目录来自 `GET /api/v1/models/user`,遵循账号供应商、隐私和 guardrail 设置;过滤被排除厂商、自动路由、非文本输出、无 tools 和 `:batch` 模型。厂商排除也在启动路由和 slot 校验中执行。
|
|
65
|
+
- `modelSelection` 保存可见模型 id 和完整允许候选;`models` 只暴露面板可见项。`model_list_open` / `model_add` / `model_remove` 对应接口项显示/隐藏,服务端校验当前页、模式与配置版本。`model_custom_remove` 删除补录记录,不能用于接口项;厂商排除也应用于手动补录。
|
|
66
|
+
- `models` 未配置时使用默认十一项,空字符串表示用户主动清空,不能当作未配置。默认模型、effort、slots、Key 及相邻配置节保留;启动和 slots 按完整允许目录验证。上游不再返回的已选项显示 `unavailableReason`,不能启动,但可以删除。
|
|
67
|
+
- effort 来自 `reasoning.supported_efforts`,仅暴露 Claude SDK 支持的档位;显式 `null` 表示全部网关档位。没有 effort 选择器的模型使用 `default`,含义是请求不携带 `output_config.effort`,不代表关闭推理,选择模型后直接应用并跳过 effort 卡。其他缺失的默认档位保留 `null`,要求用户明确选择。已选榜单代表模型使用榜单明确的档位或账号目录的默认档位。
|
|
68
|
+
- Claude SDK 0.3.251 的 CLI 会为省略 effort 的自定义模型补 `high`,Fable alias 还存在启动档位固定行为。`default` 用显式启动档位解除固定,同时在真实子进程环境设置 `CLAUDE_CODE_EFFORT_LEVEL=unset`;已抓取实际请求验证不发送 effort。`settings.env` 不能替代真实环境,单纯省略选项也不成立。显式 `max` 通过 `effortLevel: 'max'` 下发,不能映射成 `ultracode`。
|
|
69
|
+
- `modelEnvironmentRevision` 参与进程配置比较。`default` 与显式档位之间切换需要新进程环境,Session 在空闲时保存并恢复原生 session;相同模式继续走 `setModelSettings`。slots 不能混合两种参数模式,避免辅助任务继承不适用的环境。模型切换不触发 daemon 重启。
|
|
70
|
+
- 余额直接来自 `GET /api/v1/credits`:`total_credits - total_usage`,USD。2026-09-10 使用现有推理 Key 实测返回 200,不根据文档中的管理 Key 说明预先拒绝请求。权限以实际 HTTP 结果为准;失败显示 `余额 MISS`,不能改用 `/key` 限额、单 Key 累计用量或旧余额。
|
|
71
|
+
- HTTP、网络、畸形响应及无效显式配置均报告失败;目录刷新失败后清空旧能力数据,不改用公开目录或另一模型。Claude 进程禁用模型 fallback。`thinking_tokens` 转为实时估计进度,不计入真实 token 用量;空工具名记录诊断并显示 `MISS`。
|
|
72
|
+
|
|
73
|
+
接口依据:[Claude Code 接入](https://openrouter.ai/docs/cookbook/coding-agents/claude-code-integration)、[账号模型目录](https://openrouter.ai/docs/api/api-reference/models/list-models-filtered-by-user-provider-preferences-privacy-settings-and-guardrails)、[推理档位](https://openrouter.ai/docs/guides/best-practices/reasoning-tokens)、[账户余额接口](https://openrouter.ai/docs/api/api-reference/credits/get-credits)。官方兼容保证限于 Anthropic 第一方供应商,其他模型需另做真实 Agent 会话验证。
|
|
74
|
+
|
|
75
|
+
### OpenRouter 验证
|
|
76
|
+
|
|
77
|
+
2026-09-10 使用真实普通 API key 验证了九个默认模型的 Anthropic Messages 工具调用往返,并通过 Claude Agent SDK 执行 `Read`,校验随机文件内容。额外捕获请求中的 model/effort,确认实际路由和面板档位一致;无档位模型不发送 effort。
|
|
78
|
+
|
|
79
|
+
小米 `default` → Kimi `max` → 小米 `default` 的三阶段测试使用原生 resume,校验 session id 不变、上一轮随机内容保留,以及每轮实际请求参数。腾讯 Hy4 测试中出现过 429,SDK 有限重试后完成;Meta 首次请求要求年龄确认,后续直接接口和 SDK 复测均通过。这些是功能验证,未覆盖长上下文压力、所有工具或所有 OpenRouter 候选模型;本次 SDK 上报的会话窗口为 200K。
|
|
80
|
+
|
|
81
|
+
最终九模型检查通过 9/9,共核验 19 次 Messages 请求。Qwen 有 1 次工具错误,修正后返回了正确文件内容;探针报告保留 `toolErrors` 和 `httpErrorsRecovered`,不抹去中间错误。
|
|
82
|
+
|
|
83
|
+
2026-09-11 曾验证字节 Seed 2.1 Turbo、美团 LongCat 2.0、蚂蚁 Ling 3.0 Flash、阶跃 Step 3.7 Flash,SDK 实测通过 4/4,核验 8 次 Messages 请求;全部执行 Read 并返回正确随机值,三次跨模型原生 resume 保留同一会话和上一轮标记。前三项不发送 effort,阶跃发送 high。最终默认列表只追加字节和美团,蚂蚁和阶跃已移出。初测发生过目录连接中断、美团漏答上一轮标记;日志保留,明示双标记要求后复测通过。百度空路由、快手上游 400 的可用性限制见[模型说明](models.md#openrouter)。
|
|
84
|
+
|
|
85
|
+
可复现实测使用 `scripts/test-openrouter.ts`:显式提供私有 JSON 凭据文件(`api_key`)、输出目录及 `--agent-runtimes` 指向的已安装 Agent 目录,`--capture-requests` 校验实际请求,`--sequence` 验证同一会话按顺序恢复。探针只在私有临时目录操作随机文件;不连接飞书、不启动或重启 daemon。传输失败保留在报告并返回错误响应,最终失败以非零退出码报告。真实密钥、请求正文和 session id 不写入跟踪文件。
|
|
86
|
+
|
|
87
|
+
`scripts/test-model-panel-live.ts` 用已有 daemon 做群内回调测试:显式指定 `--chat-id` 和 `--extra-model`,通过权限 0600 的本机 debug socket 读取模型状态并注入有限的模型面板动作。服务端绑定已设置的群和操作用户,校验真实卡片所属群、所属应用及面板消息,再交给正常的 Card action admission、去重、群队列和呈现链路;不提供通用方法执行入口。此测试覆盖服务端回调与真实飞书消息更新,客户端点击手势另需人工或 UI 自动化验证。
|
|
88
|
+
|
|
89
|
+
该脚本会发送测试消息,核验首页分组,临时增删 OpenRouter 模型,并逐一检查其他已启用来源的隐藏、刷新和恢复;选择小米的模型默认档位验证真实回复及 footer,随后恢复原模型设置和列表。失败保留记录并尽力恢复自己产生的修改,群仍忙时拒绝强行切换。原始卡片通过 `card_msg_content_type=raw_card_content` 读取,普通消息接口的兼容文案不能用来判断 schema 2.0 实际内容。布局或协议变更后需在加载新版本的 daemon 上重跑。
|
|
90
|
+
|
|
91
|
+
2026-09-10 在加载新版代码的 daemon 上完成群内测试:六个已启用来源的首页分组、接口项隐藏/显示与刷新持久化通过;Codex、OpenRouter、DeepSeek Harness、DSH GLM 的列表外补录、MISS 展示与删除通过,GLM / DeepSeek 对无法验证的补录明确拒绝且不写入记录。OpenRouter 完成真实回复,最终 footer 正确显示模型/effort 和账户余额;测试后恢复九项列表及群内原模型。Claude native 当时未启用,其管理行为由七类来源的统一回归测试覆盖。
|
|
92
|
+
|
|
93
|
+
SDK 结果到达时卡片可能还在异步查询余额,探针需等待同一回复卡的最终 footer,再校验金额与模型信息。第一次探针提前读取导致余额断言失败,原卡稍后正常显示余额;修正等待条件后完整复测通过。`--routes-only --test-source dsh-glm --test-model glm-5.3 --test-effort high` 也已实测,确认正常群回复及 `dsh · glm-5.3/high`、额度展示,并恢复原设置。
|
|
94
|
+
|
|
95
|
+
## DeepSeek Harness 原生后端
|
|
96
|
+
|
|
97
|
+
`DshProcess` 启动自动更新到上游 `latest` 的 Node DSH 子进程,以 `sdk` profile 加载 `dsh-bridge` Cordis 插件,替换默认 SDK JSON-RPC server。Lodestar 的 stdio 协议只承载控制和事件;Agent 循环、工具执行、持久化及子 Agent 由 DSH 管理。
|
|
98
|
+
|
|
99
|
+
Agent 运行依赖由 `src/agent-updates.ts` 独立安装,daemon 启动时及每 6 小时检查 upstream latest,安装成功直接启用,旧任务继续使用各自目录。DSH 子包的 dist-tag 可能不同步,因此从主包最新版本递归读取 dependencies/peerDependencies/optionalDependencies,整族安装该次动态选中的版本。不存在兼容版本白名单;不兼容直接报告并后续适配。`dsh-bridge` 被放入选中运行目录,从同一依赖树加载,握手版本来自实际 package.json。开发依赖和 Bun 锁文件只是本地测试快照,不限制生产更新。普通安全 overrides 同时用于独立运行目录,tarball 验收真实执行更新器、包审计和原生查询。
|
|
100
|
+
|
|
101
|
+
- `session/open` 完成原生 create/resume/fork 并 flush 后才公布恢复点。`rs` 通过原生持久化服务列出同工作目录会话;`fk/bk` 使用 `turn/end` 的事件序号作为 checkpoint,原生日志验证并加载分叉历史。
|
|
102
|
+
- 实时文本来自 `agent/assistant-stream`,工具和计划来自会话事件。进入 idle 后等待持久化完成,再用真实 `turn/end` 原因结算;认证失败、token 耗尽及驱动异常均向调用方报告。
|
|
103
|
+
- 子工具返回的内容块数组先转换为后台卡摘要;不能按字符串直接处理。致命桥接错误会把未结束的子任务标记失败,并将进程退出作为异常向用户报告。
|
|
104
|
+
- 提问通过 `user-questions/request` 停驻,复用飞书问答卡;回答按原始 question id 返回。主动和自动压缩使用 DSH compaction 服务与事件。
|
|
105
|
+
- 模型与 effort 更新在下一轮应用,同一轮的工具续跑保持当前路由。`off` 是 DSH 原生推理选项。
|
|
106
|
+
- `dsh-glm` 接入 Coding Plan 的 `/api/coding/paas/v4/models` 与 `/chat/completions`。显式配置优先,否则复用已有 GLM 账号;凭据变化参与 `spawnRevision`。`dsh-runtime` 通过私有 composition patch 启用原生 `llm-pi-ai` 的 `zai-coding-cn` / `zai` 路由并关闭 DeepSeek 适配器,patch 仅记录环境变量名,不写明文 Key。
|
|
107
|
+
- GLM 可选列表来自账号接口并合并手动补录,通过 pi-ai models 配置提供请求档位,`supportsReasoningEffort` 明确启用所选档位的传递;本地安装目录未收录的新模型也能使用。`LODESTAR_DSH_*` 控制路由,跨来源先清除冲突环境,不能复用旧的 DeepSeek 凭据或默认模型。
|
|
108
|
+
- 每个进程默认读取项目 `.mcp.json` 的 stdio/HTTP MCP,并加载 `.agents/skills`、`.dsh/skills` 和 Lodestar 管理的 Skill。项目 `tools` 和 `load_project_mcp` 对 DSH 生效。
|
|
109
|
+
- 图片 MIME 由文件字节识别。飞书下载的 JPEG 可能使用 `.png` 文件名,不能据扩展名声明编码;无法识别的图片明确报错。
|
|
110
|
+
- 运行状态保存在 `src/paths.ts` 的 `DSH_HOME_DIR`。不读取用户 DSH settings 或凭据文件;`DEEPSEEK_API_KEY`、`DEEPSEEK_BASE_URL` 由选定账号显式注入。默认 telemetry 插件不加载。
|
|
111
|
+
- 委派 worker 与原生子 Agent 均禁止继续派工。主 Agent 的 Lodestar capability 通过原生 ShellEnv 按执行者注入,子 Agent 的 shell 不继承它;Agent CLI 识别这一专用上下文。
|
|
112
|
+
- 中断使用不可变原因对象,避免 Node fetch 附加 `stack` 属性后破坏 DSH 的无损 JSON 日志校验。关闭先回收 Agent,再通过协议、stdin EOF 与精确子进程终止确认退出。
|
|
113
|
+
|
|
114
|
+
需要 Node 22.19+(22.x)或 Node 24+;`[token_source.deepseek-harness].bin` 指定 Node 路径。DSH 是开发者预览版,升级依赖时须同步检查桥接协议并运行原生集成测试。`src/dsh-process.test.ts` 使用真实运行时和本地模拟模型/MCP,不连接飞书或付费 API。
|
|
115
|
+
|
|
116
|
+
2026-09-10 运行 `bun scripts/test-dsh-glm.ts`,用真实 GLM Coding Plan 的 GLM-5.3 / high 完成 Read 随机文件验证,再创建新进程通过原生 resume 复述原标记,两轮均成功且无错误。测试使用私有临时目录,不连接飞书、不控制 daemon。原生集成测试另核验了 GLM 工具往返、low → max 的实际请求参数和 resume 历史。
|
|
117
|
+
|
|
118
|
+
接口依据:[GLM Coding Plan 快速开始](https://docs.bigmodel.cn/cn/coding-plan/quick-start)、[DSH 模型供应商配置](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/guide/providers.md)。
|
|
119
|
+
|
|
120
|
+
## 共享事件和委派
|
|
121
|
+
|
|
122
|
+
`claude-agent-process.ts` 将 SDK 文本、工具、结果、用量、压缩和后台任务转换成 `AgentProcess` 事件。共享事件由 Session 和卡片消费,保留两种后端在初始化、上下文和后台任务上的差异。
|
|
123
|
+
|
|
124
|
+
委派只有一层:主 Agent 可以并行派工、回答问题和续跑原生会话,被委派的 Agent 不得继续调用其他 Agent。Skill、worker 提示词及运行时入口共同遵循该规则;worker 关闭 Codex `multi_agent` 或 Claude `Agent`/`Task`,保留其余代码工具、项目 MCP 和独立调用凭据。历史父子记录仍保留以便读取与清理。运行状态原子落盘,大段输入输出单独存放;委派会话登记后从主群的历史列表中排除。
|
|
125
|
+
|
|
126
|
+
委派卡片将整体进度放在顶部,按执行者展示结果、待回答问题和失败原因。单个 Agent 的完成结果默认展开,多个 Agent 的结果分别折叠;不展示 depth、session id 或 request id。
|
|
127
|
+
|
|
128
|
+
## 源码与验证
|
|
129
|
+
|
|
130
|
+
- 启动与协议:`src/agent-launch.ts`、`src/agent-process.ts`、`src/codex-process.ts`、`src/claude-agent-process.ts`、`src/dsh-process.ts`、`src/dsh-runtime.ts`、`src/dsh-bridge.ts`。
|
|
131
|
+
- 路由与配置:`src/token-source*.ts`、`src/session-model.ts`、`src/config.ts`、`src/claude-models.ts`。
|
|
132
|
+
- 会话分支:`src/conversation.ts`、`src/session-temp.ts`、`src/temp-session-runtime.ts`、`src/feishu.ts`。
|
|
133
|
+
- 委派:`src/agent-service.ts`、`src/agent-runner.ts`、`src/agent-session-registry.ts`。
|
|
134
|
+
|
|
135
|
+
本地检查使用 `bun run typecheck`、`bun test` 和 `bun run build`。真实后端与飞书交互需要单独指定账号、目标群和允许的副作用;历史探针结果不代表当前版本已完成线上验证。
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# 安装与配置
|
|
2
|
+
|
|
3
|
+
[返回首页](../README.md) · [模型与账号](models.md)
|
|
4
|
+
|
|
5
|
+
## 安装与运行
|
|
6
|
+
|
|
7
|
+
支持 Windows、macOS 和 Linux,需要 Node.js ≥ 18.15。Bun 用于源码开发和构建。
|
|
8
|
+
|
|
9
|
+
DeepSeek Harness 子进程另需 Node 22.19+(22.x)或 Node 24+;可通过其账号配置的 `bin` 指定 Node 可执行文件。
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm i -g @leviyuan/lodestar
|
|
13
|
+
lodestar-setup
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
向导会配置 Claude Code、可选的 GLM API key、飞书应用和项目目录,并启动 daemon;也可以同时配置 Codex 登录。Claude 按 API key 方式配置。
|
|
17
|
+
|
|
18
|
+
把机器人拉进群,群名设为 `projects_root` 下的目录名。目录不存在时会自动创建。首次消息默认使用 Claude 侧已配置的账号;发 `model` 可切换到其他账号。
|
|
19
|
+
|
|
20
|
+
安装后提供以下命令:
|
|
21
|
+
|
|
22
|
+
| 命令 | 作用 |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| `lodestar-setup` | 配置向导 |
|
|
25
|
+
| `lodestar-daemon` | 启动 daemon |
|
|
26
|
+
| `lodestar-stop` | 停止 daemon |
|
|
27
|
+
| `lodestar-update` | 升级 Lodestar 及实际使用的 Codex、Claude Code/SDK、DSH;`--agents-only` 仅立即更新 Agent |
|
|
28
|
+
| `lodestar-version` | 查看 Lodestar、实际 Agent 版本、运行目录及更新错误 |
|
|
29
|
+
| `lodestar-agent` | 由会话中的 Agent 调用其他模型执行任务 |
|
|
30
|
+
|
|
31
|
+
Codex、Claude Code/Agent SDK、DSH 默认自动跟随上游 `latest`:daemon 启动时检查一次,之后每 6 小时检查并更新。运行文件放在 Lodestar 数据目录的 `agent-runtimes/` 下,更新完成后新进程使用新版,已有任务继续使用自己的版本目录。可用 `lodestar-update --agents-only` 立即检查并更新。Agent 更新独立于 Lodestar 发版,不需要先通过兼容性验收;新版不兼容时明确报错,后续更新 Lodestar 适配。查询或安装失败不会静默使用旧安装,`lodestar-version` 可查看错误。显式配置的 `[claude].bin` 仍按该路径执行。
|
|
32
|
+
|
|
33
|
+
长期运行可交给 Linux `systemd --user`、macOS `launchd` 或 Windows 任务计划程序。daemon 重启后会恢复上次活跃的会话。
|
|
34
|
+
|
|
35
|
+
## 本机配置
|
|
36
|
+
|
|
37
|
+
默认配置文件是 `~/.config/lodestar/config.toml`,可通过 `LODESTAR_CONFIG` 指定文件。日志和会话状态位于 `~/.local/share/lodestar/`;Windows 使用相应的应用数据目录。完整路径定义见 [src/paths.ts](../src/paths.ts)。
|
|
38
|
+
|
|
39
|
+
```toml
|
|
40
|
+
[runtime]
|
|
41
|
+
projects_root = "/abs/projects"
|
|
42
|
+
live_elapsed = "bucket" # bucket 按档位刷新耗时;second 按秒刷新
|
|
43
|
+
|
|
44
|
+
[projects.calculator]
|
|
45
|
+
cwd = "/abs/projects/calculator" # 对两个后端均生效
|
|
46
|
+
setting_sources = "project" # Claude 后端;仅未绑定 Token Source 时使用
|
|
47
|
+
strict_mcp = "true" # 以下字段用于 Claude 主会话
|
|
48
|
+
load_project_mcp = "true"
|
|
49
|
+
tools = "Read,Write,Edit,Bash,Glob,Grep"
|
|
50
|
+
|
|
51
|
+
[claude]
|
|
52
|
+
bin = "/abs/path/to/claude-wrapper" # 可选的 Claude 可执行文件
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
账号配置、OpenRouter 默认模型和 DSH 接入见[模型与账号](models.md)。手动修改配置后需重启 daemon;群内设置自行保存。
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# 把 DeepSeek Harness 接进飞书:完整测试记录
|
|
2
|
+
|
|
3
|
+
版本:Lodestar 0.17.0。验收日期:2026-09-10。
|
|
4
|
+
|
|
5
|
+
这次接入把 DeepSeek Harness(DSH)作为独立原生后端:Lodestar 启动 Node 子进程,通过 stdio 桥接原生 Agent、会话、工具和提问服务,再把事件交给现有 Session 和飞书 Card Kit。原来使用 Claude 兼容接口的 DeepSeek 来源继续保留,两者各自管理账号、模型和历史。
|
|
6
|
+
|
|
7
|
+
验收分三层:可重复的本地自动化、真实 DeepSeek API、真实飞书群。测试中发现并修复了取消状态无法落盘、后台工具结果导致进程退出、图片编码误判和 setup 命令解析问题。最后由用户从飞书客户端发送图片,补齐 WebSocket 入站验证。
|
|
8
|
+
|
|
9
|
+
本报告按场景列出用例;一个自动化用例可能包含多个步骤和断言。不同层次会重复验证同一能力,因此不把所有表格行相加当作“独立测试总数”。群标识、用户身份、真实会话编号、API key、余额和原始用户图片均不包含在分享版中。
|
|
10
|
+
|
|
11
|
+
## 测试环境和方法
|
|
12
|
+
|
|
13
|
+
| 项目 | 本次使用的环境或方法 |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| 原生依赖 | `@deepseek-ai/dsh@0.1.5-alpha.2`(当次历史验收快照;当前生产策略为自动跟随 latest) |
|
|
16
|
+
| 本机运行时 | Linux、Bun 1.3.11、Node 22.22.2 |
|
|
17
|
+
| 模型 | DeepSeek-V4-Flash、DeepSeek-V4-Pro、DeepSeek-V4-Flash-Vision-Exp |
|
|
18
|
+
| 推理设置 | 真实请求覆盖 `off`、`high`、`max`;支持值仍以模型目录为准 |
|
|
19
|
+
| 本地自动化 | 真正启动 Node DSH runtime;模型接口使用本地 HTTP/SSE 服务,Shell、文件和 MCP 工具实际执行 |
|
|
20
|
+
| 真实 API | 使用已经配置的账号;在临时目录建立独立运行时,结束后回收子进程 |
|
|
21
|
+
| 群内验收 | 使用用户指定的测试群和运行中的 daemon;通过现有 debug 注入入口发送带“自动化测试”标记的可见消息 |
|
|
22
|
+
| 人工交互 | 用户实际选择模型、点击提问按钮、发送 `cl` 并上传图片 |
|
|
23
|
+
| 证据 | 模型请求内容、工具结果、实际文件内容、原生持久化事件、飞书原始卡片、systemd 日志及进程状态 |
|
|
24
|
+
|
|
25
|
+
文本注入复用了真实群、真实消息 ID 和正常 Session 处理路径,但它不能证明飞书 WebSocket 收到了用户图片。因此图片入站另用真实客户端消息验证;没有把模拟事件算作这一项通过。
|
|
26
|
+
|
|
27
|
+
## 一、本次新增或扩展的 27 个自动化用例
|
|
28
|
+
|
|
29
|
+
### 14 个原生 runtime 与桥接用例
|
|
30
|
+
|
|
31
|
+
源码:[src/dsh-process.test.ts](../src/dsh-process.test.ts)。这些用例运行真实 Node DSH 子进程,本地模型服务负责提供可控响应和错误。
|
|
32
|
+
|
|
33
|
+
| 编号 | 场景与执行方式 | 验收条件 |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| A01 | 主 Agent 启动后台子 Agent,主回复先结束,子 Agent 再执行 Bash | 内容块结果进入共享后台卡状态;子任务完成,主进程仍存活 |
|
|
36
|
+
| A02 | 注入桥接致命错误,随后正常完成 shutdown | 即使退出码为 0,仍报告非预期退出 |
|
|
37
|
+
| A03 | 连续多轮、停止进程、恢复历史,再从首轮 checkpoint 分叉并查询历史 | 流式文本和 token/cache 用量正确;恢复包含旧上下文;分支保留边界之前的内容、排除之后的内容;历史归属正确 |
|
|
38
|
+
| A04 | 让模型发起真实 Bash 写文件 | 工具结果关联正确,磁盘上的文件内容与预期一致 |
|
|
39
|
+
| A05 | 原生 `ask_user_question`,通过标准权限回答接口选择 Blue | 只触发一次提问,下一次模型请求包含真实选择值 |
|
|
40
|
+
| A06 | 持续挂起 SSE 响应,取消后再发下一轮 | 本轮明确为 aborted,进程存活,后续回复成功 |
|
|
41
|
+
| A07 | 模型接口先返回 HTTP 401,再返回 `finish_reason=length` | 分别报告鉴权失败、输出上限,不标记为成功 |
|
|
42
|
+
| A08 | 一轮工具调用中切换模型和 effort,下一轮再继续;同时以 worker 权限启动 | 当前轮仍使用原路由,下一轮使用 Pro/off;worker 工具列表不含继续委派能力 |
|
|
43
|
+
| A09 | 根 Agent 通过真实 Shell 检查委派环境 | 根 Agent 获得专用上下文,通用主会话 capability 不直接出现在 Shell 环境中 |
|
|
44
|
+
| A10 | 附加一个内容并非图片的 `.png` 文件 | 明确报错,模型接口没有收到请求 |
|
|
45
|
+
| A11 | 把有效 JPEG 保存成 `.png` 后附加给视觉模型 | 依据文件字节声明类型,图片被接受 |
|
|
46
|
+
| A12 | 空历史压缩、构造多轮长历史后压缩,再停止并恢复 | 无需压缩时显式拒绝;真实压缩完成且发出事件;压缩后的会话可恢复 |
|
|
47
|
+
| A13 | 原生子 Agent 检查自己的工具清单及 Shell 环境 | 不能再次委派,不能继承根 Agent 的委派上下文;仍能使用普通代码工具 |
|
|
48
|
+
| A14 | 在隔离项目配置 stdio MCP 服务,由模型调用发现的工具 | 服务实际启动,工具被发现并执行,结果回到模型 |
|
|
49
|
+
|
|
50
|
+
### 3 个账号来源用例
|
|
51
|
+
|
|
52
|
+
源码:[src/token-source-dsh.test.ts](../src/token-source-dsh.test.ts)。
|
|
53
|
+
|
|
54
|
+
| 编号 | 场景 | 验收条件 |
|
|
55
|
+
| --- | --- | --- |
|
|
56
|
+
| A15 | 没有为 DSH 显式配置凭据,但环境中存在 DeepSeek key | 来源保持禁用、模型列表为空,启动报缺失凭据;不借用旧来源 |
|
|
57
|
+
| A16 | 启动环境中混有旧 Anthropic、DeepSeek、DSH home 与 Node 覆盖值 | 清除冲突值,注入选定账号与 Node 配置,保留调用方需要的委派上下文 |
|
|
58
|
+
| A17 | 注册和解析 `deepseek-harness-setup` | 命令对应独立来源,解析后 provider 为 `dsh` |
|
|
59
|
+
|
|
60
|
+
### 10 个共享模块用例
|
|
61
|
+
|
|
62
|
+
| 编号 | 场景 | 验收条件与源码 |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| A18 | Agent CLI 使用 DSH 专用上下文发请求 | 请求带正确认证;[agent-cli.test.ts](../src/agent-cli.test.ts) |
|
|
65
|
+
| A19 | DSH 上下文结构不合法,同时存在旧凭据 | 明确失败,不改用旧凭据;同上 |
|
|
66
|
+
| A20 | 保存再加载 DSH resume、`off` effort 与原生 event checkpoint | 数据完整,保留其他 provider 的历史;[feishu-turns-map.test.ts](../src/feishu-turns-map.test.ts) |
|
|
67
|
+
| A21 | 提交非法 DSH fork 锚点 | 在触碰后端前拒绝;同上 |
|
|
68
|
+
| A22 | 在 Session 输入含连字符、无参数的 setup 命令 | 由命令层消费并给出提示,不流入模型;[session.test.ts](../src/session.test.ts) |
|
|
69
|
+
| A23 | 模型面板选择 DSH 的 `off` effort | 使用同一个原生进程更新设置;同上 |
|
|
70
|
+
| A24 | Claude 正在执行任务时切换到 DSH | 拒绝替换忙碌进程;同上 |
|
|
71
|
+
| A25 | DSH 子工具返回内容块数组 | Session 不抛异常,结果不写到主对话卡;同上 |
|
|
72
|
+
| A26 | 后台卡 active/pending 两个池接收结构化结果及错误 | 正常生成摘要,错误信息保留;[background.test.ts](../src/cards/background.test.ts) |
|
|
73
|
+
| A27 | 通知回复占用输入时,DSH 连续产生两条提问 | 延迟按钮和提醒;回复结束后逐题激活、回填;[session-ask.test.ts](../src/session-ask.test.ts) |
|
|
74
|
+
|
|
75
|
+
## 二、真实 DeepSeek API 验收
|
|
76
|
+
|
|
77
|
+
首轮独立验收包含 13 个场景,另有 1 个视觉模型场景,全部通过。下表的成功证据均来自实际请求或工具执行。
|
|
78
|
+
|
|
79
|
+
| 编号 | 用例 | 检查结果 |
|
|
80
|
+
| --- | --- | --- |
|
|
81
|
+
| L01 | Flash/off 基础流式回复与 checkpoint | 收到预期回复、用量及原生完成锚点 |
|
|
82
|
+
| L02 | Write → Edit → Bash | 文件确实创建、修改,Shell 读到修改后的内容 |
|
|
83
|
+
| L03 | 独立 Read | 模型通过 Read 读取未在提示词中给出的文件内容 |
|
|
84
|
+
| L04 | 原生提问和程序回填 | 回填 BLUE 后,模型使用了实际答案 |
|
|
85
|
+
| L05 | 项目 MCP | 实际调用本地 MCP echo 工具并取得结果 |
|
|
86
|
+
| L06 | 切换到 Pro | 使用选定模型成功回复 |
|
|
87
|
+
| L07 | 切回 Flash/high | 推理设置被实际请求采用,回复成功 |
|
|
88
|
+
| L08 | 进程恢复 | 关闭并恢复原生会话后,仍能回答先前保存的记忆词 |
|
|
89
|
+
| L09 | 中断真实 Shell,再继续 | 取消能结束本轮,下一轮继续工作 |
|
|
90
|
+
| L10 | 手动压缩与后续回复 | 原生压缩完成,压缩后继续回答 |
|
|
91
|
+
| L11 | 原生 checkpoint 分叉 | 新分支从指定完成边界继续,源会话保留 |
|
|
92
|
+
| L12 | 原生子 Agent | 子任务实际执行,主 Agent 获得并使用结果 |
|
|
93
|
+
| L13 | 原生历史列表 | 返回同目录的原生会话记录 |
|
|
94
|
+
| L14 | Vision-Exp/off 看图 | 正确识别测试图形为 triangle |
|
|
95
|
+
|
|
96
|
+
发现后台卡和图片问题后,又用真实 API 分别复测:JPEG 识别为 circle;后台子 Agent 的结构化工具结果进入共享状态,完成后根进程继续存活。随后再到运行中的测试群验证修复。
|
|
97
|
+
|
|
98
|
+
## 三、真实飞书群验收
|
|
99
|
+
|
|
100
|
+
群内选择的是 `DeepSeek-V4-Flash-Vision-Exp / max`;跨模型委派选择 DSH 的 Pro/high。以下各项均观察飞书返回的实际卡片或文件,避免把提示词中的“成功标记”当作模型输出。
|
|
101
|
+
|
|
102
|
+
| 编号 | 用例 | 真实验收证据 |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| F01 | 模型目录与面板选择 | DSH 三个模型已加载;用户实际选择 Vision-Exp/max;群设置与回复 footer 一致 |
|
|
105
|
+
| F02 | 基础流式回复 | 助手正文包含预期标记;卡片结束 streaming,footer 显示完成、模型和用量 |
|
|
106
|
+
| F03 | 工具卡与文件发送 | Agent 创建文件并读取;发送标记生成独立文件消息;从飞书重新下载后内容逐字一致 |
|
|
107
|
+
| F04 | 提问按钮 | 用户真实点击 BLUE;卡片显示已回答;模型回复使用 BLUE |
|
|
108
|
+
| F05 | 两条消息排队 | 第一条执行短 Shell 时发送第二条;两条结果落在不同卡片 |
|
|
109
|
+
| F06 | `stop` 后继续 | 中断正在等待的 Shell,卡片显示停止;下一条输入正常完成 |
|
|
110
|
+
| F07 | `rs` 恢复本群会话 | 保持原生会话编号,记忆词保留;daemon PID 不变 |
|
|
111
|
+
| F08 | 前台原生子 Agent | `run_in_background=false`,子 Agent 计算 `13×17`,主 Agent 返回 221 |
|
|
112
|
+
| F09 | Lodestar 管理的跨模型委派 | 通过真实 `lodestar-agent` CLI 调用 DSH Pro;委派板显示完成,主回复和子结果均为 42 |
|
|
113
|
+
| F10 | `compact` | 群命令显示原生压缩完成,后续回复正常;暂缺的上下文数据明确显示 MISS |
|
|
114
|
+
| F11 | `fk` / `bk` 选择器 | 两个选择器均出现并列出可选历史;本项只验证展示,不包含点击后建群或切换分支 |
|
|
115
|
+
| F12 | 后台原生子 Agent,首次尝试 | 实际发现结构化工具结果导致卡片异常和 DSH 退出;保留失败证据 |
|
|
116
|
+
| F13 | 后台修复后的群内回归 | 主回复先结束;子 Agent 完成 Bash、job_output、Read 三次调用;后台卡显示三条结果并正常结算;主会话还能继续回答 |
|
|
117
|
+
| F14 | JPEG 编码回归 | 上传 JPEG 到飞书、下载为 `.png`,以附件路径送入运行中 Session;正确回答 blue circle |
|
|
118
|
+
| F15 | 回归结束后的会话健康 | 继续发送独立短请求,回复成功;检查本轮日志无 DSH 异常退出或卡片错误 |
|
|
119
|
+
| F16 | 用户真实 `cl` | 用户在客户端清空会话;旧 DSH 正常退出,新会话就绪 |
|
|
120
|
+
| F17 | 用户真实图片 WebSocket 入站 | 用户从客户端发图;daemon 实际下载附件;DSH 正确读出图片中的文字与场景,卡片约 3.1 秒完成 |
|
|
121
|
+
|
|
122
|
+
F13 还检查了原生记录:后台启动时的主回复与完成后的续聊属于同一个已初始化会话。F17 使用用户自己发来的图片,不是机器人发送后的注入模拟。3.1 秒只是这一次样本的处理时长,不代表性能基准。
|
|
123
|
+
|
|
124
|
+
## 四、测试发现了什么
|
|
125
|
+
|
|
126
|
+
| 问题 | 触发与证据 | 修复及复测 |
|
|
127
|
+
| --- | --- | --- |
|
|
128
|
+
| setup 命令未被拦截 | 原正则不接受来源名中的连字符,也不接受无参数形式,命令可能落入模型输入 | 命令层接受连字符、大小写和无参数提示;新增 Session 用例 |
|
|
129
|
+
| 取消状态无法落盘 | Node fetch 会修改可变的 abort reason,附加原生日志不接受的 stack 属性 | 取消原因保持不可变;取消请求、取消 Shell、取消后续聊均验证 |
|
|
130
|
+
| 后台工具结果导致退出 | 子工具返回 `ContentBlock[]`;后台摘要把它当字符串调用 `.replace()`,实际抛 TypeError 并终止 DSH | 先按内容结构归一化文本;补共享卡片、Session、真实 runtime 测试;真实 API 和群内再次通过 |
|
|
131
|
+
| 致命错误退出被当成预期关闭 | 出错后清理过程正常结束,会掩盖最初的致命原因 | 保留非预期失败标记;退出码 0 也不把此前失败改成成功 |
|
|
132
|
+
| 图片编码误判 | 飞书下载文件后缀为 `.png`,字节却是 JPEG;原生附件服务报 `Declared image type does not match its bytes` | 根据图片字节判断 MIME;保留错误输入拒绝;模拟 API、真实 API、群内、用户客户端四层验证 |
|
|
133
|
+
|
|
134
|
+
这些问题被保留为失败记录和回归用例。修复后的代码先独立验证,再经用户明确授权重启 daemon,最后检查新 PID、启动时间及真实群内结果。
|
|
135
|
+
|
|
136
|
+
## 五、观察脚本也需要验证
|
|
137
|
+
|
|
138
|
+
测试过程中有几次失败来自观察方法,不能据此修改产品来“制造通过”:
|
|
139
|
+
|
|
140
|
+
- 飞书默认读卡接口返回的是兼容提示。改用 `raw_card_content`,解析真正的 Card Kit 2.0 内容,才可判断正文、工具、footer 和 streaming 状态。
|
|
141
|
+
- 原始卡片读取结果不包含按钮回调的私有字段。曾据此等不到按钮;最终以用户实际点击、卡片已回答状态和模型拿到 BLUE 三份证据验收。
|
|
142
|
+
- 复合任务中,模型虽然完成写入和执行,却跳过了单独的 Read。保留这次失败,再设计一个不知道文件内容就无法通过的独立读取任务。
|
|
143
|
+
- 递归遍历卡片的观察脚本曾占用过高 CPU。检查完整命令后只终止该脚本,改为迭代遍历,再核对已经完成的主卡和委派板。
|
|
144
|
+
- 首次启动时曾把“上次已经停止的会话编号”与“本次新会话编号”直接比较。产品的冷启动规则本就会新建会话;改为核对初始化之后的原生记录和后续回复,不把合法新会话误判为崩溃重启。
|
|
145
|
+
- 消息列表探针曾使用不支持的 `page_size=100`,收到明确参数错误;改为 50 并分页,未绕过或忽略 API 错误。
|
|
146
|
+
|
|
147
|
+
## 六、覆盖边界
|
|
148
|
+
|
|
149
|
+
本次已经验证核心代码工具、原生会话、提问、委派、后台卡、取消、压缩、模型选择与图片入站。仍应准确保留以下边界:
|
|
150
|
+
|
|
151
|
+
- 882 项是全项目回归用例数,不是 882 次真实 DeepSeek 调用,也不是所有用户操作的穷举。
|
|
152
|
+
- `fk` / `bk` 群内只验证到选择器;原生 fork 的边界语义已在本地 runtime 和真实 API 层验证,没有在这一轮额外创建临时群或执行实际回退。
|
|
153
|
+
- 项目 MCP 的真实执行覆盖 stdio;HTTP MCP、所有插件与所有外部服务没有逐一实测。
|
|
154
|
+
- 本机真实运行环境为 Linux / Node 22.22.2;没有据此宣称 macOS、Windows、所有 Node 版本均经过人工端到端测试。
|
|
155
|
+
- 问答卡仍可能同时显示原生 ask 工具行和交互提问行;真实回答链路已验证,不能据此声称展示已做去重优化。
|
|
156
|
+
|
|
157
|
+
## 七、发布门禁与复现入口
|
|
158
|
+
|
|
159
|
+
日常可重复的检查入口:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# desc: 运行 DSH 专项回归
|
|
163
|
+
bun test src/dsh-process.test.ts src/token-source-dsh.test.ts
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# desc: 运行发布质量检查
|
|
168
|
+
bun run ci
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
`bun run ci` 包含生产依赖审计、TypeScript 检查、全量测试、固定 seed 的随机顺序测试和发布入口构建。发布还必须把实际 tarball 安装到空目录,执行 `npm audit --omit=dev`,防止源码 overrides 与用户安装后的依赖树不一致。
|
|
172
|
+
|
|
173
|
+
真实群测试需要显式指定目标群与账号;独立 API 测试需要有效凭据。不要把真实 key 写进测试文件,也不要为群内验收另起一个 daemon。
|
|
174
|
+
|
|
175
|
+
0.17.0 最终发布前检查结果:
|
|
176
|
+
|
|
177
|
+
| 检查 | 结果 |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| 源码生产依赖审计 | 通过 |
|
|
180
|
+
| TypeScript 类型检查 | 通过 |
|
|
181
|
+
| 全量测试 | **882 pass / 0 fail**,59 个文件,3380 次断言 |
|
|
182
|
+
| 固定 seed 17 的随机顺序测试 | **882 pass / 0 fail**,3380 次断言 |
|
|
183
|
+
| 发布入口构建 | 7 个 JavaScript 入口生成成功,包含独立 `dsh-bridge.js` |
|
|
184
|
+
| 实际 tarball 安装 | 空目录安装成功;7 个安装后入口通过 Node 语法检查 |
|
|
185
|
+
| 安装后生产依赖审计 | **0 漏洞** |
|
|
186
|
+
| 安装包中的原生 DSH smoke | 协议握手成功,读取 3 个模型,2 次本地模型请求、1 次真实 Shell 工具调用,磁盘文件内容匹配,子进程正常回收 |
|
|
187
|
+
| 用户真实图片入站 | 通过,最终图像内容经人工核对 |
|
|
188
|
+
|
|
189
|
+
源码层与安装包层分别留存了检查结果。安装包 smoke 使用实际解包后的桥接文件与依赖,模型接口为本地可控服务;真实 DeepSeek 请求和真实群内验收见前两节。
|
package/docs/models.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# 账号、模型与 effort
|
|
2
|
+
|
|
3
|
+
[返回首页](../README.md) · [安装与配置](configuration.md) · [群内用法](usage.md)
|
|
4
|
+
|
|
5
|
+
账号配置使用 `[token_source.glm]`、`[token_source.deepseek]` 等节。GLM、DeepSeek 和 OpenRouter 也可以从本机 Claude settings 中识别;识别后由对应 Token Source 注入凭据,避免不同账号的环境变量串用。项目的工具限制只作用于主会话,委派 Agent 使用完整工具集。
|
|
6
|
+
|
|
7
|
+
`md` / `model` 首页用独立分组展示 Claude Code、Codex、DeepSeek Harness:每组都有浅蓝标题栏、边框和 `Agent · 名称` 标题,默认展开,Token Source 行放在组内。模型行之间有分隔线,右侧窄按钮使用单字「选 / 隐 / 显 / 删」,补录、返回和翻页等宽按钮保留完整文案。选账号后进入模型选择;有多个 effort 档位时再选择档位,只有一个档位(包括原生默认)时直接应用。除 OpenRouter 的默认列表外,各来源默认显示接口目录。接口中的模型使用「隐藏 / 显示」,只调整面板可见性,接口新增模型仍会出现。
|
|
8
|
+
|
|
9
|
+
所有 Token Source 都提供「补录模型」按钮,补录接口列表外的模型;「删」删除补录记录。记录保存在 `custom_models`;支持端点验证的来源会先验证,补录后即可选择 effort 并使用:DSH 调用原生模型解析,其他来源提供 Agent 的请求档位。目录未收录不会阻止选择,实际不支持的请求由后端报告错误。接口后来收录同名模型时自动转为接口项,不重复显示。删除补录记录需要先切换仍选用它的会话;默认模型和辅助模型中指向已删除补录项的配置也会清理。
|
|
10
|
+
|
|
11
|
+
所有对话卡的模型标识固定为 `claude · 模型名/effort`、`codex · 模型名/effort` 或 `dsh · 模型名/effort`。窗口额度沿用原来的紧凑格式,如 `4.1h·7%·[6.9d·17%]`(重置倒计时与已用百分比);余额显示 `余额 $12.34` 或 `余额 ¥12.34`。Codex 额度接口短暂网络失败会有限重试;最终读取失败才显示 `MISS`。`hi` 中的额度标题、各个额度窗口与 Codex 重置卡次数分别换行。
|
|
12
|
+
|
|
13
|
+
## OpenRouter
|
|
14
|
+
|
|
15
|
+
OpenRouter 通过 Claude Agent SDK 运行。在群内发送 `openrouter-setup <api_key>`,再通过 `model` 面板选择模型和 effort;自建兼容端点用 `openrouter-setup <base_url> <api_key>`。也可在配置文件中添加:
|
|
16
|
+
|
|
17
|
+
```toml
|
|
18
|
+
[token_source.openrouter]
|
|
19
|
+
agent = "claude"
|
|
20
|
+
api_key = "填写自己的 OpenRouter API key"
|
|
21
|
+
# base_url = "https://openrouter.ai/api" # SDK 自动追加 /v1/messages
|
|
22
|
+
# model = "anthropic/claude-fable-5.1" # 可选:默认运行模型,须获账号目录确认
|
|
23
|
+
# effort = "max" # 可选:仅覆盖默认运行模型的档位
|
|
24
|
+
# models = "anthropic/claude-fable-5.1,moonshotai/kimi-k3" # 可选:自定义可选列表
|
|
25
|
+
# slots = "haiku=anthropic/claude-fable-5.1" # 可选:辅助任务模型,须获账号目录确认且使用相同的 effort 参数模式
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
OpenRouter 默认可选列表按 [Arena Agent Labs 榜单](https://arena.ai/leaderboard/agent?rankBy=labs) 的 2026-09-08 快照设置:前 12 家各取排名最高的模型,排除 OpenAI、Z.ai / GLM、DeepSeek,保留以下 9 项。
|
|
29
|
+
|
|
30
|
+
| Labs 排名 | 厂商 | OpenRouter 模型 | 默认档位 |
|
|
31
|
+
| --- | --- | --- | --- |
|
|
32
|
+
| 1 | Anthropic | `anthropic/claude-fable-5.1` | max |
|
|
33
|
+
| 3 | Moonshot | `moonshotai/kimi-k3` | max |
|
|
34
|
+
| 4 | Tencent | `tencent/hy4-preview` | high |
|
|
35
|
+
| 7 | Google | `google/gemini-3.8-flash` | high |
|
|
36
|
+
| 8 | SpaceXAI | `x-ai/grok-4.5` | high |
|
|
37
|
+
| 9 | Alibaba | `qwen/qwen3.8-max-0902` | xhigh |
|
|
38
|
+
| 10 | Meta | `meta/muse-spark-1.2` | xhigh |
|
|
39
|
+
| 11 | Xiaomi | `xiaomi/mimo-v2.5-pro` | 模型默认 |
|
|
40
|
+
| 12 | MiniMax | `minimax/minimax-m3` | 模型默认 |
|
|
41
|
+
|
|
42
|
+
2026-09-11 进一步补齐国内厂商,默认列表共 **11 项**。原榜单顺序不变,后面追加以下两项;这些追加项不代表 Arena 前十二名排名。蚂蚁和阶跃星辰不列为默认。
|
|
43
|
+
|
|
44
|
+
| 厂商 | OpenRouter 模型 | 默认档位 |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| 字节跳动 | [Seed 2.1 Turbo](https://openrouter.ai/bytedance-seed/seed-2-1-turbo) · `bytedance-seed/seed-2-1-turbo` | 模型默认 |
|
|
47
|
+
| 美团 | [LongCat 2.0](https://openrouter.ai/meituan/longcat-2.0) · `meituan/longcat-2.0` | 模型默认 |
|
|
48
|
+
|
|
49
|
+
同日核查百度:[CoBuddy](https://openrouter.ai/baidu/cobuddy) 和 ERNIE 4.5 300B 的端点目录为空,实际调用返回 `404 No endpoints found`;账号目录中可见的 ERNIE 4.5 VL 424B 未声明工具调用支持,因此暂不加入 Agent 默认列表。快手 [KAT-Coder-Pro V2.5](https://openrouter.ai/kwaipilot/kat-coder-pro-v2.5) 虽在账号目录中,但原生 Chat Completions 和 Anthropic Messages 实测均返回 AtlasCloud 上游 `400 bad request`,暂不列为默认,仍可从目录手动显示。账号目录中也没有找到华为、讯飞、商汤的可用工具模型。阿里、腾讯、小米、月之暗面、MiniMax 已在原九项中;OpenAI、GLM、DeepSeek 继续排除。
|
|
50
|
+
|
|
51
|
+
在 `md` / `model` → claude → OpenRouter 中,点「显示模型」进入账号目录,再点行右侧「显」加入列表,点每行「隐」移出面板列表。可见性自动持久化,不改当前运行模型;全部隐藏后也能继续显示或补录。未配置 `models` 时才使用上述十一项;`models = ""` 明确表示没有已显示的接口模型,刷新或重启不会补回默认项。榜单变化不会覆盖用户维护的列表。
|
|
52
|
+
|
|
53
|
+
候选目录来自 `/api/v1/models/user`,按账号供应商和隐私设置筛选,仅纳入支持文本和工具调用的交互模型;OpenAI、GLM、DeepSeek 及无法保证厂商范围的自动路由不会出现在添加候选中。目录刷新失败显示 `MISS`。显式配置但已下线的模型保留为可删除的 `MISS` 项。
|
|
54
|
+
|
|
55
|
+
effort 按上游声明提供。小米、MiniMax、字节等没有 effort 选择器的模型直接选用原生默认行为,跳过 effort 卡,实际请求不携带 effort 参数。两种参数模式之间切换时,空闲进程会保存原生会话并在下一轮用新环境恢复;相同模式下继续使用 SDK 热切换。未配置 `model` 时需要通过面板明确选择运行模型。
|
|
56
|
+
|
|
57
|
+
OpenRouter 余额来自 `/api/v1/credits`,按 `total_credits - total_usage` 计算,卡片仅显示 `余额 $…`,不附加 Key 限额或累计消费。现有 Key 已实测返回 200;接口权限和错误以实际响应为准。SDK 使用 Bearer token,并显式清空 `ANTHROPIC_API_KEY`。OpenRouter 官方的兼容保证限于 Anthropic 第一方供应商;工具调用、模型与档位参数的验证范围见 [后端说明](claude-agent-backend.md)。
|
|
58
|
+
|
|
59
|
+
## DeepSeek Harness
|
|
60
|
+
|
|
61
|
+
DeepSeek Harness 使用独立的 `[token_source.deepseek-harness]` 账号与原生会话。在群内发送 `deepseek-harness-setup <api_key>`,再通过 `model` 面板选择该来源即可启用。自建端点用 `deepseek-harness-setup <base_url> <api_key>`;这里使用原生 API 根地址,不带 `/anthropic`。
|
|
62
|
+
|
|
63
|
+
## DSH 的 GLM Coding Plan
|
|
64
|
+
|
|
65
|
+
DSH 也支持 GLM Coding Plan:已有 `[token_source.glm]` 时自动复用该账号,在 `md` → dsh → GLM Coding Plan 中选择模型。独立凭据用 `dsh-glm-setup [base_url] <api_key>`,配置节为 `[token_source.dsh-glm]`。它调用 Coding Plan 的 OpenAI 端点,复用 GLM 额度查询;不经过 OpenRouter 或 Claude SDK。账号接口模型和补录模型一起交给原生适配器,均可选择请求档位;接口项用「隐 / 显」,补录项用「删」。
|
|
66
|
+
|
|
67
|
+
```toml
|
|
68
|
+
[token_source.deepseek-harness]
|
|
69
|
+
agent = "dsh"
|
|
70
|
+
api_key = "填写自己的 API key"
|
|
71
|
+
# bin = "/abs/path/to/node" # 可选:运行 DSH 的 Node 可执行文件
|
|
72
|
+
# model = "deepseek-v4-pro" # 可选:默认模型
|
|
73
|
+
# effort = "high" # 可选:默认请求档位
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
手动修改配置后需重启 daemon;群内账号启用和模型补录会自行重载相关配置。模型路由、配置优先级和后端差异见 [后端说明](claude-agent-backend.md)。
|
package/docs/usage.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# 群内使用指南
|
|
2
|
+
|
|
3
|
+
[返回首页](../README.md) · [模型与账号](models.md)
|
|
4
|
+
|
|
5
|
+
## 群内命令
|
|
6
|
+
|
|
7
|
+
直接发送下列词语,不加斜杠,大小写不敏感。这些命令控制当前群的 Agent 会话。
|
|
8
|
+
|
|
9
|
+
| 指令 | 行为 |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `hi` | 打开控制台;会话未运行时先启动 |
|
|
12
|
+
| `stop` / `st` | 打断当前回复并取消排队消息,保留进程 |
|
|
13
|
+
| `kill` / `kl` | 关闭当前 Agent 进程,保存可恢复的会话记录 |
|
|
14
|
+
| `restart` / `rs` | 进程存活时打断并恢复当前会话;已停止时列出同目录的历史会话,选择后创建独立分支 |
|
|
15
|
+
| `clear` / `cl` | 关闭当前进程并开始新会话;已停止时提示先启动 |
|
|
16
|
+
| `compact` / `cm` | 压缩当前会话的上下文 |
|
|
17
|
+
| `model` / `md` | 按账号 → 模型 → effort 选择并保存 |
|
|
18
|
+
| `agents` | 查看可调用的 Agent 身份及可用状态 |
|
|
19
|
+
| `task` | 创建、查看或删除绑定的飞书任务清单 |
|
|
20
|
+
|
|
21
|
+
模型列表来自各账号的模型目录,获取失败显示 `MISS`。同账号切换 Claude 模型从后续回复生效,Codex 的持久模型设置需重启会话生效;跨账号或后端切换只允许在空闲时进行。
|
|
22
|
+
|
|
23
|
+
GLM 的套餐与用量显示在 `hi` 控制台,回复底部也会显示当前窗口用量。
|
|
24
|
+
|
|
25
|
+
## Worktree 与临时会话
|
|
26
|
+
|
|
27
|
+
需要独立修改文件时,在项目主群使用 worktree:
|
|
28
|
+
|
|
29
|
+
| 指令 | 行为 |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `wt` / `worktree` | 列出项目的 `work/*` 分支和工作区状态 |
|
|
32
|
+
| `wt feature-x` | 创建或加入 `<project>[feature-x]` 群和同级 worktree 目录,使用 `work/feature-x` 分支 |
|
|
33
|
+
|
|
34
|
+
已合并且未挂载的分支会折叠隐藏,再次启用时更新到主线。卡片上的“删”会检查对应群没有运行中的会话、工作区没有未提交变更,再解散群并删除 worktree;Git 分支保留。
|
|
35
|
+
|
|
36
|
+
临时会话共享当前工作目录,适合在同一项目里另开一段对话:
|
|
37
|
+
|
|
38
|
+
| 指令 | 行为 |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `btw` | 创建 `<session>*MMDD-HHMM` 临时群,继承账号、模型和工作目录,启动新会话 |
|
|
41
|
+
| `bye` | 停止并解散当前临时群,仅适用于 Lodestar 创建的临时群 |
|
|
42
|
+
| `fk` / `fork` | 选择一条用户输入,在临时群里从这条输入之前分叉 |
|
|
43
|
+
| `bk` / `back` | 选择一条用户输入,让本群接到这条输入之前的新分支 |
|
|
44
|
+
|
|
45
|
+
`fk`、`bk` 和从历史记录恢复的 `rs` 都使用后端原生 fork,保留源对话。选第 N 条输入表示回到它发出之前,选中的输入不包含在新分支内。Claude 的新分支在首条输入时获得会话 id,准备状态会持久保存。
|
|
46
|
+
|
|
47
|
+
**分叉和回退只改变对话历史,不回滚文件或撤销 Shell、MCP 等外部操作。** `bk` 会附上已观察到的文件变更记录;需要目录隔离时使用 `wt`。
|
|
48
|
+
|
|
49
|
+
## 多模型任务
|
|
50
|
+
|
|
51
|
+
主 Agent 可以通过 `lodestar-agent` 查询实时身份,再把任务交给一个或多个模型。同一个任务选择多个身份时并发执行;后续追问可继续使用各模型的原生会话。
|
|
52
|
+
|
|
53
|
+
被调用的 Agent 可以编辑文件、执行命令、使用 MCP 和 Skill;委派只允许一层,被调用的 Agent 不能继续派工。它们与主 Agent 共享工作区,修改会立即可见。运行状态和结果通过卡片展示;需要用户输入时暂停,由主 Agent 回填答案后继续。委派产生的会话不会混入主群的 `rs` 历史列表。
|
|
54
|
+
|
|
55
|
+
`lodestar-agent` 只能在 Lodestar 管理的 Agent 进程里调用。命令用法见 [Agent Skill](../src/agent-skill.ts)。
|
|
56
|
+
|
|
57
|
+
## 飞书任务清单
|
|
58
|
+
|
|
59
|
+
发 `task`,点“启用”可创建并绑定 `<project>[lodestar]` 任务清单。删除需要在卡片上再次确认,会删除整个清单及其中任务。该面板管理清单绑定,任务执行由用户和 Agent 安排。
|
|
60
|
+
|
|
61
|
+
## 本机通知
|
|
62
|
+
|
|
63
|
+
脚本可通过 HTTP 向项目群发送通知,支持 `info`、`warn`、`error`,以及本地图片、按钮和点击回调:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
curl -sS -X POST http://127.0.0.1:9876/notify \
|
|
67
|
+
-H 'Content-Type: application/json' \
|
|
68
|
+
-d '{"project":"ops","level":"error","text":"构建失败,截图如下","images":["/abs/shot.png"]}'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
按钮点击结果可以 POST 到指定的本机 `callback`,或通过 `GET /notify/result/<notify_id>` 查询。字段和协议见 [feishu-notify Skill](../src/notify-skill.ts)。daemon 启动时会将该 Skill 同步到 Codex 和 Claude 的 Skill 目录。
|
|
72
|
+
|
|
73
|
+
## 文件与生图
|
|
74
|
+
|
|
75
|
+
单个出站文件不能超过 **30 MB**(30 × 1024 × 1024 字节)。Agent 在交付前检查大小,超限先压缩或分卷;发送层也会拒绝超限文件。
|
|
76
|
+
|
|
77
|
+
Codex 生图完成后,提示词和图片放在同一个折叠面板中,点击展开查看图片并放大预览。无法嵌入时,图片仍会单独发送。
|
|
78
|
+
|
|
79
|
+
`hi` 显示 Codex 账号的可用重置卡次数,数据来自额度接口的 `rateLimitResetCredits.availableCount`。回复 footer 继续保持原来的紧凑额度格式。
|