Skip to content

feat: pm 关 resume 降本 — noResume 配置 + 全新会话注入完整最近历史 - #273

Merged
lishuceo merged 4 commits into
mainfrom
feat/claude-session-ba6ee8
Jul 19, 2026
Merged

feat: pm 关 resume 降本 — noResume 配置 + 全新会话注入完整最近历史#273
lishuceo merged 4 commits into
mainfrom
feat/claude-session-ba6ee8

Conversation

@lishuceo

Copy link
Copy Markdown
Owner

背景

pm bot(土豆儿)在高频私聊场景整天 resume 累积,基线上下文从 60K 一路涨到 600K+,长循环里每轮重读把成本推高,频繁撞 $15 budget 上限、无法使用。根因不是单句话贵,而是长会话逐轮累积。

方案

让 pm 不 resume(每条消息全新 SDK 会话),用"注入最近 N 条聊天历史"替代 SDK session 记忆。配套上调历史预算,让 fresh 会话装得下足够上下文。

改动

1. per-agent noResume 配置字段

  • AgentConfig.noResume:开启后该 agent 每条消息全新会话
  • schema / loader 透传(agent 级覆盖 defaults);agents.example.json 的 pm 示例开启

2. 统一 resume 判定 canResumeSession(纯函数,可测)

  • 无会话 / cwd 变更 / agent noResume → 全新会话
  • 接入 executeClaudeTaskexecuteDirectTask 两条路径
  • 修正一处隐患:历史增量去重(afterMsgId)与历史文件附件跳过原本以 activeConversationId 为准,导致不 resume 时只注入增量、SDK 端却无记忆 → 失忆。改为以 canResume 为准,只有真正 resume 才做增量,否则注入完整最近 N 条(cwd 变更场景一并受益)

3. 上调默认历史预算

  • CHAT_HISTORY_MAX_COUNT 10 → 20
  • CHAT_HISTORY_MAX_CHARS 8000 → 16000
  • SELF_BOT_MSG_MAX 150 → 1500(noResume 下历史是唯一自我记忆来源,需保留较完整自身回复;字符硬顶仍防爆)

测试

  • 新增 canResumeSession 单测(4 分支)+ noResume 配置透传单测(4 例)
  • history-truncation / structured-chat-context 测试适配新预算
  • npx vitest run:1757 passed,唯一失败 memory/quality.test.ts > 当前工作重点 在 main 上同样失败(依赖 embedding API 的环境问题,与本 PR 无关)

部署注意

  • 本 PR 只提供 noResume 能力;要对 pm 生效,需在部署目录的 config/agents.json 给 pm 加 "noResume": true(该文件不在 git 中)
  • src/config.ts 默认值改动,合并后部署目录需 build + 重启生效

🤖 Generated with Claude Code

lishuceo and others added 3 commits July 20, 2026 03:48
新增 AgentConfig.noResume:开启后该 agent 每条消息都用全新 SDK 会话
(不 resume 上一轮),配合注入的最近 N 条聊天历史提供上下文,避免高频
闲聊型 agent(如 pm)长会话逐轮累积把上下文推到数十万 token、成本失控。

- types.ts: AgentConfig 加 noResume?: boolean
- config-schema.ts: input + defaults schema 加 noResume
- config-loader.ts: mergeAgentConfig 透传(agent 级覆盖 defaults)
- agents.example.json: pm 示例开启 noResume=true

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
抽出纯函数 canResumeSession 统一 resume 判定(无会话 / cwd 变更 /
agent noResume → 全新会话),并在 executeClaudeTask、executeDirectTask
两条路径接入。

关键修正:历史增量去重(afterMsgId)与历史文件附件跳过原本以
activeConversationId 为准,导致不 resume(noResume 或 cwd 变更)时
只注入增量历史、SDK 端却无对话记忆 → 失忆。改为以 canResume 为准:
只有真正 resume 时才做增量,否则注入完整最近 N 条。

配套上调默认预算,让 fresh 会话装得下足够上下文:
- CHAT_HISTORY_MAX_COUNT 10 → 20
- CHAT_HISTORY_MAX_CHARS 8000 → 16000
- SELF_BOT_MSG_MAX 150 → 1500 (noResume 下历史是唯一自我记忆来源,
  需保留较完整的自身回复;字符硬顶仍防爆)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- event-handler.test.ts: 新增 canResumeSession describe(无会话/cwd 变更/
  noResume/正常 resume 各分支)
- config-loader.test.ts: 新增 noResume 透传/继承/覆盖/缺省 4 例
- history-truncation.test.ts: 常量与断言同步到 SELF_BOT_MSG_MAX=1500、
  TOTAL_BUDGET=16000,新增'<1500 不截断'回归例
- structured-chat-context.test.ts: 放大输入以在 16000 预算下重新触发
  父群消息裁剪/省略提示

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Claude finished @lishuceo's task in 2m 58s —— View job


PR Review: pm 关 resume 降本

Verdict: ✅ Approved — clean, well-tested, no blocking issues. One trivial doc-drift nit below.

  • Read CLAUDE.md & PR intent
  • Review canResumeSession extraction + both call sites
  • Verify config schema/loader/type passthrough
  • Trace history-injection & dedup logic
  • Review tests

What I checked

canResumeSession (pure fn) + both call sites — Correct. The three not-resumable branches (no activeConversationId / cwd changed / noResume) are right, and both executeClaudeTask (line 2679) and executeDirectTask (line 3344) now route through it. The old inline canResume at the resume decision was removed and resumeSessionId: canResume ? activeConversationId : undefined (line 2905) still gates the actual SDK resume — so history injection and the resume decision are now driven by the same flag. 👍

The amnesia fix is real and correct. Previously afterMsgId and the history-file skip keyed off activeConversationId; on a cwd change (or noResume) the SDK started fresh yet only incremental history was injected → memory loss. Switching both to canResume (lines 2726, 2740, 3367, 3385) fixes this and correctly extends the benefit to the cwd-switch case.

Optional-chaining consistencyexecuteClaudeTask uses agentCfg?.noResume (agentCfg from .get(), nullable) while executeDirectTask uses agentCfg.noResume (agentCfg from getOrThrow() at line 3261, non-null). Both correct.

Merge precedencenoResume: input.noResume ?? defaults.noResume handles explicit false correctly (agent-level false overrides a defaults: true), matching the test at config-loader.test.ts. Schema adds noResume to both input and defaults schemas ✓.

Budget hard-cap holdsSELF_BOT_MSG_MAX 150→1500 is per-message; historyMaxChars (line 2331–2341) still drops oldest lines to enforce the total cap, so the "字符硬顶仍防爆" claim checks out.

TestscanResumeSession (all 4 branches + edge cases) and noResume passthrough (4 cases incl. defaults inheritance/override) are thorough and match the implementation.

🟡 Minor nit (confidence 85, non-blocking)

src/feishu/event-handler.ts:2272 — the doc comment still reads 总字符数超 CHAT_HISTORY_MAX_CHARS(默认 8000), but this PR bumped the default to 16000 (config.ts:168). Stale after this change.

Fix this →

Notes

  • Deploy caveat is well-flagged in the PR body: noResume is opt-in per agent via config/agents.json (not in git), and config.ts default changes need build + restart.
    · feat/claude-session-ba6ee8

review 反馈:注释还写 CHAT_HISTORY_MAX_CHARS 默认 8000 / 自身 bot 150 字符,
本 PR 已改成 16000 / 1500,同步注释消除 doc-drift。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lishuceo

Copy link
Copy Markdown
Owner Author

Fixed — 已把 formatHistoryMessages 注释里的 默认 8000 更新为 16000,并顺手修正了同段 自身 bot 150 字符1500(都是本 PR 引入的 drift)。commit 见 HEAD。(回复 review

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Claude finished @lishuceo's task in 1m 4s —— View job


Re-review after doc-comment fix

  • Verify the stale-comment fix (默认 800016000, 1501500)
  • Re-scan latest diff for new issues

Verdict: ✅ Approved — the fix in a832bb6 is correct and the wiring is unchanged. canResumeSession is still the single source of truth for both the resume decision (resumeSessionId, lines 2905/3350) and the history-injection/dedup gates (lines 2726/2740, 3367/3385). No regressions.

The formatHistoryMessages doc comment (event-handler.ts:2271-2272) now correctly reads 1500 / 16000. 👍

🟡 One more stale comment of the same kind (confidence 90, non-blocking)

src/feishu/event-handler.ts:3565buildDirectChatContext's doc comment still says:

 * max 由 CHAT_HISTORY_MAX_COUNT 控制(默认 10)。

but this PR bumped that default to 20 (config.ts:167). Same doc-drift class as the two just fixed — worth catching it in the same pass.

Fix this →

Everything else in the PR holds up — no blocking issues.
· feat/claude-session-ba6ee8

@lishuceo
lishuceo merged commit f23b0ad into main Jul 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant