Skip to content

fix: resolve circular imports, bump litellm, fix release tag format#285

Closed
Aureliolo wants to merge 2 commits into
mainfrom
fix/release-and-litellm-streaming
Closed

fix: resolve circular imports, bump litellm, fix release tag format#285
Aureliolo wants to merge 2 commits into
mainfrom
fix/release-and-litellm-streaming

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • Fix circular imports: Move RetryConfig/RateLimiterConfig from config.schema to new core/resilience_config.py, and move BudgetExhaustedError/DailyLimitExceededError/QuotaExhaustedError from engine/errors.py to new budget/errors.py. Delete the providers/resilience/config.py re-export shim. Move routing module imports of config.schema behind TYPE_CHECKING guards (placed at end of import sections per convention).
  • Bump litellm 1.82.0 → 1.82.1 and fix streaming test types (ModelResponseModelResponseStream)
  • Fix release tag format: Add "include-component-in-tag": false to release-please config so tags are vX.Y.Z (not ai-company-vX.Y.Z), matching the Docker CI v* trigger
  • Update docs: DESIGN_SPEC.md §15.3 project structure updated (new files added, deleted file removed), CLAUDE.md package structure descriptions updated for budget/ and core/
  • Add test coverage: New tests/unit/budget/test_errors.py for budget error hierarchy assertions; QuotaExhaustedError added to engine budget handler parametrize

Test plan

  • ruff check — all checks passed
  • ruff format — no changes needed
  • mypy src/ tests/ — no issues (848 files)
  • pytest tests/ -n auto --cov=ai_company --cov-fail-under=80 — 6653 passed, 8 skipped, 94.80% coverage
  • Pre-commit hooks pass (commitizen, gitleaks, trailing whitespace, etc.)

Review coverage

Pre-reviewed by 9 agents (code-reviewer, python-reviewer, pr-test-analyzer, comment-analyzer, type-design-analyzer, logging-audit, resilience-audit, security-reviewer, docs-consistency). 11 findings identified and addressed. No CRITICAL code issues found — all findings were import ordering, docstring accuracy, docs drift, and test coverage gaps.

- Fix Release Please tag format: add `include-component-in-tag: false`
  to produce `vX.Y.Z` tags matching Docker workflow's `v*` trigger
- Bump litellm 1.82.0 → 1.82.1 and fix streaming test mocks:
  use `ModelResponseStream` instead of `ModelResponse(stream=True)`
- Break circular import chain (config.schema ↔ providers):
  - Extract RetryConfig/RateLimiterConfig to core/resilience_config.py
  - Extract budget errors to budget/errors.py
  - Move routing module imports to TYPE_CHECKING blocks (PEP 649)
  - Delete providers/resilience/config.py re-export module
  - Remove all backward-compatibility re-exports from engine/errors.py,
    engine/__init__.py, and providers/__init__.py
  - Update all consumers to import from canonical locations
- Move TYPE_CHECKING blocks to end of import sections in routing modules
- Fix inaccurate docstrings in budget/errors.py
- Update DESIGN_SPEC.md §15.3 project structure (add budget/errors.py,
  core/resilience_config.py; remove deleted providers/resilience/config.py)
- Update CLAUDE.md package structure descriptions for budget/ and core/
- Add tests/unit/budget/test_errors.py for budget error hierarchy
- Add QuotaExhaustedError to engine budget handler parametrize

Pre-reviewed by 9 agents, 11 findings addressed
Copilot AI review requested due to automatic review settings March 10, 2026 22:54
@github-actions
Copy link
Copy Markdown
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 1 package(s) with unknown licenses.
See the Details below.

License Issues

uv.lock

PackageVersionLicenseIssue Type
litellm1.82.1NullUnknown License
Allowed Licenses: MIT, MIT-0, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, MPL-2.0, PSF-2.0, Unlicense, 0BSD, CC0-1.0, Python-2.0, Python-2.0.1, LicenseRef-scancode-free-unknown

OpenSSF Scorecard

PackageVersionScoreDetails
pip/litellm 1.82.1 UnknownUnknown

Scanned Files

  • uv.lock

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 10, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: cfae85be-ac5b-45ab-997d-90b969449f15

📥 Commits

Reviewing files that changed from the base of the PR and between b9907e8 and ce1ec38.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (34)
  • .github/release-please-config.json
  • CLAUDE.md
  • DESIGN_SPEC.md
  • pyproject.toml
  • src/ai_company/budget/__init__.py
  • src/ai_company/budget/enforcer.py
  • src/ai_company/budget/errors.py
  • src/ai_company/config/schema.py
  • src/ai_company/core/resilience_config.py
  • src/ai_company/engine/__init__.py
  • src/ai_company/engine/agent_engine.py
  • src/ai_company/engine/errors.py
  • src/ai_company/providers/__init__.py
  • src/ai_company/providers/resilience/__init__.py
  • src/ai_company/providers/resilience/config.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/_strategy_helpers.py
  • src/ai_company/providers/routing/resolver.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/providers/routing/strategies.py
  • tests/integration/providers/conftest.py
  • tests/integration/providers/test_retry_integration.py
  • tests/unit/budget/test_enforcer.py
  • tests/unit/budget/test_enforcer_quota.py
  • tests/unit/budget/test_errors.py
  • tests/unit/config/conftest.py
  • tests/unit/engine/test_agent_engine_budget.py
  • tests/unit/engine/test_errors.py
  • tests/unit/providers/drivers/conftest.py
  • tests/unit/providers/resilience/conftest.py
  • tests/unit/providers/resilience/test_config.py
  • tests/unit/providers/resilience/test_rate_limiter.py
  • tests/unit/providers/resilience/test_retry.py

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Introduced explicit budget error types for improved error handling and clarity.
  • Chores

    • Updated litellm dependency to version 1.82.1.
    • Reorganized resilience and budget configuration modules for better code maintainability and reduced circular dependencies.
    • Optimized import handling to improve module loading efficiency.

Walkthrough

This PR reorganizes module structure by centralizing budget-related exceptions into ai_company.budget.errors and resilience configuration into ai_company.core.resilience_config, removes intermediate re-export modules, adds TYPE_CHECKING guards in routing modules to prevent circular imports, and updates all dependent imports across the codebase and tests.

Changes

Cohort / File(s) Summary
Budget Errors Centralization
src/ai_company/budget/errors.py, src/ai_company/budget/__init__.py, src/ai_company/budget/enforcer.py
New dedicated budget/errors.py module defines BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError. Re-exported from budget/__init__.py. Enforcer imports updated to use new module.
Engine Budget Error Removal
src/ai_company/engine/__init__.py, src/ai_company/engine/errors.py, src/ai_company/engine/agent_engine.py
Budget error classes removed from engine public API and engine/errors.py. Agent engine import updated to reference ai_company.budget.errors.
Resilience Config Centralization
src/ai_company/core/resilience_config.py, src/ai_company/config/schema.py, src/ai_company/providers/resilience/...
New core/resilience_config.py defines RetryConfig and RateLimiterConfig with validation. Removed from config/schema.py and re-imported from core. Deleted intermediate re-export at providers/resilience/config.py.
Providers Resilience Updates
src/ai_company/providers/__init__.py, src/ai_company/providers/resilience/__init__.py, src/ai_company/providers/resilience/rate_limiter.py, src/ai_company/providers/resilience/retry.py
Removed resilience config re-exports from public API. Updated imports to source configs from core.resilience_config.
Routing TYPE_CHECKING Guards
src/ai_company/providers/routing/_strategy_helpers.py, src/ai_company/providers/routing/resolver.py, src/ai_company/providers/routing/router.py, src/ai_company/providers/routing/strategies.py
Added TYPE_CHECKING blocks around config imports to prevent circular dependencies while preserving type hints.
Test Import Updates
tests/integration/providers/conftest.py, tests/unit/budget/..., tests/unit/config/conftest.py, tests/unit/engine/..., tests/unit/providers/...
Updated imports across 15+ test files to reference budget errors from ai_company.budget.errors and resilience configs from ai_company.core.resilience_config. New test file test_errors.py validates budget error hierarchy.
Minor Configuration Updates
.github/release-please-config.json, CLAUDE.md, DESIGN_SPEC.md, pyproject.toml
Added include-component-in-tag: false to release-please config, updated documentation references to new modules, bumped litellm from 1.82.0 to 1.82.1.
Streaming Test Builders
tests/integration/providers/conftest.py
Updated builder functions (build_content_chunk, build_usage_chunk, build_tool_call_delta_chunk, build_finish_chunk) and async_iter_chunks to return ModelResponseStream instead of ModelResponse.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/release-and-litellm-streaming
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/release-and-litellm-streaming

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily focuses on improving the project's architectural integrity by resolving several circular import issues, which enhances modularity and maintainability. It also includes a minor dependency update for litellm and a crucial fix to the release tagging mechanism to ensure consistent versioning. These changes collectively contribute to a more robust and well-structured codebase, simplifying future development and deployment processes.

Highlights

  • Circular Import Resolution: Moved RetryConfig and RateLimiterConfig from config.schema to a new core/resilience_config.py. Similarly, BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError were moved from engine/errors.py to a new budget/errors.py. The providers/resilience/config.py re-export shim was deleted, and routing module imports were placed behind TYPE_CHECKING guards to prevent future circular dependencies.
  • Dependency Update: Bumped the litellm library from version 1.82.0 to 1.82.1 and updated streaming test types from ModelResponse to ModelResponseStream to align with the new version.
  • Release Tag Format Fix: Modified the release-please configuration to ensure release tags follow the vX.Y.Z format by setting include-component-in-tag to false, which matches the Docker CI trigger.
  • Documentation Updates: Updated DESIGN_SPEC.md to reflect the new project structure, including newly added and removed files. CLAUDE.md was also updated to describe the new budget/ and core/ package structures.
  • Test Coverage Enhancement: Added a new test file tests/unit/budget/test_errors.py to assert the budget error hierarchy. QuotaExhaustedError was also included in the engine budget handler parametrization for comprehensive testing.
Changelog
  • .github/release-please-config.json
    • Added "include-component-in-tag": false to ensure release tags are in vX.Y.Z format.
  • CLAUDE.md
    • Updated package structure descriptions for budget/ and core/ to reflect new error and resilience config locations.
  • DESIGN_SPEC.md
    • Updated project structure to include resilience_config.py in core/.
    • Removed config.py from providers/resilience/ in the project structure.
    • Added errors.py to budget/ in the project structure.
  • pyproject.toml
    • Updated litellm dependency from 1.82.0 to 1.82.1.
  • src/ai_company/budget/init.py
    • Imported and re-exported BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError from ai_company.budget.errors.
  • src/ai_company/budget/enforcer.py
    • Updated imports for BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError to reference ai_company.budget.errors.
  • src/ai_company/budget/errors.py
    • Added new file defining BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError classes.
  • src/ai_company/config/schema.py
    • Removed local definitions of RetryConfig and RateLimiterConfig.
    • Imported RetryConfig and RateLimiterConfig from ai_company.core.resilience_config.
  • src/ai_company/core/resilience_config.py
    • Added new file defining RetryConfig and RateLimiterConfig models.
  • src/ai_company/engine/init.py
    • Removed imports and re-exports of BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError.
  • src/ai_company/engine/agent_engine.py
    • Updated import for BudgetExhaustedError to reference ai_company.budget.errors.
  • src/ai_company/engine/errors.py
    • Removed definitions of BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError.
  • src/ai_company/providers/init.py
    • Removed imports and re-exports of RateLimiterConfig and RetryConfig.
  • src/ai_company/providers/resilience/init.py
    • Removed imports and re-exports of RateLimiterConfig and RetryConfig.
  • src/ai_company/providers/resilience/config.py
    • Removed file.
  • src/ai_company/providers/resilience/rate_limiter.py
    • Updated import for RateLimiterConfig to reference ai_company.core.resilience_config.
  • src/ai_company/providers/resilience/retry.py
    • Updated import for RetryConfig to reference ai_company.core.resilience_config.
  • src/ai_company/providers/routing/_strategy_helpers.py
    • Added TYPE_CHECKING guard for RoutingConfig and RoutingRuleConfig imports.
  • src/ai_company/providers/routing/resolver.py
    • Added TYPE_CHECKING guard for ProviderConfig import.
  • src/ai_company/providers/routing/router.py
    • Added TYPE_CHECKING guard for ProviderConfig and RoutingConfig imports.
  • src/ai_company/providers/routing/strategies.py
    • Added TYPE_CHECKING guard for RoutingConfig import.
  • tests/integration/providers/conftest.py
    • Updated imports for resilience configuration and adjusted streaming test types to ModelResponseStream.
    • Removed stream=True argument from ModelResponseStream instantiations.
  • tests/integration/providers/test_retry_integration.py
    • Updated imports for RateLimiterConfig and RetryConfig to reference ai_company.core.resilience_config.
  • tests/unit/budget/test_enforcer.py
    • Updated imports for BudgetExhaustedError and DailyLimitExceededError to reference ai_company.budget.errors.
  • tests/unit/budget/test_enforcer_quota.py
    • Updated the import path for QuotaExhaustedError.
  • tests/unit/budget/test_errors.py
    • Added new file to test the budget error hierarchy, including inheritance and message preservation.
  • tests/unit/config/conftest.py
    • Updated imports for RateLimiterConfig and RetryConfig to reference ai_company.core.resilience_config.
  • tests/unit/engine/test_agent_engine_budget.py
    • Updated imports for BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError to reference ai_company.budget.errors.
    • Added QuotaExhaustedError to parameterized tests for pre-flight budget stops.
  • tests/unit/engine/test_errors.py
    • Updated import for BudgetExhaustedError to reference ai_company.budget.errors.
    • Modified test to assert that BudgetExhaustedError is not a subclass of EngineError.
  • tests/unit/providers/drivers/conftest.py
    • Updated imports for RateLimiterConfig and RetryConfig to reference ai_company.core.resilience_config.
  • tests/unit/providers/resilience/conftest.py
    • Updated imports for RateLimiterConfig and RetryConfig to reference ai_company.core.resilience_config.
  • tests/unit/providers/resilience/test_config.py
    • Updated imports for RateLimiterConfig and RetryConfig to reference ai_company.core.resilience_config.
  • tests/unit/providers/resilience/test_rate_limiter.py
    • Updated the import path for RateLimiterConfig.
  • tests/unit/providers/resilience/test_retry.py
    • Updated the import path for RetryConfig.
  • uv.lock
    • Updated the litellm package version from 1.82.0 to 1.82.1.
    • Updated hashes for litellm sdist and wheels.
Activity
  • Pre-reviewed by 9 agents (code-reviewer, python-reviewer, pr-test-analyzer, comment-analyzer, type-design-analyzer, logging-audit, resilience-audit, security-reviewer, docs-consistency).
  • 11 findings identified and addressed during pre-review.
  • No CRITICAL code issues were found; all findings related to import ordering, docstring accuracy, docs drift, and test coverage gaps.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR removes circular import pressure between config/provider/engine layers by relocating shared configuration and budget exceptions into leaf modules, while also updating LiteLLM to 1.82.1 (including streaming test type fixes) and adjusting release-please tagging to match CI’s v* trigger.

Changes:

  • Move RetryConfig / RateLimiterConfig to ai_company.core.resilience_config and update imports; remove the old resilience config re-export shim.
  • Move budget exhaustion exceptions to ai_company.budget.errors, update engine/budget/tests accordingly, and add unit coverage for the new budget error hierarchy.
  • Bump litellm to 1.82.1, update streaming test helpers to ModelResponseStream, and fix release-please tag format.

Reviewed changes

Copilot reviewed 34 out of 35 changed files in this pull request and generated no comments.

Show a summary per file
File Description
uv.lock Updates locked LiteLLM version to 1.82.1.
pyproject.toml Bumps direct dependency litellm==1.82.1.
.github/release-please-config.json Forces tags to be vX.Y.Z by disabling component-in-tag.
DESIGN_SPEC.md Updates project structure docs for new/moved/removed modules.
CLAUDE.md Updates package structure notes for budget/ and core/.
src/ai_company/core/resilience_config.py New canonical home for retry/rate-limiter config models to avoid cycles.
src/ai_company/config/schema.py Imports and re-exposes resilience config models from core/.
src/ai_company/providers/resilience/retry.py Updates RetryConfig type import to core.resilience_config.
src/ai_company/providers/resilience/rate_limiter.py Switches RateLimiterConfig import to core.resilience_config.
src/ai_company/providers/resilience/config.py Removes the re-export shim module.
src/ai_company/providers/resilience/init.py Stops exporting RetryConfig/RateLimiterConfig from resilience package.
src/ai_company/providers/init.py Stops re-exporting resilience config types at top-level providers API.
src/ai_company/providers/routing/strategies.py Moves RoutingConfig import behind TYPE_CHECKING to break cycles.
src/ai_company/providers/routing/router.py Moves ProviderConfig/RoutingConfig imports behind TYPE_CHECKING.
src/ai_company/providers/routing/resolver.py Moves ProviderConfig import behind TYPE_CHECKING.
src/ai_company/providers/routing/_strategy_helpers.py Moves routing config imports behind TYPE_CHECKING.
src/ai_company/engine/errors.py Removes budget exceptions from engine error hierarchy.
src/ai_company/engine/agent_engine.py Imports/catches BudgetExhaustedError from budget.errors.
src/ai_company/engine/init.py Removes budget exceptions from engine public exports.
src/ai_company/budget/errors.py New leaf-module budget error hierarchy.
src/ai_company/budget/enforcer.py Imports budget exceptions from budget.errors.
src/ai_company/budget/init.py Re-exports budget exceptions from the budget package.
tests/unit/providers/resilience/test_retry.py Updates RetryConfig import to core.resilience_config.
tests/unit/providers/resilience/test_rate_limiter.py Updates RateLimiterConfig import to core.resilience_config.
tests/unit/providers/resilience/test_config.py Updates resilience config imports to core.resilience_config.
tests/unit/providers/resilience/conftest.py Updates resilience config fixture imports to core.resilience_config.
tests/unit/providers/drivers/conftest.py Splits schema imports vs resilience config imports to avoid cycles.
tests/integration/providers/test_retry_integration.py Splits schema imports vs resilience config imports to avoid cycles.
tests/integration/providers/conftest.py Updates streaming helper typing from ModelResponse to ModelResponseStream.
tests/unit/engine/test_errors.py Adjusts expectations: budget errors are no longer EngineError.
tests/unit/engine/test_agent_engine_budget.py Adds QuotaExhaustedError case and updates imports to budget.errors.
tests/unit/config/conftest.py Updates resilience config imports to core.resilience_config.
tests/unit/budget/test_errors.py Adds unit tests for the new budget error hierarchy.
tests/unit/budget/test_enforcer_quota.py Updates QuotaExhaustedError import to budget.errors.
tests/unit/budget/test_enforcer.py Updates budget exception imports to budget.errors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Mar 10, 2026

Greptile Summary

This PR is a well-scoped structural refactoring that resolves circular import chains by relocating two sets of classes to better-positioned leaf modules — RetryConfig/RateLimiterConfig into core/resilience_config.py and the budget error hierarchy into budget/errors.py — and defensively guards several routing-module imports behind TYPE_CHECKING blocks. It also fixes the release-please tag format to match the Docker CI v* trigger and bumps litellm by a patch version.

  • Circular import fix (errors): BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError extracted from engine/errors.py into the new leaf module budget/errors.py, making budget errors independent of the engine error hierarchy and re-exported from budget/__init__.py.
  • Circular import fix (config): RetryConfig and RateLimiterConfig moved from config/schema.py to core/resilience_config.py; providers/resilience/config.py re-export shim deleted cleanly.
  • TYPE_CHECKING guards: Import-time references to config.schema types in the routing sub-package (resolver.py, router.py, strategies.py, _strategy_helpers.py) are now inside TYPE_CHECKING blocks, valid under Python 3.14 / PEP 649 lazy annotations.
  • Style inconsistency: rate_limiter.py suppresses TC001 with a # noqa comment rather than using a TYPE_CHECKING block as retry.py does for the identical pattern.
  • Public docstring hygiene: QuotaExhaustedError docstring contains an internal milestone reference ("tracked in M7") that will surface in generated docs and IDE tooltips.
  • Test coverage: New tests/unit/budget/test_errors.py comprehensively covers the error hierarchy; QuotaExhaustedError added to the engine budget handler parametrize set.

Confidence Score: 5/5

  • Safe to merge — pure structural refactoring with comprehensive test coverage and no functional logic changes.
  • All import paths are updated consistently across source and tests, the full test suite passes at 94.8% coverage, mypy strict mode reports no issues, and the two findings are minor style/docs concerns that do not affect correctness or runtime behavior.
  • No files require special attention; the two style observations in rate_limiter.py and budget/errors.py are non-blocking.

Important Files Changed

Filename Overview
src/ai_company/budget/errors.py New leaf module defining the budget error hierarchy; no intra-project imports, cleanly breaks circular dependency. Minor: QuotaExhaustedError docstring contains an internal milestone reference ("tracked in M7") that leaks into the public API surface.
src/ai_company/core/resilience_config.py New leaf module housing RetryConfig and RateLimiterConfig, extracted from config/schema.py to break the circular import with providers.resilience. Model validators, field constraints, and logging are all correctly preserved from the original location.
src/ai_company/providers/resilience/rate_limiter.py Updated to import RateLimiterConfig from core.resilience_config. The import is kept at runtime level with # noqa: TC001, inconsistent with retry.py which correctly uses a TYPE_CHECKING guard for RetryConfig from the same module.
src/ai_company/providers/resilience/retry.py Updated to import RetryConfig from core.resilience_config inside a TYPE_CHECKING guard — the correct pattern for Python 3.14 / PEP 649.
src/ai_company/config/schema.py Now imports RetryConfig and RateLimiterConfig from core.resilience_config instead of defining them inline. All field references, validators, and defaults remain intact.
src/ai_company/engine/errors.py BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError removed, leaving a clean engine-only error hierarchy. All callers have been updated to import from budget.errors.
src/ai_company/budget/init.py Budget errors (BudgetExhaustedError, DailyLimitExceededError, QuotaExhaustedError) correctly added to the public API via both import and __all__.
src/ai_company/engine/agent_engine.py Import of BudgetExhaustedError updated from engine.errors to budget.errors. Change is minimal and correct.
src/ai_company/providers/routing/router.py ProviderConfig and RoutingConfig imports moved behind TYPE_CHECKING guard to break circular imports with config.schema, following the established pattern in the routing subpackage.
.github/release-please-config.json Added "include-component-in-tag": false to produce vX.Y.Z tags instead of ai-company-vX.Y.Z, aligning with the Docker CI v* trigger pattern.
tests/unit/budget/test_errors.py New test file providing thorough coverage of the budget error hierarchy: inheritance, message preservation, cross-catching, and explicit assertion that budget errors are independent of EngineError.
pyproject.toml litellm bumped from 1.82.0 to 1.82.1. Pinned dependency, minimal risk.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph core["core/"]
        RC["resilience_config.py\nRetryConfig\nRateLimiterConfig"]
    end

    subgraph budget["budget/"]
        BE["errors.py\nBudgetExhaustedError\nDailyLimitExceededError\nQuotaExhaustedError"]
        ENF["enforcer.py"]
        BINIT["__init__.py"]
    end

    subgraph config["config/"]
        SCH["schema.py\nProviderConfig\nRootConfig"]
    end

    subgraph engine["engine/"]
        AE["agent_engine.py"]
        EE["errors.py\nEngineError hierarchy"]
    end

    subgraph providers["providers/resilience/"]
        RH["retry.py\nRetryHandler"]
        RL["rate_limiter.py\nRateLimiter"]
    end

    subgraph routing["providers/routing/"]
        ROU["router.py\nresolver.py\nstrategies.py"]
    end

    RC -->|imported by| SCH
    RC -->|TYPE_CHECKING| RH
    RC -->|runtime import| RL
    BE -->|imported by| ENF
    BE -->|imported by| AE
    BE -->|re-exported by| BINIT
    SCH -->|TYPE_CHECKING| ROU
    EE -->|independent of| BE
Loading

Comments Outside Diff (1)

  1. src/ai_company/budget/errors.py, line 28-33 (link)

    Internal milestone note leaking into public docstring

    The phrase "Degradation routing (FALLBACK/QUEUE) is tracked in M7" is an internal project-management reference that does not belong in a public API docstring. Users of the library will see this in help(), IDE tooltips, and generated documentation. It should either be removed or replaced with a forward-looking note about intended behavior:

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/ai_company/budget/errors.py
    Line: 28-33
    
    Comment:
    **Internal milestone note leaking into public docstring**
    
    The phrase "Degradation routing (FALLBACK/QUEUE) is tracked in M7" is an internal project-management reference that does not belong in a public API docstring. Users of the library will see this in `help()`, IDE tooltips, and generated documentation. It should either be removed or replaced with a forward-looking note about intended behavior:
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: ce1ec38

import math
import time

from ai_company.core.resilience_config import RateLimiterConfig # noqa: TC001
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Inconsistent TYPE_CHECKING pattern with retry.py

retry.py (the companion module in this same PR) correctly places RetryConfig inside a TYPE_CHECKING guard, consistent with the project's Python 3.14 / PEP 649 stance (lazy annotations — no from __future__ import annotations needed). rate_limiter.py keeps RateLimiterConfig at module-level and suppresses the ruff TC001 warning with a # noqa comment instead.

Both imports are used only as constructor parameter annotations; neither needs to be resolved at runtime under PEP 649. Aligning rate_limiter.py with retry.py removes the noqa suppression and keeps the two resilience modules consistent:

Suggested change
from ai_company.core.resilience_config import RateLimiterConfig # noqa: TC001
from ai_company.observability import get_logger
from ai_company.observability.events.provider import (
PROVIDER_RATE_LIMITER_PAUSED,
PROVIDER_RATE_LIMITER_THROTTLED,
)
if TYPE_CHECKING:
from ai_company.core.resilience_config import RateLimiterConfig

(Add TYPE_CHECKING to the from typing import line above as well.)

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/ai_company/providers/resilience/rate_limiter.py
Line: 7

Comment:
**Inconsistent TYPE_CHECKING pattern with `retry.py`**

`retry.py` (the companion module in this same PR) correctly places `RetryConfig` inside a `TYPE_CHECKING` guard, consistent with the project's Python 3.14 / PEP 649 stance (lazy annotations — no `from __future__ import annotations` needed). `rate_limiter.py` keeps `RateLimiterConfig` at module-level and suppresses the ruff `TC001` warning with a `# noqa` comment instead.

Both imports are used only as constructor parameter annotations; neither needs to be resolved at runtime under PEP 649. Aligning `rate_limiter.py` with `retry.py` removes the noqa suppression and keeps the two resilience modules consistent:

```suggestion
from ai_company.observability import get_logger
from ai_company.observability.events.provider import (
    PROVIDER_RATE_LIMITER_PAUSED,
    PROVIDER_RATE_LIMITER_THROTTLED,
)

if TYPE_CHECKING:
    from ai_company.core.resilience_config import RateLimiterConfig
```

(Add `TYPE_CHECKING` to the `from typing import` line above as well.)

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively resolves circular import issues by refactoring resilience configuration and budget-related error classes into separate, lower-level modules. The changes are well-executed, with corresponding updates to imports, documentation, and tests. The use of TYPE_CHECKING guards for routing module imports is a good practice. Additionally, the pull request includes a version bump for litellm with necessary adjustments to streaming test types, and a configuration fix for release tags. The new tests for the budget error hierarchy are a valuable addition, ensuring the new structure is correct. Overall, this is a high-quality contribution that improves the project's architecture and maintainability.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a significant and well-executed refactoring to resolve circular import issues by restructuring core configuration and error models. The changes are clean, consistent, and improve the overall architecture of the codebase. The dependency bump for litellm and the associated test fixes are also correctly handled. I have one suggestion to improve the docstring for the new BudgetExhaustedError to make it more accurate and comprehensive.

Comment on lines +10 to +20
"""Budget exhaustion signal.

Used in two contexts:

1. Raised directly by :meth:`BudgetEnforcer.check_can_execute`
when pre-flight budget checks fail (monthly hard stop or daily
limit exceeded).
2. Caught by the engine layer (``AgentEngine.run``) and converted
into an ``ExecutionResult`` with
``TerminationReason.BUDGET_EXHAUSTED``.
"""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The docstring for BudgetExhaustedError is slightly incomplete. It mentions that it's raised for 'monthly hard stop or daily limit exceeded', but it's also the base class for QuotaExhaustedError, which is also raised in check_can_execute. To improve clarity and accuracy, I suggest updating the docstring to reflect that it's a base exception for all budget exhaustion signals, including quota limits.

Suggested change
"""Budget exhaustion signal.
Used in two contexts:
1. Raised directly by :meth:`BudgetEnforcer.check_can_execute`
when pre-flight budget checks fail (monthly hard stop or daily
limit exceeded).
2. Caught by the engine layer (``AgentEngine.run``) and converted
into an ``ExecutionResult`` with
``TerminationReason.BUDGET_EXHAUSTED``.
"""
"""Base exception for budget exhaustion signals.
This exception and its subclasses are used in two contexts:
1. Raised by :meth:`BudgetEnforcer.check_can_execute`
when pre-flight budget checks fail (e.g., monthly hard stop, daily
limit, or provider quota exceeded).
2. Caught by the engine layer (``AgentEngine.run``) and converted
into an ``ExecutionResult`` with
``TerminationReason.BUDGET_EXHAUSTED``.
"""

Aureliolo added a commit that referenced this pull request May 10, 2026
- scripts/check_baseline_growth.py:_count_json_entries fallback to len(payload) when 'locations' key is missing, so flat-dict baselines surface growth instead of returning sentinel 0 (gemini)

- scripts/check_baseline_growth.py: validate resolved baseline path stays under REPO_ROOT before reading; closes CodeQL alert #285 (py/path-injection)

- .pre-commit-config.yaml: hook regex now accepts underscore-prefixed JSON/TXT baselines like scripts/_workflow_shell_git_commits_baseline.json (CodeRabbit)

- scripts/check_no_em_dashes_hook.sh: normalise backslashes before changelog exemption case-match so Windows paths hit the same skip path (CodeRabbit)

- Tests: update json fallback expectation, add path-traversal guard test, add Windows-path changelog exemption parametrized cases
Aureliolo added a commit that referenced this pull request May 10, 2026
- scripts/check_baseline_growth.py: replace _safe_baseline_path resolve()/is_relative_to() with regex-validated basename approach so the user-supplied directory is discarded and only a known-safe REPO_ROOT/scripts/<basename> path is constructed; closes CodeQL alerts #285 (line 151) and #286 (line 134)

- scripts/check_baseline_growth.py: emit stderr WARNING when InvalidBaselineError is raised parsing HEAD content instead of silently falling back to head_count=0 (coderabbit)

- scripts/check_no_edit_baseline.sh: normalise backslashes before case-match so Windows paths like C:\repo\scripts\foo_baseline.txt hit the same protection as POSIX (coderabbit)

- Tests: rewrite path-injection test for regex sanitisation, add corrupt-HEAD warning test, new tests/unit/scripts/test_check_no_edit_baseline.py covering POSIX + Windows-path + non-baseline + malformed-envelope cases
Aureliolo added a commit that referenced this pull request May 10, 2026
- scripts/check_baseline_growth.py:_count_json_entries fallback to len(payload) when 'locations' key is missing, so flat-dict baselines surface growth instead of returning sentinel 0 (gemini)

- scripts/check_baseline_growth.py: validate resolved baseline path stays under REPO_ROOT before reading; closes CodeQL alert #285 (py/path-injection)

- .pre-commit-config.yaml: hook regex now accepts underscore-prefixed JSON/TXT baselines like scripts/_workflow_shell_git_commits_baseline.json (CodeRabbit)

- scripts/check_no_em_dashes_hook.sh: normalise backslashes before changelog exemption case-match so Windows paths hit the same skip path (CodeRabbit)

- Tests: update json fallback expectation, add path-traversal guard test, add Windows-path changelog exemption parametrized cases
Aureliolo added a commit that referenced this pull request May 10, 2026
- scripts/check_baseline_growth.py: replace _safe_baseline_path resolve()/is_relative_to() with regex-validated basename approach so the user-supplied directory is discarded and only a known-safe REPO_ROOT/scripts/<basename> path is constructed; closes CodeQL alerts #285 (line 151) and #286 (line 134)

- scripts/check_baseline_growth.py: emit stderr WARNING when InvalidBaselineError is raised parsing HEAD content instead of silently falling back to head_count=0 (coderabbit)

- scripts/check_no_edit_baseline.sh: normalise backslashes before case-match so Windows paths like C:\repo\scripts\foo_baseline.txt hit the same protection as POSIX (coderabbit)

- Tests: rewrite path-injection test for regex sanitisation, add corrupt-HEAD warning test, new tests/unit/scripts/test_check_no_edit_baseline.py covering POSIX + Windows-path + non-baseline + malformed-envelope cases
Aureliolo added a commit that referenced this pull request May 10, 2026
- scripts/check_baseline_growth.py: unify _is_baseline_path and _safe_baseline_path under a single _BASELINE_BASENAME_RE (canonical regex matching txt/json with optional leading underscore + py with required leading underscore); remove _safe_baseline_path entirely so the gate never touches the user-controlled filesystem path (coderabbit)

- scripts/check_baseline_growth.py: read staged content via 'git show :<path>' instead of Path.read_text(); index reads reflect what is actually staged and remove the path-injection sink, closing CodeQL alert #285 (coderabbit + codeql)

- tests/unit/scripts/test_check_baseline_growth.py: switch tmp_path/REPO_ROOT-monkeypatched fixtures to mocks of _read_staged + _read_head; broaden test_is_baseline_path with traversal/Windows-separator/uppercase/extension cases; add _read_staged subprocess.run tests

- tests/unit/scripts/test_check_no_edit_baseline.py: add test_blocks_edit_of_python_baseline_posix and a Windows-path .py case (coderabbit)
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.

2 participants