Skip to content
This repository was archived by the owner on Jul 30, 2026. It is now read-only.

fix(omp): parse title slot session transcripts - #120

Merged
makoMakoGo merged 2 commits into
personal/local-clientsfrom
codex/omp-title-slot-usage
Jul 5, 2026
Merged

fix(omp): parse title slot session transcripts#120
makoMakoGo merged 2 commits into
personal/local-clientsfrom
codex/omp-title-slot-usage

Conversation

@makoMakoGo

@makoMakoGo makoMakoGo commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • accept OMP session JSONL files with a leading fixed title slot before the session header
  • label advisor transcript files as OMP Advisor while keeping them under the OMP client
  • bump only the OMP parser revision so old OMP cache entries do not mask the new parse semantics

Root Cause

OMP 16.3.x writes a fixed title slot as the first JSONL record. Tokscale required the first non-empty record to be type=session, so affected OMP transcripts, including __advisor.jsonl, parsed as empty files even when later assistant rows contained usage tokens.

Validation

  • cargo fmt --check
  • cargo test -p tokscale-core sessions::pi:: -- --nocapture
  • cargo test -p tokscale-core adapters::omp:: -- --nocapture
  • cargo test -p tokscale-core
  • cargo build --release -p tokscale-cli
  • tokscale --no-spinner --client omp --today --json

Summary by cubic

Fix OMP session parsing by skipping the new leading title slot and correctly labeling advisor transcripts. Also versions the OMP parser on all OMP units to avoid stale cache masking.

  • Bug Fixes
    • Parse OMP 16.3.x JSONL when a validated title slot is the first record; reject invalid or duplicate title slots, then read the session normally.
    • Tag advisor transcripts (__advisor.jsonl and __advisor.*.jsonl) as "OMP Advisor" while keeping them under the OMP client.

Written for commit cdfcbc9. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • 新功能

    • 改进了 OMP/PI 会话解析,能更准确识别首行标题信息,并自动跳过符合规范的标题行继续解析后续内容。
    • 对 OMP 子会话的标注规则进行了增强,__advisor 类文件会统一识别为 OMP Advisor
  • Bug 修复

    • 遇到不合法的标题槽位时,解析结果现在会返回空,避免生成错误会话数据。

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

本次变更为 OmpAdapter 的扫描结果附加解析器版本标记,并在 Pi/OMP JSONL 会话解析中引入更细粒度的首行识别逻辑:新增行类型判定、title 槽位严格校验、advisor 标签归一化,以及跳过合法 title 首行的解析主循环调整,附带三条新测试。

Changes

OMP 标题槽位与解析器版本

Layer / File(s) Summary
OmpAdapter 解析器版本标记
crates/tokscale-core/src/adapters/omp.rs
新增 OMP_TITLE_SLOT_REVISION 常量,discover 返回前为每个 SourceUnit 附加 ParserVersion(Omp, revision) 标记。
行类型与 title 槽位数据结构
crates/tokscale-core/src/sessions/pi.rs
新增 PiEntryKind 用于判定 JSONL 行类型,OmpTitleSlot 用于反序列化并校验 title 槽位字段。
首行 header 解析与主循环整合
crates/tokscale-core/src/sessions/pi.rs
新增 PiHeaderParse 枚举与 parse_pi_header_line 系列函数,基于 simd_json 判定并严格校验首行;parse_pi_format_file 主循环用 saw_omp_title_slot 标记跳过合法 title 首行,无效 header 直接返回空结果。
Advisor 标签归一化与测试
crates/tokscale-core/src/sessions/pi.rs
新增 normalize_omp_advisor_label,识别 __advisor 系列文件名 stem 并覆盖 agent 标注;新增测试覆盖 title 跳过、无效 title、advisor 标签场景。

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Reader as parse_pi_format_file
  participant Parser as parse_pi_header_line
  participant Slot as OmpTitleSlot 校验

  Reader->>Parser: 解析首行 JSONL
  Parser->>Slot: 校验 entry_type/v/updated_at
  Slot-->>Parser: 校验结果
  alt 有效 title 且客户端为 omp
    Parser-->>Reader: TitleSlot
    Reader->>Reader: 设置标记并跳过该行
  else 有效 session
    Parser-->>Reader: Session
  else 无效
    Parser-->>Reader: Invalid
    Reader-->>Reader: 返回空 Vec
  end
