Skip to content

feat(runtime): wire CostTracker to agent loop with budget enforcement#448

Merged
yacosta738 merged 6 commits intomainfrom
feature/dallay-255-wire-costtracker-to-agent-loop
Apr 6, 2026
Merged

feat(runtime): wire CostTracker to agent loop with budget enforcement#448
yacosta738 merged 6 commits intomainfrom
feature/dallay-255-wire-costtracker-to-agent-loop

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

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 now
tracks 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 (bootstrap/mod.rs): Instantiate CostTracker when cost.enabled=true,
    with graceful fallback to None on initialization failure
  • Agent loop (agent/agent.rs):
    • Pre-flight check_budget() gate before each LLM call
    • Post-call record_usage() with estimated token counts from response
    • model_pricing() with fuzzy name matching against CostConfig.prices
    • estimate_request_cost() from conversation history (~4 chars/token heuristic)
    • BudgetCheck::Exceeded returns structured error, blocking the LLM call
    • BudgetCheck::Warning logs warning via observer but proceeds
    • AgentEnd observer events now populated with real cost_usd and tokens_used
      (previously always None)
  • Feature flag: All behavior gated behind cost.enabled (defaults to false).
    Zero overhead, zero behavior change for existing users.

Testing

  • 4 new integration tests:
    • cost_tracker_records_usage_after_llm_call — verifies usage recording after LLM response
    • cost_tracker_none_when_disabled — verifies zero-cost path when feature disabled
    • budget_exceeded_blocks_llm_call — verifies hard block when daily limit exceeded
    • bootstrap_creates_cost_tracker_when_enabled / bootstrap_no_cost_tracker_when_disabled
  • All 3410 existing tests pass
  • Clippy clean (zero warnings)

Context

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

How to test

  1. Set cost.enabled = true in your corvus config
  2. Optionally adjust cost.daily_limit_usd (default: $10)
  3. Run corvus — observe budget checks in logs when approaching limits
  4. With a very low limit ($0.01), verify LLM calls are blocked with "Budget exceeded" error

Closes: #447

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
@yacosta738 yacosta738 self-assigned this Apr 6, 2026
@linear
Copy link
Copy Markdown

linear bot commented Apr 6, 2026

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Wire CostTracker into the agent runtime behind cost.enabled: initialize tracker at bootstrap, perform pre-flight budget checks before LLM calls, record post-call estimated token/cost usage, and surface cost summary in observer events; add product proposal and change-state files.

Changes

Cohort / File(s) Summary
Agent Cost Integration
clients/agent-runtime/src/agent/agent.rs
Added cost_tracker: Option<Arc<CostTracker>> and cost_config to Agent/builder; added pre-call enforce_budget_check() and post-call record_estimated_usage() (model pricing lookup, token estimation, budget check/error/warning paths).
Bootstrap Cost Initialization
clients/agent-runtime/src/bootstrap/mod.rs
Added cost_tracker: Option<Arc<CostTracker>> to BootstrapContext; instantiate CostTracker::new() when config.cost.enabled is true, log and fall back to None on failure.
Cost Module & Crate Wiring
clients/agent-runtime/src/cost/mod.rs, clients/agent-runtime/src/main.rs
Reduced public re-exports to BudgetCheck and TokenUsage; added mod cost; to crate root.
Docs / Product Spec
openspec/changes/2026-04-06-cost-governance-productization/proposal.md, openspec/.../state.yaml
Added comprehensive cost-governance product proposal and state record documenting enforcement semantics, CLI/admin surfaces, observability changes, and rollout state.

Sequence Diagram

sequenceDiagram
    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)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested labels

area:rust, risk:high

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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
Title check ✅ Passed The PR title follows Conventional Commit style with a 'feat' prefix, clear scope (runtime), and a concise 69-character description of the main change.
Description check ✅ Passed The PR description covers all key template sections: summary, detailed changes, testing evidence, context/linked issues, and how-to-test instructions with clear defaults.
Linked Issues check ✅ Passed The PR fulfills all eight acceptance criteria from #447: CostTracker instantiation on bootstrap [bootstrap/mod.rs], pre-flight budget checks [agent.rs], post-call usage recording [agent.rs], error handling on exceeded budget [agent.rs], observer warnings on budget warnings [agent.rs], cost.enabled gating [throughout], and estimation fallback via model_pricing [agent.rs].
Out of Scope Changes check ✅ Passed All changes directly support cost tracking activation: bootstrap initialization, agent loop enforcement, cost module API narrowing (intentional encapsulation), and product documentation are all within scope of DALLAY-255.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/dallay-255-wire-costtracker-to-agent-loop

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 and usage tips.

@yacosta738 yacosta738 added this to the v1.0.0 milestone Apr 6, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 6, 2026

✅ Contributor Report

User: @yacosta738
Status: Passed (12/13 metrics passed)

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 89% >= 30%
Repo Quality Repos with ≥100 stars 0 >= 0
Positive Reactions Positive reactions received 10 >= 1
Negative Reactions Negative reactions received 0 <= 5
Account Age GitHub account age 3082 days >= 30 days
Activity Consistency Regular activity over time 108% >= 0%
Issue Engagement Issues with community engagement 0 >= 0
Code Reviews Code reviews given to others 516 >= 0
Merger Diversity Unique maintainers who merged PRs 2 >= 0
Repo History Merge Rate Merge rate in this repo 91% >= 0%
Repo History Min PRs Previous PRs in this repo 203 >= 0
Profile Completeness Profile richness (bio, followers) 90 >= 0
Suspicious Patterns Spam-like activity detection 1 N/A

Contributor Report evaluates based on public GitHub activity. Analysis period: 2025-04-06 to 2026-04-06

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between a07f6b3 and ef91d58.

📒 Files selected for processing (6)
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/cost/mod.rs
  • clients/agent-runtime/src/main.rs
  • openspec/changes/2026-04-06-cost-governance-productization/proposal.md
  • openspec/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.rs
  • clients/agent-runtime/src/cost/mod.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • 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, and cargo test for code validation, or document which checks were skipped and why

Files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/cost/mod.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/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.rs
  • clients/agent-runtime/src/cost/mod.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • 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/main.rs
  • clients/agent-runtime/src/cost/mod.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • openspec/changes/2026-04-06-cost-governance-productization/state.yaml
  • openspec/changes/2026-04-06-cost-governance-productization/proposal.md
  • clients/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.rs
  • clients/agent-runtime/src/cost/mod.rs
  • 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/src/**/*.rs : Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/cost/mod.rs
  • 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/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.rs
  • clients/agent-runtime/src/cost/mod.rs
  • 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/main.rs
  • 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/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.rs
  • 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/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.enabled flag 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 None on summary errors is appropriate for telemetry. This fulfills the objective of populating cost_usd and tokens_used in AgentEnd events.


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_with check 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.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Apr 6, 2026

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

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

View logs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between ef91d58 and 6a19a63.

📒 Files selected for processing (2)
  • clients/agent-runtime/src/agent/agent.rs
  • clients/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.rs
  • 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, and cargo test for code validation, or document which checks were skipped and why

Files:

  • clients/agent-runtime/src/cost/mod.rs
  • 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/cost/mod.rs
  • 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/cost/mod.rs
  • clients/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.rs
  • 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/cost/mod.rs
  • 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/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.rs
  • 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/**/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 BudgetCheck and TokenUsage keeps the module boundary explicit without leaking internal cost types.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 4 unresolved review comments.

Files modified:

  • clients/agent-runtime/src/agent/agent.rs

Commit: b9ecd1fe76da4038fe1a7da691b2fcdec109f252

The changes have been pushed to the feature/dallay-255-wire-costtracker-to-agent-loop branch.

Time taken: 10m 18s

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 6, 2026

Fixed 1 file(s) based on 4 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
clients/agent-runtime/src/agent/agent.rs (2)

850-855: ⚠️ Potential issue | 🟠 Major

Cost-budget failures still degrade to generic session/mission outcomes.

Returning AgentExecutionError::CostBudgetExceeded here is only half the fix: later classifiers in this file still inspect the rendered error string, so a cost stop ends up as generic CodeSessionStatus::Error / MissionTerminationReason::Unrecoverable instead 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:fast becomes fast, not the routed model behind that hint. Any CostConfig.prices keyed 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 calling model_pricing() and TokenUsage::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

📥 Commits

Reviewing files that changed from the base of the PR and between 6a19a63 and b9ecd1f.

📒 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, and cargo test for 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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • clients/agent-runtime/src/agent/agent.rs

Commit: d8ccc5926277c7f8e955d3cbf42ecb07ba11128c

The changes have been pushed to the feature/dallay-255-wire-costtracker-to-agent-loop branch.

Time taken: 8m 13s

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@yacosta738 yacosta738 merged commit eb44248 into main Apr 6, 2026
11 of 12 checks passed
@yacosta738 yacosta738 deleted the feature/dallay-255-wire-costtracker-to-agent-loop branch April 6, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wire CostTracker to agent loop

1 participant