feat(runtime): wire CostTracker to agent loop with budget enforcement#448
Conversation
Define complete cost-governance product model for DALLAY-164/DALLAY-255. Includes budget types, enforcement semantics, override policy, surface requirements (CLI, API, dashboard), and 6-issue implementation plan.
- Instantiate CostTracker in BootstrapContext when cost.enabled=true - Add pre-flight check_budget() gate before each LLM call - Record estimated token usage after successful provider responses - Populate cost_usd and tokens_used in AgentEnd observer events - Add model_pricing() with fuzzy name matching for cost estimation - Feature-flagged: zero behavior change when cost.enabled=false (default) Resolves: DALLAY-255
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughWire CostTracker into the agent runtime behind Changes
Sequence DiagramsequenceDiagram
participant Agent as Agent
participant Config as Config
participant Tracker as CostTracker
participant Provider as Provider
Agent->>Config: load cost_config (enabled, limits, prices)
alt cost.enabled = true
Agent->>Tracker: CostTracker::new() → Arc
Tracker-->>Agent: tracker ready
end
Agent->>Tracker: check_budget(pre_flight_estimate)
Tracker-->>Agent: BudgetCheck (Ok / Warning / Exceeded)
alt Exceeded
Agent-->>Agent: return CostBudgetExceeded error
else Ok or Warning
Agent->>Provider: provider.chat(request)
Provider-->>Agent: response (+ TokenUsage / no tokens)
Agent->>Tracker: record_estimated_usage(input_tokens, output_estimate)
Tracker-->>Agent: recorded
end
Agent->>Agent: emit ObserverEvent::AgentEnd with tokens_used/cost_usd (if tracker)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
✅ Contributor ReportUser: @yacosta738
Contributor Report evaluates based on public GitHub activity. Analysis period: 2025-04-06 to 2026-04-06 |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 825-838: Extract the duplicated character-counting iteration into
a private helper on the Agent (e.g., fn history_char_count(&self) -> usize) and
replace the inline logic in both the current block and estimate_request_cost
with calls to that helper; ensure the helper matches the existing match arms
over ConversationMessage (Chat, AssistantToolCalls, ToolResults) and returns the
summed usize so both places use the same implementation.
- Around line 761-763: The fixed 500-token output estimate
(estimated_output_tokens) can misestimate real outputs; update the pre-flight
budget check logic that sets estimated_input_tokens and estimated_output_tokens
to emit a diagnostic log when actual output tokens (from the response/response
metadata) significantly exceed the estimate (e.g., actual_output_tokens >
estimated_output_tokens * 1.5); include both estimated_output_tokens and
actual_output_tokens and the request id/context in the log so we can tune the
heuristic over time and optionally increment a metric/counter for large-overrun
events.
- Around line 789-796: The code emits ObserverEvent::Error for
BudgetCheck::Warning which conflates warnings with errors; update the handling
in the BudgetCheck::Warning branch so it emits a distinct warning event—either
add a new enum variant ObserverEvent::BudgetWarning (and construct
ObserverEvent::BudgetWarning { component: "cost".to_string(), message: ... }) or
change the emitted event to use a non-error component name like "cost_warning"
when calling self.observer.record_event; ensure the ObserverEvent enum and any
matching/consuming code are updated to accept the new variant or component
string so monitoring downstream can distinguish warnings from real errors.
In `@clients/agent-runtime/src/cost/mod.rs`:
- Around line 5-6: The blanket #[allow(unused_imports)] on the pub use line
should be narrowed: inspect which re-exports are actually referenced externally
(e.g., BudgetCheck and TokenUsage are used by agent.rs) and either remove unused
re-exports (CostRecord, CostSummary, ModelStats, UsagePeriod) or keep them but
replace the blanket attribute with per-item justification (add a short comment
above the remaining pub use listing saying these types are intentionally part of
the public API) or apply #[allow(unused_imports)] to only the specific names
that are required; update the pub use accordingly (BudgetCheck, TokenUsage,
etc.) and remove the global allow to avoid masking truly dead exports.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6fdc90a9-e0e4-4f47-8f8e-424ea7558733
📒 Files selected for processing (6)
clients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/bootstrap/mod.rsclients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/main.rsopenspec/changes/2026-04-06-cost-governance-productization/proposal.mdopenspec/changes/2026-04-06-cost-governance-productization/state.yaml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: sonar
- GitHub Check: pr-checks
- GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (6)
clients/agent-runtime/src/**/*.rs
📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)
clients/agent-runtime/src/**/*.rs: Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements
Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency
Files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/bootstrap/mod.rsclients/agent-runtime/src/agent/agent.rs
clients/agent-runtime/**/*.rs
📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)
Run
cargo fmt --all -- --check,cargo clippy --all-targets -- -D warnings, andcargo testfor code validation, or document which checks were skipped and why
Files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/bootstrap/mod.rsclients/agent-runtime/src/agent/agent.rs
clients/agent-runtime/src/main.rs
📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)
clients/agent-runtime/src/main.rs: Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths
Keep startup path lean and avoid heavy initialization in command parsing flow
Files:
clients/agent-runtime/src/main.rs
**/*.rs
⚙️ CodeRabbit configuration file
**/*.rs: Focus on Rust idioms, memory safety, and ownership/borrowing correctness.
Flag unnecessary clones, unchecked panics in production paths, and weak error context.
Prioritize unsafe blocks, FFI boundaries, concurrency races, and secret handling.
Files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/bootstrap/mod.rsclients/agent-runtime/src/agent/agent.rs
**/*
⚙️ CodeRabbit configuration file
**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.
Files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/bootstrap/mod.rsopenspec/changes/2026-04-06-cost-governance-productization/state.yamlopenspec/changes/2026-04-06-cost-governance-productization/proposal.mdclients/agent-runtime/src/agent/agent.rs
**/*.{md,mdx}
⚙️ CodeRabbit configuration file
**/*.{md,mdx}: Verify technical accuracy and that docs stay aligned with code changes.
For user-facing docs, check EN/ES parity or explicitly note pending translation gaps.
Files:
openspec/changes/2026-04-06-cost-governance-productization/proposal.md
🧠 Learnings (7)
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Do not add heavy dependencies for minor convenience; justify new crate additions
Applied to files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/**/*.rs : Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency
Applied to files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths
Applied to files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why
Applied to files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/providers/**/*.rs : Implement `Provider` trait in `src/providers/` and register in `src/providers/mod.rs` factory when adding a new provider
Applied to files:
clients/agent-runtime/src/main.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Preserve release-size profile assumptions in `Cargo.toml` and avoid adding heavy dependencies unless clearly justified
Applied to files:
clients/agent-runtime/src/main.rsclients/agent-runtime/src/cost/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Keep startup path lean and avoid heavy initialization in command parsing flow
Applied to files:
clients/agent-runtime/src/main.rs
🔇 Additional comments (8)
clients/agent-runtime/src/main.rs (1)
50-50: LGTM!Module declaration follows the existing pattern and keeps the startup path lean—no heavy initialization here.
openspec/changes/2026-04-06-cost-governance-productization/state.yaml (1)
1-9: LGTM!Change tracking record accurately reflects the PR's implementation of DALLAY-255 (agent loop wiring). Phase progression is clear.
clients/agent-runtime/src/bootstrap/mod.rs (1)
255-274: LGTM!Conditional initialization with graceful fallback mirrors the audit_logger pattern. The warning log on failure provides visibility without blocking startup.
openspec/changes/2026-04-06-cost-governance-productization/proposal.md (1)
1-139: LGTM!Comprehensive proposal with clear scope boundaries, risk mitigations, and rollback strategy. The incremental implementation plan behind
cost.enabledflag ensures safe rollout.clients/agent-runtime/src/agent/agent.rs (4)
1677-1698: LGTM!Pre-flight budget check correctly gates the LLM call, and post-call recording captures actual response length. Error propagation is handled appropriately.
1825-1837: LGTM!Graceful fallback to
Noneon summary errors is appropriate for telemetry. This fulfills the objective of populatingcost_usdandtokens_usedinAgentEndevents.
2240-2392: LGTM!Good test coverage for:
- Usage recording on LLM calls
- Disabled path behavior
- Budget exceeded blocking
- Bootstrap integration for both enabled/disabled states
726-739: No action needed—suffix matching works as designed for realistic model identifiers.The bidirectional
ends_withcheck is intentional (explained in the code comment) and safe in practice. All evidence shows models are full identifiers (e.g.,"anthropic/claude-sonnet-4-20250514") or substantial substrings, never short names like"4". Exact-match lookup happens first, providing a safeguard. Tests confirm realistic usage patterns only.
Extract shared history character counting for cost estimates, emit cost_warning observer events for budget warnings, and log large output token estimate overruns for tuning. Narrow cost module re-exports to the intended public API.
Deploying corvus with
|
| Latest commit: |
d8ccc59
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d8fef5ed.corvus-42x.pages.dev |
| Branch Preview URL: | https://feature-dallay-255-wire-cost.corvus-42x.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 823-858: record_estimated_usage currently estimates output tokens
only from response_text, so tool-only responses get billed as 1 token; update
record_estimated_usage (and its callers) to accept the full model response or
parsed tool_calls payload and include serialized tool-call content when
computing output_chars/actual_output_tokens (e.g., serialize tool_calls into a
string and use its length alongside response_text), then build TokenUsage with
that combined output token estimate; ensure callers that previously passed
response_text now pass the full response (or tool_call string) and preserve
existing uses of model_pricing, history_char_count,
PRE_FLIGHT_ESTIMATED_OUTPUT_TOKENS and cost_tracker so warning and TokenUsage
creation remain intact.
- Around line 743-755: history_char_count currently only counts the optional
text field for ConversationMessage::AssistantToolCalls, which underestimates
size because the serialized tool_calls payload (tool names and args) is included
in the next provider request; update history_char_count to include the
serialized length of the AssistantToolCalls.tool_calls payload as well (e.g.,
JSON/string serialization of each tool call name + args or using the same
serialization routine used where AssistantToolCalls is created) so that
history_char_count sums text.len() plus the serialized tool_calls length for
ConversationMessage::AssistantToolCalls; refer to the history_char_count
function and the AssistantToolCalls.tool_calls field to implement the change.
- Around line 802-817: The BudgetCheck::Exceeded arm currently calls
anyhow::bail! which discards structured data; instead introduce and return a
stable error variant (e.g., add AgentError::CostBudgetExceeded { current_usd:
f64, limit_usd: f64, period: Period } or similar) and replace the anyhow::bail!
in the BudgetCheck::Exceeded match with Err(AgentError::CostBudgetExceeded {
current_usd, limit_usd, period }). Keep the tracing::error call, add the same
fields into the new variant, and update downstream match sites that previously
relied on error text to explicitly match AgentError::CostBudgetExceeded (or
inspect a `cost_budget_exceeded` marker) so budget stops are classified
reliably.
- Around line 728-740: The model_pricing lookup fails for routed hints like
"hint:{hint}" because CostConfig.prices is keyed by concrete model IDs; detect
when the model id has a "hint:" prefix (or matches your routing pattern) and
resolve it to the concrete model identifier using the existing routing logic
before calling model_pricing and before any pre-flight budget gate or post-call
cost accounting (the classified turn path). Either add hint-resolution inside
model_pricing or, better, perform resolution in the caller right before
pricing/usage recording so that CostConfig.prices is always consulted with the
actual model id.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6e2f2ff3-b067-4914-9d03-fef400d1b41d
📒 Files selected for processing (2)
clients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/cost/mod.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: greet / Welcome first-time contributor
- GitHub Check: sonar
- GitHub Check: pr-checks
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (4)
clients/agent-runtime/src/**/*.rs
📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)
clients/agent-runtime/src/**/*.rs: Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements
Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency
Files:
clients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
clients/agent-runtime/**/*.rs
📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)
Run
cargo fmt --all -- --check,cargo clippy --all-targets -- -D warnings, andcargo testfor code validation, or document which checks were skipped and why
Files:
clients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
**/*.rs
⚙️ CodeRabbit configuration file
**/*.rs: Focus on Rust idioms, memory safety, and ownership/borrowing correctness.
Flag unnecessary clones, unchecked panics in production paths, and weak error context.
Prioritize unsafe blocks, FFI boundaries, concurrency races, and secret handling.
Files:
clients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
**/*
⚙️ CodeRabbit configuration file
**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.
Files:
clients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
🧠 Learnings (5)
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Do not add heavy dependencies for minor convenience; justify new crate additions
Applied to files:
clients/agent-runtime/src/cost/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/**/*.rs : Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency
Applied to files:
clients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why
Applied to files:
clients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths
Applied to files:
clients/agent-runtime/src/cost/mod.rsclients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Preserve release-size profile assumptions in `Cargo.toml` and avoid adding heavy dependencies unless clearly justified
Applied to files:
clients/agent-runtime/src/cost/mod.rs
🔇 Additional comments (1)
clients/agent-runtime/src/cost/mod.rs (1)
5-7: Public cost API surface looks right.Narrowing the re-exports to
BudgetCheckandTokenUsagekeeps the module boundary explicit without leaking internal cost types.
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 1 file(s) based on 4 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
|
Fixed 1 file(s) based on 4 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
clients/agent-runtime/src/agent/agent.rs (2)
850-855:⚠️ Potential issue | 🟠 MajorCost-budget failures still degrade to generic session/mission outcomes.
Returning
AgentExecutionError::CostBudgetExceededhere is only half the fix: later classifiers in this file still inspect the rendered error string, so a cost stop ends up as genericCodeSessionStatus::Error/MissionTerminationReason::Unrecoverableinstead of budget exhaustion. Please inspect the concrete error in those classifiers before falling back to text matching.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@clients/agent-runtime/src/agent/agent.rs` around lines 850 - 855, The change returns AgentExecutionError::CostBudgetExceeded but downstream classifiers still rely on string matching and thus map budget stops to CodeSessionStatus::Error / MissionTerminationReason::Unrecoverable; update those classifiers in this file to detect the concrete error variant (match on AgentExecutionError::CostBudgetExceeded or unwrap the source error to that type) and map it to the proper budget-exhausted outcome before falling back to existing text-based matching, ensuring you adjust any places that convert the error to a string first so the concrete match happens earlier.
742-755:⚠️ Potential issue | 🟠 Major
resolve_model_for_pricing()still returns route aliases, not concrete model IDs.This helper claims to resolve the priced model, but
hint:fastbecomesfast, not the routed model behind that hint. AnyCostConfig.priceskeyed by actual model IDs will still fall through to(0.0, 0.0), so classified turns can bypass both pre-flight enforcement and post-call accounting. Resolve the hint through the model route before callingmodel_pricing()andTokenUsage::new().Also applies to: 795-797, 870-872
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@clients/agent-runtime/src/agent/agent.rs` around lines 742 - 755, The helper resolve_model_for_pricing currently only strips a "hint:" prefix (turning "hint:fast" into "fast") but must return the concrete routed model ID used for pricing; update resolve_model_for_pricing to run the hint through the provider routing/resolution logic used elsewhere (i.e., call the provider's model resolution routine before returning) so model_pricing() and TokenUsage::new() receive the actual routed model ID; also update the other call sites that mirror this behavior (the similar spots flagged in the review) to resolve hints via the routing logic instead of simple prefix stripping.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 793-807: The cost estimator in estimate_request_cost currently
uses history_char_count() only and misses adding tool schema size when
should_send_tool_specs() is true; update estimate_request_cost to build the same
chat request payload you send to provider.chat(...) (reuse the existing
helper/function that constructs that payload or create one if missing), compute
the serialized byte/char size including self.tool_specs when
should_send_tool_specs() is true, convert that size to token estimate the same
way the hot path does, and use model_pricing(&resolved_model) as before so
check_budget() and record_usage() reflect the true request shape (also apply the
same change to the other estimator usages noted around the
record_usage/check_budget code paths).
---
Duplicate comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 850-855: The change returns
AgentExecutionError::CostBudgetExceeded but downstream classifiers still rely on
string matching and thus map budget stops to CodeSessionStatus::Error /
MissionTerminationReason::Unrecoverable; update those classifiers in this file
to detect the concrete error variant (match on
AgentExecutionError::CostBudgetExceeded or unwrap the source error to that type)
and map it to the proper budget-exhausted outcome before falling back to
existing text-based matching, ensuring you adjust any places that convert the
error to a string first so the concrete match happens earlier.
- Around line 742-755: The helper resolve_model_for_pricing currently only
strips a "hint:" prefix (turning "hint:fast" into "fast") but must return the
concrete routed model ID used for pricing; update resolve_model_for_pricing to
run the hint through the provider routing/resolution logic used elsewhere (i.e.,
call the provider's model resolution routine before returning) so
model_pricing() and TokenUsage::new() receive the actual routed model ID; also
update the other call sites that mirror this behavior (the similar spots flagged
in the review) to resolve hints via the routing logic instead of simple prefix
stripping.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: c73e0d14-7a5c-4be3-a3c9-8f90b7a126a9
📒 Files selected for processing (1)
clients/agent-runtime/src/agent/agent.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: sonar
- GitHub Check: pr-checks
- GitHub Check: submit-gradle
- GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (4)
clients/agent-runtime/src/**/*.rs
📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)
clients/agent-runtime/src/**/*.rs: Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements
Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency
Files:
clients/agent-runtime/src/agent/agent.rs
clients/agent-runtime/**/*.rs
📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)
Run
cargo fmt --all -- --check,cargo clippy --all-targets -- -D warnings, andcargo testfor code validation, or document which checks were skipped and why
Files:
clients/agent-runtime/src/agent/agent.rs
**/*.rs
⚙️ CodeRabbit configuration file
**/*.rs: Focus on Rust idioms, memory safety, and ownership/borrowing correctness.
Flag unnecessary clones, unchecked panics in production paths, and weak error context.
Prioritize unsafe blocks, FFI boundaries, concurrency races, and secret handling.
Files:
clients/agent-runtime/src/agent/agent.rs
**/*
⚙️ CodeRabbit configuration file
**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.
Files:
clients/agent-runtime/src/agent/agent.rs
🧠 Learnings (2)
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths
Applied to files:
clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why
Applied to files:
clients/agent-runtime/src/agent/agent.rs
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 1 file(s) based on 1 unresolved review comment. Files modified:
Commit: The changes have been pushed to the Time taken: |
Fixed 1 file(s) based on 1 unresolved review comment. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>



Summary
Activates the existing
CostTracker(previously dead code — never instantiated outside tests)by wiring it into the runtime bootstrap and agent loop. When
cost.enabled=true, Corvus nowtracks token spend and enforces daily/monthly budget limits with pre-flight checks before every
LLM call.
This is the foundation for the cost governance productization effort (DALLAY-164).
Changes
bootstrap/mod.rs): InstantiateCostTrackerwhencost.enabled=true,with graceful fallback to
Noneon initialization failureagent/agent.rs):check_budget()gate before each LLM callrecord_usage()with estimated token counts from responsemodel_pricing()with fuzzy name matching againstCostConfig.pricesestimate_request_cost()from conversation history (~4 chars/token heuristic)BudgetCheck::Exceededreturns structured error, blocking the LLM callBudgetCheck::Warninglogs warning via observer but proceedsAgentEndobserver events now populated with realcost_usdandtokens_used(previously always
None)cost.enabled(defaults tofalse).Zero overhead, zero behavior change for existing users.
Testing
cost_tracker_records_usage_after_llm_call— verifies usage recording after LLM responsecost_tracker_none_when_disabled— verifies zero-cost path when feature disabledbudget_exceeded_blocks_llm_call— verifies hard block when daily limit exceededbootstrap_creates_cost_tracker_when_enabled/bootstrap_no_cost_tracker_when_disabledContext
Part of: DALLAY-164 (Productize cost governance across runtime surfaces)
Resolves: DALLAY-255
Product model and follow-up issue breakdown documented in:
openspec/changes/2026-04-06-cost-governance-productization/proposal.mdHow to test
cost.enabled = truein your corvus configcost.daily_limit_usd(default: $10)corvus— observe budget checks in logs when approaching limitsCloses: #447