Loading

Poem

兔子啃着新版本号,一蹦一跳解 JSON,
title 槽位藏首行,严格校验不放松,
__advisor 名字一出现,标签立刻换新颜,
测试三条守边关,代码干净又心安。🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了 OMP 会话解析对 title slot 记录的修复,且简洁明确。
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/omp-title-slot-usage

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@makoMakoGo
makoMakoGo marked this pull request as ready for review July 4, 2026 15:55
@makoMakoGo

Copy link
Copy Markdown
Owner Author

/juya review

@juya-review-bot juya-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

OpenCodeReview found 2 issue(s).

Comment thread crates/tokscale-core/src/sessions/pi.rs
Comment thread crates/tokscale-core/src/sessions/pi.rs Outdated
@codspeed-hq

codspeed-hq Bot commented Jul 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 27 untouched benchmarks


Comparing codex/omp-title-slot-usage (cdfcbc9) with personal/local-clients (60ec300)

Open in CodSpeed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
crates/tokscale-core/src/sessions/pi.rs (2)

265-286: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

三个 buffer 重填辅助函数存在重复样板代码。

parse_pi_line_kindparse_pi_session_header_lineparse_omp_title_slot_line 都重复了 buffer.clear(); buffer.extend_from_slice(trimmed.as_bytes()); 两行逻辑,可以抽取一个小helper(例如 fn refill_buffer(buffer: &mut Vec<u8>, trimmed: &str))以减少重复。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/sessions/pi.rs` around lines 265 - 286, The three
parsing helpers duplicate the same buffer refill steps, so extract the shared
`buffer.clear()` plus `buffer.extend_from_slice(trimmed.as_bytes())` logic into
a small helper and call it from `parse_pi_line_kind`,
`parse_pi_session_header_line`, and `parse_omp_title_slot_line` to reduce
repetition while keeping their existing parse behavior unchanged.

546-591: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

建议补充"重复 title 槽位"场景的测试。

现有测试覆盖了合法 title、非法 title、advisor 文件命名三种场景,但没有覆盖文件中出现两个连续 "type":"title" 行的情况(根据 saw_omp_title_slot 逻辑,第二个 title 行会因 allow_omp_title_slot 变为 false 而被判定为 Invalid,导致整份文件被丢弃)。这是 Line 369 状态机新增的边界条件,建议补充一条回归测试。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/sessions/pi.rs` around lines 546 - 591, Add a
regression test for the duplicate OMP title-slot edge case in
parse_omp_file/saw_omp_title_slot handling: create an input with two consecutive
"type":"title" lines followed by a valid session/message, and assert the file is
rejected (messages is empty) because allow_omp_title_slot becomes false on the
second title. Place the test alongside test_parse_omp_jsonl_skips_title_slot,
test_parse_omp_rejects_invalid_title_slot, and
test_parse_omp_advisor_transcript_sets_agent_label so the new state-machine
behavior is covered.
crates/tokscale-core/src/adapters/omp.rs (1)

12-20: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

建议补充对新 ParserVersion 标记的测试覆盖。

本次变更的核心目的是让旧缓存因解析器版本号变化而失效,但现有测试(omp_adapter_discovers_default_and_extra_jsonl)只校验了 fingerprint_policy,没有断言 unit.parser_version 确实等于 ParserVersion::new(ParserId::Omp, OMP_TITLE_SLOT_REVISION)。由于该机制正是本 PR 修复 bug 的关键路径(避免旧缓存掩盖新解析行为),建议补充一条直接断言,防止未来重构时该行为被静默破坏。

Also applies to: 32-36

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/adapters/omp.rs` around lines 12 - 20, The
OmpAdapter test coverage is missing a direct assertion that the parser version
changes with the new revision, so the current test only checks
fingerprint_policy and could miss regressions. Update the OmpAdapter test around
omp_adapter_discovers_default_and_extra_jsonl to also assert unit.parser_version
equals ParserVersion::new(ParserId::Omp, OMP_TITLE_SLOT_REVISION), using the
existing OmpAdapter and OMP_TITLE_SLOT_REVISION symbols to locate the behavior.
This should verify the cache-busting version path directly and protect against
future refactors silently breaking it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/tokscale-core/src/sessions/pi.rs`:
- Around line 27-45: Update the Pi session parser in Pi-related deserialization
so that a bad title-slot record does not invalidate the entire file;
specifically, adjust the `OmpTitleSlot`/initial-line parsing path in `pi.rs` so
malformed title metadata is skipped or treated as non-fatal, allowing the parser
to continue scanning for the next valid `session` or `message` entry instead of
returning `Invalid` for the whole session file.

---

Nitpick comments:
In `@crates/tokscale-core/src/adapters/omp.rs`:
- Around line 12-20: The OmpAdapter test coverage is missing a direct assertion
that the parser version changes with the new revision, so the current test only
checks fingerprint_policy and could miss regressions. Update the OmpAdapter test
around omp_adapter_discovers_default_and_extra_jsonl to also assert
unit.parser_version equals ParserVersion::new(ParserId::Omp,
OMP_TITLE_SLOT_REVISION), using the existing OmpAdapter and
OMP_TITLE_SLOT_REVISION symbols to locate the behavior. This should verify the
cache-busting version path directly and protect against future refactors
silently breaking it.

In `@crates/tokscale-core/src/sessions/pi.rs`:
- Around line 265-286: The three parsing helpers duplicate the same buffer
refill steps, so extract the shared `buffer.clear()` plus
`buffer.extend_from_slice(trimmed.as_bytes())` logic into a small helper and
call it from `parse_pi_line_kind`, `parse_pi_session_header_line`, and
`parse_omp_title_slot_line` to reduce repetition while keeping their existing
parse behavior unchanged.
- Around line 546-591: Add a regression test for the duplicate OMP title-slot
edge case in parse_omp_file/saw_omp_title_slot handling: create an input with
two consecutive "type":"title" lines followed by a valid session/message, and
assert the file is rejected (messages is empty) because allow_omp_title_slot
becomes false on the second title. Place the test alongside
test_parse_omp_jsonl_skips_title_slot,
test_parse_omp_rejects_invalid_title_slot, and
test_parse_omp_advisor_transcript_sets_agent_label so the new state-machine
behavior is covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9117957c-3ec4-405d-87e9-67e2ccf14ca8

📥 Commits

Reviewing files that changed from the base of the PR and between 60ec300 and 1f7243f.

📒 Files selected for processing (2)
  • crates/tokscale-core/src/adapters/omp.rs
  • crates/tokscale-core/src/sessions/pi.rs

Comment thread crates/tokscale-core/src/sessions/pi.rs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 2 files

Re-trigger cubic

@makoMakoGo makoMakoGo left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Reviewed. No blocking findings.

The change is narrowly scoped and matches the stated intent: OMP discovery now bumps only the OMP parser revision, title-slot handling is restricted to OMP before the session header, malformed or duplicate title slots are treated as hard parse rejection, and advisor transcript labeling stays under the OMP client. That strict rejection behavior is consistent with this fork's preference for clean parser semantics over silent recovery.

CI on the PR head is green for Core CI, Test & Coverage, Build Native, and CodSpeed.

@makoMakoGo

Copy link
Copy Markdown
Owner Author

Handled the latest review comment.

No code change is needed for the OmpTitleSlot note. Keeping title, updatedAt, and pad as required fields is intentional strict parsing for OMP's fixed title slot shape. If OMP removes one of those fields in a future format, that should be treated as a parser semantics change with a new parser revision, not preemptively relaxed here.

I also re-checked local real data using the fixed 2026-07-04 window across the default OMP root and the configured extra scan root. Raw JSONL totals matched the installed tokscale output exactly for input, output, cache read/write, reasoning, and nonzero message count.

@makoMakoGo
makoMakoGo merged commit 6712cb8 into personal/local-clients Jul 5, 2026
9 checks passed
@makoMakoGo
makoMakoGo deleted the codex/omp-title-slot-usage branch July 5, 2026 04:30
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant