Skip to content

fix(compact): 修复会话压缩系统六项缺陷并扩展两项可配置性#270

Merged
phantom5099 merged 10 commits into
1024XEngineer:mainfrom
wynxing:codex/taskstate-compact-pr
Apr 14, 2026
Merged

fix(compact): 修复会话压缩系统六项缺陷并扩展两项可配置性#270
phantom5099 merged 10 commits into
1024XEngineer:mainfrom
wynxing:codex/taskstate-compact-pr

Conversation

@wynxing

@wynxing wynxing commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

会话压缩(compact)系统存在 6 个功能缺陷和 2 个可配置性不足,本 PR 逐一修复并扩展。

缺陷修复

ID 缺陷 修复
D3 normalizeTaskStateListstrings.ToLower 去重,误杀大小写不同项(如 React/react) 改为精确匹配去重
D5 LLM 返回 "progress": "item" 代替数组时 json.Unmarshal 直接报错 引入 tolerantSummaryResponse + coerceStringArray 容忍解析
D4 sanitizePromptTaskStateText 将所有空白(含换行)折叠为单空格,丢失结构 按行拆分清洗,保留 \n,仅折叠行内空白和控制字符
D2 Reactive compact 仅尝试一次,provider 持续返回 context-too-long 时直接报错 boolint 计数器,最多 3 次逐步减半 ManualKeepRecentMessages 降级重试
D6 Transcript 文件在 .neocode/projects/ 下无限累积 新增 Cleanup 方法,保留最近 50 个,删除最旧文件
D1 Metrics 仅有 BeforeChars/AfterChars,与 token 限制脱节 Metrics 新增 BeforeTokens,从 session 的 TokenInputTotal 填充

可配置性扩展

ID 改动
O1 microCompactRetainedToolSpans 从硬编码常量 2 改为 CompactConfig.MicroCompactRetainedToolSpans 配置项
O2 新增 CompactConfig.MaxArchivedPromptChars,超限时在消息边界截断 archived material 并前置提示

Test plan

  • go build ./... 编译通过
  • go test ./... 全部通过
  • gofmt -w ./cmd ./internal 格式化通过
  • 新增测试:task_state_test.go(D3)、compact_generator_test.go(D5)、transcript_store_test.go(D6)、runtime_internal_helpers_test.go(D2)
  • 更新测试:source_task_state_test.go(D4)、runtime_test.go(D2 行为变更)、microcompact_test.go(O1 签名变更)

wynxing and others added 4 commits April 14, 2026 08:50
合并 main 分支引入的 decodeCompactSummaryResponse 严格解码、
extractJSONObjectCandidate 候选遍历、ClampTaskStateBoundaries
边界限幅,同时保留本分支的容忍解析与 reactive compact 降级策略。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@codecov

codecov Bot commented Apr 14, 2026

Copy link
Copy Markdown

fennoai[bot]

This comment was marked as outdated.

@wynxing

wynxing commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator Author

/simplify

@fennoai

fennoai Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Result

已按触发评论完成:读取历史评论、评估未解决 review comment、修复值得修复的问题,并执行代码简化。

What I changed

  • 修复 internal/context/source_task_state.go:在将 TaskState 渲染到 bullet 风格 prompt 前转义换行,避免多行注入破坏 prompt 结构。
  • 修复 internal/runtime/compact_generator.goextractJSONObject 候选筛选改为使用与最终解析一致的严格解码(decodeCompactSummaryResponse),严格失败时继续扫描后续候选。
  • 简化(保持行为不变):
    • renderTaskStateSection 改为字面量切片构造
    • parseCompactSummaryOutput 改为结构体字面量填充
    • coerceStringArray 合并重复 return nil 分支
    • validCompactSummaryJSON 去除单元素 strings.Join
  • 新增/更新回归测试:
    • internal/context/source_task_state_test.go
    • internal/runtime/compact_generator_test.go

Validation

  • gofmt -w(变更文件)
  • go build ./...
  • go test ./...

Git

Notes

  • 未执行额外超出触发评论范围的改动。

View job run

xgopilot and others added 2 commits April 14, 2026 01:54
- escape TaskState line breaks before prompt rendering
- use strict decoder during compact JSON candidate scan
- add regressions for injection-safe rendering and strict-candidate fallback
- apply low-risk simplifications in touched files

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Yumiue <188874804+Yumiue@users.noreply.github.com>
fix(compact): address review findings and simplify parsing/rendering
@pionxe

pionxe commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator

/review

fennoai[bot]

This comment was marked as outdated.

@wynxing

wynxing commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator Author

/simplify

@fennoai

fennoai Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Result

已完成你触发评论要求的全部步骤:读取历史评论、评估未解决 review comment、修复值得修复的问题,并执行代码简化。

What I changed

  • 已评估历史评论中的未解决 code review,确认并修复以下问题:
    • internal/context/compact_prompt.gotruncateArchivedContent 之前会在拼接截断前缀后超出 max_archived_prompt_chars
    • 修复后将截断提示前缀纳入预算,保证输出长度严格不超过配置上限;并处理极小预算分支。
  • 新增测试覆盖:
    • internal/context/compact_prompt_test.go
    • TestTruncateArchivedContentHonorsStrictMaxChars
    • TestTruncateArchivedContentHandlesTinyBudget
  • 按要求运行了 code-simplifier 子代理,并吸收等价简化:
    • BuildCompactPrompt 的拼接流程拆分为 writeCompactPromptIntrowriteCompactPromptMetadatawriteTaggedBlock,提升可读性且不改变行为。

Validation

  • gofmt -w internal/context/compact_prompt.go internal/context/compact_prompt_test.go
  • go build ./...
  • go test ./...

Git

Not done

  • 未处理与本次触发指令无关的额外改动请求。

View job run

xgopilot and others added 2 commits April 14, 2026 02:47
…sembly

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Yumiue <188874804+Yumiue@users.noreply.github.com>
fix(compact): enforce strict archived prompt cap
@phantom5099

Copy link
Copy Markdown
Collaborator

/review

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found 2 noteworthy issues in this PR.

Also note: behavior/docs drift appears in reactive compact retry semantics and compact_done payload (before_tokens) but those doc files are not part of this diff, so I’m leaving that as a summary note instead of inline comments.

MaxSummaryChars int `yaml:"max_summary_chars,omitempty"`
MicroCompactDisabled bool `yaml:"micro_compact_disabled,omitempty"`
MicroCompactRetainedToolSpans int `yaml:"micro_compact_retained_tool_spans,omitempty"`
MaxArchivedPromptChars int `yaml:"max_archived_prompt_chars,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CompactConfig adds micro_compact_retained_tool_spans / max_archived_prompt_chars, but the YAML persistence mapping is not updated (persistedCompactConfig, newPersistedContextConfig, fromPersistedContextConfig in internal/config/loader.go). With KnownFields(true), users configuring these keys will hit unknown-field parse failures, and values also cannot round-trip through save/load.

Please wire both fields through loader read/write structs and add config load/save tests for these keys.

// cloneStringSlice 复制字符串切片,避免结果复用解析对象的底层数组。
func cloneStringSlice(items []string) []string {
return append([]string(nil), items...)
// coerceStringArray 尝试将 json.RawMessage 解析为 []string,容忍单个 string 值。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coerceStringArray currently downgrades type errors (number/object/bool/malformed array) to nil, which means malformed model output can silently clear durable task_state list fields (e.g. user_constraints, blockers) while still passing overall parsing.

Consider failing parse on non-[]string / non-string values (or preserving previous field values on invalid types) to avoid silent state loss.

@wynxing

wynxing commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator Author

/simplify

@fennoai

fennoai Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Result

已按本次 /simplify 指令完成:读取历史评论、处理未解决 review comment、修复值得修复的问题,并执行代码简化与验证。

What I changed

  • 修复 review comment 1(配置持久化缺失):
    • internal/config/loader.gopersistedCompactConfignewPersistedContextConfigfromPersistedContextConfig 接入:
      • micro_compact_retained_tool_spans
      • max_archived_prompt_chars
  • 修复 review comment 2(静默丢失 task_state 风险):
    • internal/runtime/compact_generator.gocoerceStringArray 改为返回错误;仅允许 []string / string / null,其余类型直接报错,避免把非法模型输出静默降级为 nil
    • parseCompactSummaryOutput 对每个列表字段显式处理错误并中断解析。
  • 测试补齐:
    • internal/config/loader_test.go 新增:
      • TestLoaderLoadsCompactExtendedFields
      • TestLoaderSaveRoundTripsCompactExtendedFields
    • internal/runtime/compact_generator_test.go 更新:
      • 非法类型(number/object)从“容忍并置空”改为“解析失败”预期。
  • 代码简化(按要求调用 code-simplifier 子代理并吸收可用结果):
    • assembleProviders 合并为统一 section 迭代,减少重复逻辑。
    • loader_test 引入 writeLoaderConfig 测试辅助函数,减少重复样板。

Validation

  • gofmt -w internal/config/loader.go internal/config/loader_test.go internal/runtime/compact_generator.go internal/runtime/compact_generator_test.go
  • go build ./...
  • go test ./...

Git

Not done

  • 无额外未完成项。

View job run

xgopilot and others added 2 commits April 14, 2026 03:18
- wire compact extended fields through loader persistence
- reject invalid compact task_state list value types to avoid silent data loss
- add loader/load-save tests for new compact keys
- simplify loader provider assembly and loader tests helper

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Yumiue <188874804+Yumiue@users.noreply.github.com>
fix(compact): resolve unresolved review findings and harden parsing
@phantom5099 phantom5099 merged commit c2ce9c8 into 1024XEngineer:main Apr 14, 2026
2 checks passed
@wynxing wynxing deleted the codex/taskstate-compact-pr branch April 15, 2026 06:21
@fennoai fennoai Bot mentioned this pull request Apr 15, 2026
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.

4 participants