Add CLIProxyAPI cost attribution - #2457
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c82dab5a6d
ℹ️ 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".
|
Codex review: needs real behavior proof before merge. Reviewed July 30, 2026, 7:37 AM ET / 11:37 UTC. ClawSweeper reviewWhat this changesAdds CLIProxyAPI request-log and telemetry attribution so Claude Code traffic routed through a proxy can be assigned to a confirmed upstream provider, priced, cached, and displayed in CodexBar’s Usage & Spend dashboard. Merge readiness⛔ Blocked until real behavior proof is added - 5 items remain Keep this PR open for maintainer review and real behavior proof. The latest branch addresses the earlier data-loss and attribution findings with focused regressions, but this is a large new provider-attribution and persistent-cache feature whose production queue, credentials, and dashboard result have not yet been demonstrated in a redacted live setup. Priority: P2 Review scores
Verification
How this fits togetherCodexBar scans local provider histories, applies provider pricing, and aggregates the results into its Usage & Spend dashboard. This change introduces CLIProxyAPI logs and destructive telemetry-queue records as an additional evidence source before usage is assigned to Claude or Codex totals. flowchart LR
A[Claude Code session history] --> C[Cost usage scanner]
B[CLIProxyAPI logs and telemetry queue] --> D[Attribution resolver]
C --> D
D --> E[Provider pricing and cache]
E --> F[Spend dashboard]
F --> G[Attributed provider totals]
Decision needed
Why: The patch is a new product surface rather than a repair to an established contract: it adds connection settings, collection of a destructive external telemetry queue, persisted attribution state, and changes to how historical spend is assigned across providers. Before merge
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Land only after a maintainer sponsors the CLIProxyAPI integration boundary and the contributor supplies redacted live evidence that a routed Claude Code session is collected once, attributed to the correct upstream model, and rendered in the expected separate dashboard source without exposing credentials or account details. Do we have a high-confidence way to reproduce the issue? Not applicable as a bug reproduction: this PR adds a new CLIProxyAPI integration. The contributor has supplied extensive fixture-based coverage, but the PR explicitly confirms that no real routed session has been demonstrated on the current head. Is this the best way to solve the issue? Unclear. The branch has addressed the concrete review defects surfaced so far, but adding management-key telemetry collection, durable attribution storage, and cross-provider reporting needs explicit maintainer sponsorship plus a redacted end-to-end demonstration before this can be judged the best product path. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 8ef86077e70a. LabelsLabel justifications:
EvidenceWhat I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (30 earlier review cycles; latest 8 shown)
|
|
@codex review @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c3bedb05f8
ℹ️ 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".
|
Follow-up fixes are pushed in 0f4bda0 and the three current review threads have been addressed. @codex review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f4bda0d9a
ℹ️ 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".
|
The current-head retention finding is fixed in e9b111e and its review thread is addressed. @codex review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e9b111ef6c
ℹ️ 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".
|
@clawsweeper re-review |
|
@codex review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6517067c4e
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3bf52d6697
ℹ️ 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".
…nto task/ec/codex-proxy-attribution # Conflicts: # Sources/CodexBarCore/CostUsageFetcher.swift
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ff3287d8eb
ℹ️ 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".
|
CI note for the linked Linux x64 failure (run 30506735403, job 90758093269): The failure came from CLICardsClaudeSwapTests, specifically "fake executable receives only one read only list command." The test successfully created and chmodded its temporary cswap script, but Foundation Process.run failed before that script executed, returning the generic error NSCocoaErrorDomain 256. The missing invocation marker, one-card result, and failure exit code were all downstream assertions from that single launch failure. This is not caused by the changes in this PR. Comparing the PR base (8ef8607) with the current head (ff3287d), the PR does not modify CLICardsClaudeSwapTests, CLIClaudeSwapCards, ClaudeSwapAccountReader, SubprocessRunner, ProcessPipeCapture, or the Linux workflow. The tests added by this PR also do not launch subprocesses or alter file-descriptor limits. The same unchanged test passes on the current PR head, and the current Linux x64, ARM64, and musl jobs are all green. That makes the linked failure consistent with an intermittent Linux/Foundation process-launch test flake rather than a regression in the CLIProxyAPI attribution work. The exact underlying POSIX errno is not available in the failed log because SubprocessRunner currently reduces the Foundation NSError to localizedDescription; code 256 is only the generic Cocoa read/launch error. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8fd2dd4b14
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2907270dae
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0b8a0f2426
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 71592d4ff1
ℹ️ 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".
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fdf7763251
ℹ️ 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".
| } else if modelProvider != .anthropic { | ||
| liveAttribution ?? row.attribution |
There was a problem hiding this comment.
Gate non-Anthropic cached attribution after disconnect
When removal leaves the Claude cache behind because cleanup fails or the app exits after committing the disconnect marker, a cached row whose Claude-facing model is itself non-Anthropic enters this fallback and restores row.attribution despite allowCachedCLIProxyAPIAttribution being false. Fresh evidence beyond the resolved thread is that this non-Anthropic branch bypasses the newly added disconnect guard, so models such as a directly selected OpenAI alias can still render the former Codex upstream after disconnect; suppress cached .cliProxyAPI attribution in this branch as well.
AGENTS.md reference: AGENTS.md:L46-L46
Useful? React with 👍 / 👎.
| guard let sessionID = sessionID?.trimmingCharacters(in: .whitespacesAndNewlines), | ||
| !sessionID.isEmpty | ||
| else { return nil } | ||
| return self.observationsBySessionID[sessionID]?.first |
There was a problem hiding this comment.
Match proxy routes to individual requests
When a Claude Code session is resumed once through CLIProxyAPI and once with a direct connection, this returns the session's first proxy observation for every row sharing that session ID, without checking the row's model or timestamp. A direct row can therefore be assigned the Codex auth-inventory upstream, or marked as an unresolved proxy row and excluded from Claude totals; select a route observation compatible with the individual request instead of treating any session-level log as proof.
AGENTS.md reference: AGENTS.md:L46-L46
Useful? React with 👍 / 👎.
| for _ in 0..<self.maximumBatches { | ||
| guard !Task.isCancelled, await shouldContinue() else { return .disabled } | ||
| let poppedBatch = try await client.pop(count: self.batchSize) |
There was a problem hiding this comment.
Recheck disconnect state between destructive pops
When another CodexBar process removes the integration while this process already holds the interprocess collection lock, removal commits the disconnect marker before waiting to purge, but this loop checks only local task cancellation and Track costs. Fresh evidence beyond the prior purge and queued-collection threads is that the active lock holder can consequently perform every remaining destructive pop with its captured key before releasing the lock, after which removal deletes those newly consumed records; pass the current-configuration check into the loop and evaluate it before each subsequent pop.
Useful? React with 👍 / 👎.
Summary
Verification
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer make checkDEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer make test(725 selections, 61 groups, all passed on the first attempt)swift test --filter SpendDashboardProxyAttributionTestsDEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test --filter CLIProxyAPIAttributionResolverTests(24 tests)DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test --filter CostUsageFetcherCacheSnapshotTests(13 tests)swift test --filter CostUsageFetcherTests(18 tests)DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test --filter CostUsageFetcherUnknownModelPricingTests(7 tests)swift test --filter SpendDashboardCodexProxySourceTests(2 tests)swift test --filter SpendDashboardForceStateMachineTests(14 tests)SpendDashboardTokenProvenanceTests,SpendDashboardControllerTests,CostUsageCacheTests, andCostUsageScannerClaudeFableTestsRemaining proof