Skip to content

fix(hermes): harden attribution and database reads - #66

Merged
choi138 merged 11 commits into
mainfrom
fix/hermes-usage-attribution
Aug 4, 2026
Merged

fix(hermes): harden attribution and database reads#66
choi138 merged 11 commits into
mainfrom
fix/hermes-usage-attribution

Conversation

@choi138

@choi138 choi138 commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • add validated SQLite read snapshots that preserve live WAL data and fall back to immutable reads for checkpointed databases in read-only directories
  • split Hermes ledger increments into model-specific events, retaining mixed and unattributed residuals across restarts
  • allocate catalog-derived and reported costs to their correct model portions, and surface unattributed usage in app and agent snapshots

Root cause

Hermes session totals can combine several session_model_usage rows, but the ledger previously kept only a single optional session model. It also priced every model with a catalog entry before distributing the reported-cost remainder, which distorted per-model costs. Separately, SQLite could fail to open a checkpointed database in a non-writable directory even though no live sidecars were required.

Impact

Hermes totals remain unchanged while model and cost breakdowns stay accurate. Read-only checkpointed databases and live WAL databases are handled without dropping current usage.

Validation

  • SwiftFormat
  • SwiftLint strict
  • 439 macOS Xcode tests
  • 121 SwiftPM tests
  • toki-agent Release build

Summary by CodeRabbit

  • 개선 사항
    • Hermes 사용량을 모델별 토큰과 비용으로 더욱 정확하게 집계합니다.
    • 모델 사용 시점의 가격을 반영해 비용 계산의 일관성을 높였습니다.
    • 모델을 확인할 수 없는 사용량은 ‘Mixed / Unattributed’로 분류합니다.
    • 토큰 없이 비용만 기록된 이벤트도 통계와 내보내기에 포함합니다.
    • 데이터베이스 변경을 감지해 안전한 읽기와 재시도를 지원합니다.
    • 세션별 활동 이벤트를 정확하게 통합하고 정렬합니다.
    • 화면, CSV, JSON에서 모델명이 일관되게 표시됩니다.

@choi138
choi138 marked this pull request as ready for review July 30, 2026 10:25
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@choi138, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9477706f-15d1-4d48-9553-fbfe48991484

📥 Commits

Reviewing files that changed from the base of the PR and between 0f82e2e and 30f7e04.

📒 Files selected for processing (15)
  • .gitignore
  • Sources/TokiAgentCore/AgentSnapshotBuilder.swift
  • Sources/TokiSyncProtocol/SnapshotValidation.swift
  • Sources/TokiSyncProtocol/UsageSnapshot.swift
  • Sources/TokiUsageReaders/HermesUsageAttribution.swift
  • Sources/TokiUsageReaders/HermesUsageResolver.swift
  • Sources/TokiUsageReaders/ModelPricing.swift
  • Tests/TokiAgentTests/AgentSnapshotModelAttributionTests.swift
  • Tests/TokiSyncProtocolTests/SnapshotCipherTests.swift
  • Tests/TokiSyncProtocolTests/SyncSecurityTests.swift
  • Toki/Infrastructure/RemoteSync/RemoteUsageMapper.swift
  • TokiTests/Claude5ModelPricingBehaviorTests.swift
  • TokiTests/HermesPricingRefreshTests.swift
  • TokiTests/HermesUsageLedgerTests.swift
  • TokiTests/RemoteUsageReaderTests.swift

Walkthrough

Hermes 사용량 읽기를 SQLite 스냅샷 기반으로 변경했습니다. 모델별 토큰과 비용 귀속, 가격 산정 시각, 원장 baseline, 미귀속 이벤트 집계를 추가했습니다. 원격 스냅샷 비용 필드와 관련 회귀 테스트도 확장했습니다.

Changes

Hermes 사용량 파이프라인

Layer / File(s) Summary
SQLite 스냅샷 읽기와 활동 이벤트
Sources/TokiUsageReaders/HermesSQLiteConnection.swift, Sources/TokiUsageReaders/HermesReader.swift, TokiTests/HermesReaderTests.swift
읽기 전용 연결, schema 검사, immutable fallback, WAL 상태 검증을 추가했습니다. 활동 이벤트를 세션과 시각별로 병합하고 모델 키를 정렬합니다.
관측값과 모델별 비용 해결
Sources/TokiUsageReaders/HermesUsageObservation.swift, Sources/TokiUsageReaders/HermesUsageResolver.swift, Sources/TokiUsageReaders/HermesUsageCostBreakdown.swift
모델별 카운터, 보고 비용, 가격 산정 시각을 검증하고 비용 해결 결과에 저장합니다. 모델별 비용 합계와 델타를 계산합니다.
모델별 원장 이벤트와 비용 배분
Sources/TokiUsageReaders/HermesUsageAttribution.swift, Sources/TokiUsageReaders/HermesUsageLedger.swift, Sources/TokiUsageReaders/HermesUsageLedgerSupport.swift, Sources/TokiUsageCore/RawTokenUsage.swift, TokiTests/HermesUsageLedgerTests.swift
모델별 토큰 델타를 원장 이벤트로 변환합니다. 보고 비용과 파생 비용을 모델별로 배분하고 baseline에 저장합니다.
사용량 집계와 원격 이벤트 검증
Toki/Domain/Usage/*, Toki/Features/UsagePanel/PanelStatComponents.swift, Sources/TokiAgentCore/AgentSnapshotBuilder.swift, Sources/TokiSyncProtocol/*, Toki/Infrastructure/RemoteSync/RemoteUsageMapper.swift, TokiTests/*, Tests/TokiAgentTests/*
모델이 없는 이벤트를 Mixed / Unattributed로 집계하고 비용 전용 이벤트를 보고서와 원격 스냅샷에 포함합니다. 내보내기, 패널 표시, 원격 매핑, 가격 갱신 및 재시작 동작을 검증합니다.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HermesReader
  participant HermesSQLiteConnection
  participant HermesUsageResolver
  participant HermesUsageLedger
  participant RemoteUsageMapper
  participant UsageReportModelStats
  HermesReader->>HermesSQLiteConnection: SQLite 스냅샷에서 사용량 읽기
  HermesSQLiteConnection-->>HermesReader: 최신 데이터베이스 행 반환
  HermesReader->>HermesUsageResolver: 모델별 사용량과 pricingTimestamp 전달
  HermesUsageResolver->>HermesUsageLedger: 모델별 비용과 카운터 적용
  HermesUsageLedger-->>RemoteUsageMapper: 토큰·비용 이벤트 전달
  RemoteUsageMapper-->>UsageReportModelStats: 미귀속 및 비용 전용 이벤트 전달
  UsageReportModelStats-->>UsageReportModelStats: Mixed / Unattributed로 집계
Loading

Possibly related PRs

  • choi138/toki#41: HermesReader와 모델별 사용량 분석 경로를 확장한 변경입니다.
  • choi138/toki#62: Hermes 비용 해결과 가격 산정 시각에 직접 연결된 변경입니다.
  • choi138/toki#18: 토큰 이벤트와 사용량 보고 경로를 추가한 변경입니다.

Poem

토끼가 모델별 토큰을 세고,
스냅샷은 시각을 남겨요.
비용은 원장에 나뉘고,
미귀속 항목도 이름을 얻어요.
깡총, Hermes가 정리됐어요!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 Hermes 사용량 귀속 강화와 데이터베이스 읽기 개선이라는 PR의 주요 변경 사항을 정확하고 간결하게 요약합니다.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/hermes-usage-attribution

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.

@choi138

choi138 commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f803fbcf76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/TokiUsageReaders/HermesSQLiteConnection.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesUsageAttribution.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesUsageAttribution.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesUsageAttribution.swift
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 30, 2026

@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 (1)
Toki/Domain/Usage/UsageReportModelStats.swift (1)

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

미귀속 모델 식별자를 공유 상수로 노출하세요.

unattributedModelID는 이 파일에서만 private으로 정의됩니다. 동일한 문자열 "Mixed / Unattributed"TokiTests/UsageServiceBehaviorTests.swift(라인 251), Tests/TokiAgentTests/AgentSnapshotModelAttributionTests.swift(라인 41)에 하드코딩되어 있습니다. 값을 변경하면 테스트는 실패하지 않고 낡은 문자열을 계속 비교합니다. 이 식별자는 집계 키이면서 화면에 표시되는 문자열입니다. 공유 가능한 상수로 노출하고 테스트와 표시 계층이 그 상수를 참조하게 하세요.

또한 표시 문자열을 데이터 키로 사용하면 실제 모델 ID와 충돌할 수 있습니다. 키와 표시 문자열을 분리하는 방안도 검토하세요.

Also applies to: 132-132

🤖 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 `@Toki/Domain/Usage/UsageReportModelStats.swift` at line 5, Expose the
unattributed model identifier through a shared, non-private constant associated
with UsageReportModelStats, and update all tests and presentation code to
reference it instead of hardcoding the string. Separate the aggregation key from
the user-facing “Mixed / Unattributed” label so a real model ID cannot collide
with the display value.
🤖 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 `@TokiTests/HermesPricingRefreshTests.swift`:
- Line 437: Rename the test method
test_hermesReader_allocatesInitialDerivedCostsAtModelUsagePricingInstant to
reflect that HermesReader prices usage at read time, such as
test_hermesReader_allocatesInitialDerivedCostsAtReadTimePricingInstant. Keep the
test behavior and assertions unchanged.

---

Nitpick comments:
In `@Toki/Domain/Usage/UsageReportModelStats.swift`:
- Line 5: Expose the unattributed model identifier through a shared, non-private
constant associated with UsageReportModelStats, and update all tests and
presentation code to reference it instead of hardcoding the string. Separate the
aggregation key from the user-facing “Mixed / Unattributed” label so a real
model ID cannot collide with the display value.
🪄 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 Plus

Run ID: c2d10f80-2009-482c-a276-60920415d929

📥 Commits

Reviewing files that changed from the base of the PR and between 2bde5c3 and 538acb8.

📒 Files selected for processing (14)
  • Sources/TokiUsageReaders/HermesReader.swift
  • Sources/TokiUsageReaders/HermesSQLiteConnection.swift
  • Sources/TokiUsageReaders/HermesUsageAttribution.swift
  • Sources/TokiUsageReaders/HermesUsageCostBreakdown.swift
  • Sources/TokiUsageReaders/HermesUsageLedger.swift
  • Sources/TokiUsageReaders/HermesUsageLedgerSupport.swift
  • Sources/TokiUsageReaders/HermesUsageObservation.swift
  • Sources/TokiUsageReaders/HermesUsageResolver.swift
  • Tests/TokiAgentTests/AgentSnapshotModelAttributionTests.swift
  • Toki/Domain/Usage/UsageReportModelStats.swift
  • TokiTests/HermesPricingRefreshTests.swift
  • TokiTests/HermesReaderTests.swift
  • TokiTests/HermesUsageLedgerTests.swift
  • TokiTests/UsageServiceBehaviorTests.swift

Comment thread TokiTests/HermesPricingRefreshTests.swift

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 538acb8a8e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/TokiUsageReaders/HermesUsageResolver.swift
Comment thread Sources/TokiUsageReaders/HermesReader.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesReader.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesSQLiteConnection.swift
@choi138

choi138 commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2bf7dfb0a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/TokiUsageReaders/HermesUsageResolver.swift Outdated
Comment thread Toki/Domain/Usage/UsageReportModelStats.swift Outdated
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2bf7dfb0a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/TokiUsageReaders/HermesUsageAttribution.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesUsageResolver.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesUsageResolver.swift Outdated
@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 31, 2026

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/TokiUsageReaders/HermesUsageLedger.swift (1)

221-261: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

초기 zero-token 비용 관찰값을 기록하지 않도록 개선하십시오.

applyInitialobservation.counters.totalTokens > 0에서 false를 반환하면 기준선과 미귀속 사용량 모두 저장되지 않습니다. validateHermesUsageObservationcost >= 0만 요구하므로 costs > 0인 zero-token 관찰값은 유효하지만, 현재는 이 비용이 Ledger와 HermesUsageLedgerStatus.unattributedTokens에서 모두 누락됩니다. 첫 호출에서 candidate.baselines[identifier] = currentBaseline을 먼저 저장한 뒤, cost-only 초기 사용량을 이벤트 또는 미귀속 경로로 처리하도록 맞추는 것이 필요합니다.

🤖 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 `@Sources/TokiUsageReaders/HermesUsageLedger.swift` around lines 221 - 261,
Update applyInitial so zero-token observations with positive cost are retained:
store candidate.baselines[identifier] before the early-return logic, and allow
cost-only initial observations to proceed through the existing dated event or
addUnattributed path. Continue returning false only when the observation has
neither token usage nor reportable cost, while preserving normal token-bearing
behavior.
🤖 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.

Outside diff comments:
In `@Sources/TokiUsageReaders/HermesUsageLedger.swift`:
- Around line 221-261: Update applyInitial so zero-token observations with
positive cost are retained: store candidate.baselines[identifier] before the
early-return logic, and allow cost-only initial observations to proceed through
the existing dated event or addUnattributed path. Continue returning false only
when the observation has neither token usage nor reportable cost, while
preserving normal token-bearing behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 95363901-f5b9-4307-8b00-f2f2b6b555e4

📥 Commits

Reviewing files that changed from the base of the PR and between 538acb8 and 1522601.

📒 Files selected for processing (20)
  • Sources/TokiUsageCore/RawTokenUsage.swift
  • Sources/TokiUsageReaders/HermesReader.swift
  • Sources/TokiUsageReaders/HermesSQLiteConnection.swift
  • Sources/TokiUsageReaders/HermesUsageAttribution.swift
  • Sources/TokiUsageReaders/HermesUsageCostBreakdown.swift
  • Sources/TokiUsageReaders/HermesUsageLedger.swift
  • Sources/TokiUsageReaders/HermesUsageLedgerSupport.swift
  • Sources/TokiUsageReaders/HermesUsageResolver.swift
  • Tests/TokiAgentTests/AgentSnapshotModelAttributionTests.swift
  • Toki/Domain/Usage/UsageData.swift
  • Toki/Domain/Usage/UsageReportBuilder.swift
  • Toki/Domain/Usage/UsageReportExport.swift
  • Toki/Domain/Usage/UsageReportModelStats.swift
  • Toki/Features/UsagePanel/PanelStatComponents.swift
  • TokiTests/HermesPricingRefreshTests.swift
  • TokiTests/HermesReaderTests.swift
  • TokiTests/UsageExportTests.swift
  • TokiTests/UsageOriginAggregationTests.swift
  • TokiTests/UsageProjectTimelineReportTests.swift
  • TokiTests/UsageServiceBehaviorTests.swift
🚧 Files skipped from review as they are similar to previous changes (7)
  • Toki/Domain/Usage/UsageReportModelStats.swift
  • Tests/TokiAgentTests/AgentSnapshotModelAttributionTests.swift
  • Sources/TokiUsageReaders/HermesUsageAttribution.swift
  • Sources/TokiUsageReaders/HermesUsageLedgerSupport.swift
  • Sources/TokiUsageReaders/HermesUsageCostBreakdown.swift
  • Sources/TokiUsageReaders/HermesUsageResolver.swift
  • Sources/TokiUsageReaders/HermesReader.swift

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1522601472

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/TokiUsageCore/RawTokenUsage.swift
Comment thread Sources/TokiUsageReaders/HermesReader.swift
Comment thread Sources/TokiUsageReaders/HermesUsageLedger.swift Outdated
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 31, 2026
@choi138

choi138 commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

CodeRabbit의 outside-diff 지적도 26e9966에서 반영했습니다. 초기 zero-token·positive-cost 관찰값을 baseline에 보존하고, 날짜가 있으면 cost-only 이벤트로 기록하며 날짜를 확정할 수 없으면 carryover로 저장합니다. 토큰 변화 없이 비용만 증가하는 증분과 모델별 reported cost-only delta도 함께 보존하도록 회귀 테스트를 추가했습니다.

@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 31, 2026
@choi138

choi138 commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26e9966307

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/TokiUsageReaders/HermesUsageResolver.swift
Comment thread Sources/TokiUsageCore/RawTokenUsage.swift
Comment thread Sources/TokiUsageReaders/HermesUsageLedger.swift Outdated
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0f82e2ecc5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/TokiAgentCore/AgentSnapshotBuilder.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesUsageResolver.swift Outdated
Comment thread Sources/TokiUsageReaders/HermesUsageResolver.swift Outdated
@choi138

choi138 commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 06631362fb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +107 to +109
let residual = counters.subtracting(combinedCounters)
if residual.totalTokens > 0 {
parts.append(HermesUsageEventPart(model: nil, counters: residual))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Attribute consistent residuals to the resolved model

When the session counters exceed a partial session_model_usage breakdown but the session and every detail row agree on one model, HermesUsageResolver preserves that model in observation.model, yet this branch assigns the residual counters to nil. For example, a 150-token session and a 100-token detail row both labeled model A are reported as A=100 and Mixed / Unattributed=50, also misassigning the residual cost and activity. Use the resolved model for the residual when it is non-nil, reserving nil for genuinely ambiguous sessions, and add focused partial-detail reader coverage.

AGENTS.md reference: AGENTS.md:L38-L40

Useful? React with 👍 / 👎.

@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Jul 31, 2026
choi138 added 4 commits August 4, 2026 16:07
The custom billing provider reports kr/claude-opus-5 as its own catalog entry
rather than as a provider prefix on claude-opus-5, so usage under that ID was
left unpriced. Add an explicit exact key at the claude-opus-5 rates.

Keep the entry exact-only so it cannot lend its rates to future tiers, and
cover that slash-bearing keys stay independent of prefix stripping.
Pick up the lane-based Codex review loop from #68 so the skill files are
tracked here instead of lingering as a stale untracked copy.
Hermes, omo, and senpi write task logs and plans into the working tree, which
left dozens of untracked files in every status check and risked committing
local agent state.
When session counters exceeded a partial session_model_usage breakdown, the
residual was always emitted with a nil model. A 150-token session with a
100-token detail row on the same model was therefore reported as 100 tokens for
that model and 50 as Mixed / Unattributed, and the residual cost followed the
same wrong split.

The resolver leaves the observation model non-nil only when the session and
every detail row agree on one model, so use it for the residual and reserve nil
for genuinely ambiguous sessions. Merge into the existing part for that model so
its pricing counters are not charged twice, and keep emitting an unattributed
carrier when reported cost belongs to no model.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 4, 2026
@choi138
choi138 merged commit 772e04a into main Aug 4, 2026
7 checks passed
@choi138
choi138 deleted the fix/hermes-usage-attribution branch August 4, 2026 07:40
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