Skip to content

面板 Sent to LLM(sent view)漏计 system prompt+工具 schema:plugin.ts 硬编码 systemPromptTokens: 0,SysPrompt 行永不可渲染(#425 不覆盖) #532

Closed

Description

@wosnxn123

症状(0.1.83 实机)

"ACP Context Analysis" 面板的 Sent to LLM (after compression, est.) 与 Token Breakdown (sent view) 系统性漏计 system prompt + 工具 schema:62k/35k 的会话显示 Sent=181/219;SysPrompt 行永远不渲染。

根因(v0.1.83)

  • 面板渲染在 vendored kernel:acp-kernel/src/panel/panel.ts:62-167(dist 54396-54470);唯一调用点 src/plugin.ts:388-400(dist 54740-54750);
  • sentTotal = classified + systemPromptTokens(panel.ts:67-69),而 systemPromptTokens 被硬编码为 0:src/plugin.ts:393(dist 54745)——尽管 kernel API 明确索要"measured token count of the host system prompt"(panel.ts:17-19);
  • bili 其实已经测过这个量:estimateInputTokens(processedMessages, systemText, tools, …)(server.ts:1643-1647),只是没传给面板;适配器也已把 system 从消息投影里抽出(openaiToCore 返回 {msgs, systemText}),故 breakdown 的 bd.system 也≈0;
  • 行渲染跳过 ≤0 值(panel.ts:104/111)→ SysPrompt/Code 行永不可见,用户无法察觉漏计;
  • PR fix: report uncompressed baseline in host usage + clamp negative persisted token stats (#408) #425 不覆盖此缺陷(其 plugin.ts hunk 保留 systemPromptTokens: 0)。

注:折叠原件被排除属设计内(有 Session-only (compressed originals, est.) 行自证),不在本票。

建议修复

prepare 时把 countTokens(systemText) + toolsTokens 存到 session(与 server.ts:1643-1647 同源),plugin.ts:393 改传该值;breakdown 的 system 类别同喂。

验收标准

  • 20k token system+tools 的会话:面板 Sent ≈ 折叠消息估计 + 20k,且出现 SysPrompt 条
  • 单测:systemPromptTokens 非零时 sentTotal 与 breakdown 自洽(各项和=total)

Activity

  1. ranxianglei commented on Sep 4, 2026

    @ranxianglei
    Owner

    🤖 ework agent · qwen3.8-27b

    [bot] 🏷 审核结论:缺陷属实,根因定位正确,开始修复。

    验证(v0.1.83 / acp-kernel 0.0.51)

    层次判断:这是"测过但没传"的接线缺口,不是 kernel bug——kernel API 文档明确要 host 自己测量并传入("host-specific to obtain; the kernel breakdown does not see it")。因此不需要动 kernel,bili 侧修复即可。

    方案(按票述建议实现,略有细化):

    1. prepare 三条 wire 路径(openai/responses/anthropic)在出站前把实际发往 LLM 的 system+tools token 数存到 session.metadata.systemPromptTokens(与 estimateInputTokens 同源计数;anthropic 用 injectSystem 后的最终文本,openai 只计 bili 注入部分避免与 kernel 已分类的 head-system 双计,responses 计 developer message 内容);
    2. plugin.ts 改传该值;同时给 unprunedTokens 加同一量,保证 Session-only (compressed originals) 推导(unpruned − sent)仍在同一尺度上隔离纯压缩原件;
    3. 单测:systemPromptTokens 非零时 sentTotal 与 breakdown 自洽(各项和=total)+ 集成测试验证大 system+tools 会话出现 SysPrompt 行。

    一个已知残留:Responses wire 的 additional_tools/mcp_list_tools preamble 项不计入(与 #453 clamp 路径的约定一致,那边同样忽略),codex 会话仍会少这部分;如需计入可另开一票。

    PR 稍后贴在本票。

  2. ranxianglei commented on Sep 4, 2026

    @ranxianglei
    Owner

    🤖 ework agent · qwen3.8-27b

    [bot] 🏷 进展:实现完成,新测试全绿,全量套件核验中(沙箱磁盘写满导致一次中断,正在清理后复跑)。

    已完成:

    • src/server.ts:新增导出 countSystemAndToolsTokens(systemText, tools)(与 estimateInputTokens 同源计数,后者改为复用,行为不变);三条 wire 路径在 prepare 时把实际出站的 system+tools token 数存入 session.metadata.systemPromptTokens(anthropic = injectSystem 后的最终文本;openai = client system + compress prompt,且跳过 title-gen 旁路请求;responses = developer message 内容,仅 transform 成功时);
    • src/plugin.ts:面板调用改传该值(带 number 守卫),unprunedTokens 同步加同一量以保持 Session-only 推导同尺度;
    • 新测试 tests/issue532-panel-system-tokens.test.ts(4 项全过):
      • counter 单测(空安全、加性、与单串计数差 ≤ ceil 噪声);
      • 面板数学单测:systemPromptTokens 非零时 Sent = classified + sysPrompt,SysPrompt 行渲染,breakdown 各项和 == Sent total,Session-only = max(0, unpruned − sent);零值时 SysPrompt 行仍被跳过;
      • anthropic + openai 两条 plugin 集成路径:80k 字符 system(~20k tok)+ 40k 工具描述(~10k tok)的会话,面板出现 SysPrompt 行且值落在 [client system + tools, +compress prompt 上界] 区间,Sent ≥ 该区间下界。修复前面板对这种会话显示 Sent≈219(即票述症状),现在正确计入 ~30k。

    typecheck 干净。全量套件第一次跑 1035/1036,唯一失败项待定位(疑似与下面环境问题相关而非本改动引入)。随后沙箱磁盘写满(ENOSPC)打断了复核,清理空间后会复跑全套 + build,确认无回归即开 PR 并回贴链接。

  3. ranxianglei commented on Sep 4, 2026

    @ranxianglei
    Owner

    🤖 ework agent · qwen3.8-27b

    [bot] 🏷 修复完成 → PR: #534

    实现(与票面建议一致,按 wire 路径细化)

    src/server.ts:新增导出 countSystemAndToolsTokens(systemText, tools)(与 estimateInputTokens 同源计数,后者改为复用它、行为不变);三条 prepare 路径把实际出站的 system+tools token 数存入 session.metadata.systemPromptTokens:

    • anthropic:injectSystem 后的最终文本(注入时含 compress prompt);
    • openai:hoist 出的 client system + compress system prompt(sysParts),title-gen 旁路请求跳过(其自带的小 system 不得覆盖主会话值);
    • responses:developer message 内容,仅 transform 成功时。

    src/plugin.ts:handlePluginStatus 改传该值(带 number 守卫),替代硬编码的 0;unprununedTokens 同步加同一量,保持 Session-only 推导同尺度。

    为何不会重复计数:适配器把头 system 从消息投影里抽出(openaiToCore→{msgs, systemText}、Responses→systemParts),kernel breakdown 的 bd.system≈0 是设计使然——喂给 kernel 明确预留的 "host-measured system" 槽位(systemPromptTokens)恰好补上这块盲区,breakdown 五项之和 == Sent total 自动成立(自洽)。测出站文本而非原始输入,保证 bili 注入 compress prompt 时数值仍然真实。

    验收标准对照

    • ✅ 20k token system+tools:anthropic + openai 两条 plugin 集成测试各发 ~80k 字符 system(~20k tok)+ ~40k 工具描述(~10k tok)走真实代理,面板出现 SysPrompt 行且值落在 [client system+tools, +compress prompt 上界],Sent ≥ client system+tools(修复前这类会话显示 Sent≈219);
    • ✅ 自洽单测:systemPromptTokens 非零时 Sent = classified + sysPrompt,SysPrompt 行渲染,breakdown 各项和 == Sent total;零值时行仍被跳过(行为不变)。

    Pre-flight

    • npm run typecheck 干净;新测试 4/4 过;npm run build 成功;
    • 全量 npm test 1035/1036。唯一失败 launcher.test.ts "codex/claude resolve to themselves" 已验证为预先存在的环境相关失败:在未改动的 master(baf1ac5)上以独立 worktree 复跑,同样失败且报错一致(环境里 codex 装在绝对路径,resolver 返回 /usr/bin/codex,断言期望裸名 codex)。与本改动无关,按"小问题只报告不另开票"处理在此;若希望 CI 全绿可考虑让该断言容忍绝对路径解析。

    已知残留(已在 PR body 注明)

    Responses-API 的 preamble 项(additional_tools / mcp_list_tools)未计入——与现有 estimateInputTokens / #453 clamp 约定一致(它们也不计),相对真实 tool schema 占比很小,需要的话后续可补。

    合并请人工操作(规则禁止 Agent merge):#534

  4. ranxianglei commented on Sep 6, 2026

    @ranxianglei
    Owner

    已 review + 冲突已解:#425(host-credit arming)与 #534(systemPromptTokens arming)在 prepareOpenai/prepareResponses 的 snapshotMessages 前同一位置交叉,二者正交,合并保留双方(prepareAnthropic 自动合并已是双块)。plugin.ts 面板取 tokenCount: hostContextTokens ?? lastInputTokens(#425)+ systemPromptTokens(#532)组合。

    已推 merge commit 8cdf842 到 PR 分支(含最新 master)。Pre-flight:typecheck ✓ 1131/1133(2 个已知 plugin-agent 环境失败)build ✓。

    设计审查通过:countSystemAndToolsTokens 与 estimateInputTokens 同源复用(无第二套口径);openai 只计注入的 sysParts 避免与折叠视图 head system 双计;responses 只计注入的 devContent;title-gen 侧请求跳过防污染;unprunedTokens 同步加回保持 Session-only 推导单一尺度。测试 269 行含面板自洽性(行和=Sent 总)+ anthropic/openai e2e。

    可合并。

  5. ranxianglei commented on Sep 6, 2026

    @ranxianglei
    Owner

    🤖 ework agent · qwen3.8-27b

    [bot] 🏷 收到。已把 PR head 的 8cdf842 拉到本地核对,与你描述一致:

    PR 状态 open、mergeable=true。合并按规则只能人工操作(Agent 禁止 merge):#534 —— 你点合并后 CI 会自动发版流程照常,这边无需再动。

  6. added a commit that references this issue on Sep 6, 2026
  7. ranxianglei commented on Sep 6, 2026

    @ranxianglei
    Owner

    已修复并合并:PR #534(merge 3eb918e)。countSystemAndToolsTokens 统一口径,anthropic/openai/responses 三 wire 在 prepare 阶段测量出站 system+tools,面板 SysPrompt 行恢复渲染。issue 之所以未自动关闭:PR 标题里 '(#532)' 是纯引用,无 Closes 关键词。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingp2

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions