feat: Display model + tokens in PR code reviews summary#407
feat: Display model + tokens in PR code reviews summary#407alex-alecu wants to merge 6 commits intomainfrom
Conversation
Code Review SummaryStatus: 2 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (13 files)
|
…usage data Use 3 retries with 200/400/800ms delays instead of a single 2-second sleep. Reduces average latency when data is already present and provides more attempts when it isn't.
Cover buildUsageFooter and appendUsageFooter including first-time append, footer replacement with exact and variant whitespace, empty body, unrelated horizontal rules, and multi-slash model slugs.
Sync model/token/cost accumulators to this.state on every LLM API event so they are written to durable storage by the existing event batch save. Restore them in loadState() so accumulation resumes correctly after a DO restart.
| // We pass the current status (no status change) to just update the usage fields. | ||
| const status = CodeReviewStatusSchema.parse(review.status); | ||
|
|
||
| await updateCodeReviewStatus(reviewId, status, { |
There was a problem hiding this comment.
[WARNING]: updateCodeReviewStatus will overwrite started_at timestamp
When this endpoint is called while the review is in 'running' status, updateCodeReviewStatus auto-sets started_at = new Date() (in code-reviews.ts line 129) because updates.startedAt is undefined. This silently overwrites the original started_at with the current time, making the review appear to have started much later than it actually did.
Consider either:
- Passing
startedAt: review.started_at ? new Date(review.started_at) : undefinedto preserve the existing value, or - Adding a dedicated
updateCodeReviewUsage()function that only updates usage fields without touching status/timestamps.
|
|
||
| // Restore usage accumulators from persisted state so they survive DO eviction | ||
| if (storedState.model) this.model = storedState.model; | ||
| if (storedState.totalTokensIn) this.totalTokensIn = storedState.totalTokensIn; |
There was a problem hiding this comment.
[WARNING]: Truthiness check fails for 0 — fragile restore logic
if (storedState.totalTokensIn) evaluates to false when the value is 0. Currently benign because the class fields default to 0, but this is fragile: if defaults change or if the intent is to explicitly restore a persisted 0, this silently skips the assignment.
Prefer explicit nullish checks:
| if (storedState.totalTokensIn) this.totalTokensIn = storedState.totalTokensIn; | |
| if (storedState.totalTokensIn != null) this.totalTokensIn = storedState.totalTokensIn; |
We cannot include the total tokens in the first summary because we would exclude the tokens used to generate the token itself. Instead we manually add the footer after the summary is posted.