fix: resolve circular imports, bump litellm, fix release tag format#286
fix: resolve circular imports, bump litellm, fix release tag format#286
Conversation
- 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
Dependency ReviewThe following issues were found:
License Issuesuv.lock
OpenSSF Scorecard
Scanned Files
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
📜 Recent 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). (1)
🧰 Additional context used📓 Path-based instructions (3)**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
src/ai_company/**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
tests/**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (7)📓 Common learnings📚 Learning: 2026-03-10T22:52:37.949ZApplied to files:
📚 Learning: 2026-03-10T22:52:37.949ZApplied to files:
📚 Learning: 2026-03-10T22:52:37.949ZApplied to files:
📚 Learning: 2026-03-10T22:52:37.949ZApplied to files:
📚 Learning: 2026-03-10T22:52:37.949ZApplied to files:
📚 Learning: 2026-03-10T22:52:37.949ZApplied to files:
🧬 Code graph analysis (1)tests/unit/budget/test_errors.py (2)
🔇 Additional comments (3)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR refactors budget error placement and resilience configuration locations. BudgetExhaustedError, DailyLimitExceededError, and QuotaExhaustedError are moved into a new Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
Summary of ChangesHello, 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 enhancing the modularity and maintainability of the codebase by resolving several circular import issues. By relocating shared configuration models and error classes to more appropriate, independent modules, the system's dependency graph is simplified, making it easier to understand and extend. Additionally, it incorporates an important dependency update for Highlights
Changelog
Activity
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
Pull request overview
This PR removes a couple of circular import edges by relocating shared configuration and error types into leaf modules, updates LiteLLM to align with upstream streaming types, and adjusts release-please tagging to match CI tag triggers.
Changes:
- Moved
RetryConfig/RateLimiterConfigintoai_company.core.resilience_configand updated imports across config, providers, and tests. - Moved budget exhaustion errors into
ai_company.budget.errorsand updated engine/budget wiring plus unit tests. - Bumped
litellmto 1.82.1 and updated integration test streaming chunk types; fixed release-please tag format config.
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 |
Locks litellm to 1.82.1 to match updated test expectations. |
pyproject.toml |
Bumps litellm dependency to 1.82.1. |
.github/release-please-config.json |
Ensures tags are vX.Y.Z by disabling component-in-tag. |
src/ai_company/core/resilience_config.py |
New canonical home for RetryConfig and RateLimiterConfig to avoid circular imports. |
src/ai_company/config/schema.py |
Imports resilience configs from core.resilience_config instead of defining them inline. |
src/ai_company/providers/resilience/retry.py |
Updates type-only import of RetryConfig to the new module. |
src/ai_company/providers/resilience/rate_limiter.py |
Switches RateLimiterConfig import to the new module. |
src/ai_company/providers/resilience/config.py |
Deletes the old re-export shim module. |
src/ai_company/providers/resilience/__init__.py |
Removes config model re-exports from the resilience public surface. |
src/ai_company/providers/__init__.py |
Stops re-exporting resilience config models from ai_company.providers. |
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 to break cycles. |
src/ai_company/providers/routing/resolver.py |
Moves ProviderConfig import behind TYPE_CHECKING to break cycles. |
src/ai_company/providers/routing/_strategy_helpers.py |
Moves routing config imports behind TYPE_CHECKING to break cycles. |
src/ai_company/budget/errors.py |
New leaf-module budget exception hierarchy. |
src/ai_company/budget/enforcer.py |
Imports budget exceptions from ai_company.budget.errors. |
src/ai_company/budget/__init__.py |
Re-exports budget errors at the budget package level. |
src/ai_company/engine/errors.py |
Removes budget exceptions from the engine error hierarchy. |
src/ai_company/engine/agent_engine.py |
Catches BudgetExhaustedError from the budget layer rather than engine errors. |
src/ai_company/engine/__init__.py |
Removes budget error re-exports from engine package exports. |
tests/unit/providers/resilience/test_retry.py |
Updates imports to new RetryConfig location. |
tests/unit/providers/resilience/test_rate_limiter.py |
Updates imports to new RateLimiterConfig location. |
tests/unit/providers/resilience/test_config.py |
Updates imports to new resilience config module. |
tests/unit/providers/resilience/conftest.py |
Updates imports to new resilience config module. |
tests/unit/providers/drivers/conftest.py |
Splits config imports to avoid pulling resilience configs from config.schema. |
tests/integration/providers/test_retry_integration.py |
Splits config imports to use new resilience config module. |
tests/integration/providers/conftest.py |
Updates streaming helper types to ModelResponseStream. |
tests/unit/config/conftest.py |
Updates imports for resilience configs. |
tests/unit/engine/test_errors.py |
Updates assertions to reflect budget errors no longer subclass EngineError. |
tests/unit/engine/test_agent_engine_budget.py |
Adds quota exhaustion to parametrized budget stop behavior. |
tests/unit/budget/test_errors.py |
New unit tests covering budget error hierarchy and behavior. |
tests/unit/budget/test_enforcer_quota.py |
Updates quota exhaustion error import to new module. |
tests/unit/budget/test_enforcer.py |
Updates budget error imports to new module. |
DESIGN_SPEC.md |
Updates project structure docs for new/removed modules. |
CLAUDE.md |
Updates package structure notes for budget/ and core/ additions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Code Review
This is an excellent refactoring pull request that successfully resolves circular import issues by moving shared configuration and error classes to more appropriate, central locations. The changes are well-structured, consistent across the codebase, and thoroughly tested. The documentation has also been updated to reflect the new file structure. The litellm dependency bump and the fix for the release tag format are also valuable improvements. I have one minor suggestion to improve the accuracy of a docstring in the new budget/errors.py file.
src/ai_company/budget/errors.py
Outdated
| when pre-flight budget checks fail (monthly hard stop or daily | ||
| limit exceeded). |
There was a problem hiding this comment.
The docstring for BudgetExhaustedError mentions it's raised for "monthly hard stop or daily limit exceeded". Since QuotaExhaustedError is now also a subclass and is raised in the same context, it would be more accurate to make this description more general or include quota exhaustion as an example. This would improve clarity for future developers.
| when pre-flight budget checks fail (monthly hard stop or daily | |
| limit exceeded). | |
| when pre-flight budget checks fail (e.g., monthly hard stop, daily | |
| limit, or provider quota exceeded). |
Greptile SummaryThis PR resolves circular import chains in the Key changes:
Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
subgraph core["core/ (shared leaf)"]
RC["resilience_config.py\nRetryConfig\nRateLimiterConfig"]
end
subgraph budget["budget/ (leaf)"]
BE["errors.py\nBudgetExhaustedError\nDailyLimitExceededError\nQuotaExhaustedError"]
ENF["enforcer.py\nBudgetEnforcer"]
end
subgraph config["config/"]
CS["schema.py\nRootConfig\nProviderConfig"]
end
subgraph providers["providers/"]
PR["resilience/\nRetryHandler\nRateLimiter"]
RT["routing/\nModelRouter\nstrategies.py\nresolver.py\n_strategy_helpers.py"]
end
subgraph engine["engine/"]
AE["agent_engine.py\nAgentEngine"]
EE["errors.py\nEngineError\n(no budget errors)"]
end
RC --> CS
RC --> PR
BE --> ENF
BE --> AE
CS -.->|"TYPE_CHECKING only"| RT
ENF --> AE
style core fill:#e8f5e9,stroke:#4caf50
style budget fill:#e3f2fd,stroke:#2196f3
style config fill:#fff3e0,stroke:#ff9800
style providers fill:#f3e5f5,stroke:#9c27b0
style engine fill:#fce4ec,stroke:#e91e63
Last reviewed commit: a7a5404 |
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 `@src/ai_company/budget/__init__.py`:
- Around line 41-45: Restore the deprecated aliases so existing imports keep
working: re-add the old re-exports that previously lived under ai_company.engine
and ai_company.engine.errors (i.e., ensure BudgetExhaustedError,
DailyLimitExceededError, QuotaExhaustedError are still importable from the old
paths) and mark them as deprecated (emit a DeprecationWarning when imported) so
consumers get one release to migrate; apply the same re-export+warning pattern
for the other affected symbols referenced in lines 108-145.
In `@src/ai_company/providers/resilience/__init__.py`:
- Around line 7-15: The package removed deprecated exports `RetryConfig` and
`RateLimiterConfig`, breaking callers that import them from the top-level;
restore compatibility by re-exporting those deprecated names: import
`RetryConfig` from `retry` and `RateLimiterConfig` from `rate_limiter` (or
create thin aliases if the originals moved/renamed), add them to the `__all__`
list alongside `RateLimiter`, `RetryExhaustedError`, and `RetryHandler`, and
include a short deprecation comment noting they will be removed in the next
release so callers can migrate.
In `@tests/unit/budget/test_errors.py`:
- Around line 21-29: Replace the two nearly identical tests with a single
parametrized pytest test: create one test (e.g.,
test_subtypes_are_budget_exhausted) annotated with `@pytest.mark.parametrize` over
the subclass types [DailyLimitExceededError, QuotaExhaustedError], and inside
assert both issubclass(sub, BudgetExhaustedError) and isinstance(sub("msg"),
BudgetExhaustedError); update or fold the similar repeated assertions later in
the file into the same pattern to keep tests DRY.
In `@tests/unit/providers/resilience/test_config.py`:
- Line 6: The removal of the old module path breaks downstream imports for
RetryConfig and RateLimiterConfig; restore a compatibility shim by re-adding
ai_company.providers.resilience.config that re-exports RateLimiterConfig and
RetryConfig from ai_company.core.resilience_config (i.e., export the same
symbols from the new module path), or if you prefer a breaking change, update
release notes to mark this as breaking—implement the shim so imports like from
ai_company.providers.resilience.config import RetryConfig continue to work
during the next release cycle.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 87a4b88c-ac3b-446f-a8fb-a5fcbb7e8162
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (34)
.github/release-please-config.jsonCLAUDE.mdDESIGN_SPEC.mdpyproject.tomlsrc/ai_company/budget/__init__.pysrc/ai_company/budget/enforcer.pysrc/ai_company/budget/errors.pysrc/ai_company/config/schema.pysrc/ai_company/core/resilience_config.pysrc/ai_company/engine/__init__.pysrc/ai_company/engine/agent_engine.pysrc/ai_company/engine/errors.pysrc/ai_company/providers/__init__.pysrc/ai_company/providers/resilience/__init__.pysrc/ai_company/providers/resilience/config.pysrc/ai_company/providers/resilience/rate_limiter.pysrc/ai_company/providers/resilience/retry.pysrc/ai_company/providers/routing/_strategy_helpers.pysrc/ai_company/providers/routing/resolver.pysrc/ai_company/providers/routing/router.pysrc/ai_company/providers/routing/strategies.pytests/integration/providers/conftest.pytests/integration/providers/test_retry_integration.pytests/unit/budget/test_enforcer.pytests/unit/budget/test_enforcer_quota.pytests/unit/budget/test_errors.pytests/unit/config/conftest.pytests/unit/engine/test_agent_engine_budget.pytests/unit/engine/test_errors.pytests/unit/providers/drivers/conftest.pytests/unit/providers/resilience/conftest.pytests/unit/providers/resilience/test_config.pytests/unit/providers/resilience/test_rate_limiter.pytests/unit/providers/resilience/test_retry.py
💤 Files with no reviewable changes (4)
- src/ai_company/providers/init.py
- src/ai_company/providers/resilience/config.py
- src/ai_company/engine/init.py
- src/ai_company/engine/errors.py
📜 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). (2)
- GitHub Check: Agent
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (5)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Use Python 3.14+ with PEP 649 native lazy annotations
Do NOT usefrom __future__ import annotations— Python 3.14 has PEP 649
Use PEP 758 except syntax:except A, B:(no parentheses) — ruff enforces this on Python 3.14
Include type hints on all public functions; enforce mypy strict mode
Use Google style docstrings, required on all public classes and functions (enforced by ruff D rules)
Create new objects instead of mutating existing ones — practice immutability
For non-Pydantic internal collections (registries, BaseTool), usecopy.deepcopy()at construction +MappingProxyTypewrapping for read-only enforcement
Fordict/listfields in frozen Pydantic models, rely onfrozen=Truefor field reassignment prevention andcopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, serializing for persistence)
Use frozen Pydantic models for config/identity; use separate mutable-via-copy models (usingmodel_copy(update=...)) for runtime state that evolves. Never mix static config fields with mutable runtime fields in one model
Use Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values instead of storing + validating redundant fields. UseNotBlankStr(fromcore.types) for all identifier/name fields
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code (e.g. multiple tool invocations, parallel agent calls). Prefer structured concurrency over barecreate_task. Existing code is being migrated incrementally
Limit line length to 88 characters (ruff enforced)
Keep functions under 50 lines; keep files under 800 lines
Handle errors explicitly; never silently swallow exceptions
Validate at system boundaries (user input, external APIs, config files)
Files:
src/ai_company/config/schema.pysrc/ai_company/engine/agent_engine.pysrc/ai_company/core/resilience_config.pysrc/ai_company/budget/errors.pytests/unit/budget/test_enforcer_quota.pytests/unit/providers/resilience/conftest.pytests/unit/budget/test_errors.pytests/unit/engine/test_agent_engine_budget.pytests/unit/config/conftest.pysrc/ai_company/providers/resilience/__init__.pytests/unit/providers/resilience/test_config.pysrc/ai_company/providers/routing/_strategy_helpers.pytests/unit/budget/test_enforcer.pytests/unit/providers/resilience/test_rate_limiter.pysrc/ai_company/budget/__init__.pysrc/ai_company/providers/routing/resolver.pytests/unit/providers/drivers/conftest.pytests/integration/providers/test_retry_integration.pytests/unit/providers/resilience/test_retry.pytests/integration/providers/conftest.pytests/unit/engine/test_errors.pysrc/ai_company/budget/enforcer.pysrc/ai_company/providers/resilience/retry.pysrc/ai_company/providers/resilience/rate_limiter.pysrc/ai_company/providers/routing/strategies.pysrc/ai_company/providers/routing/router.py
src/ai_company/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/ai_company/**/*.py: Every module with business logic MUST havefrom ai_company.observability import get_loggerthenlogger = get_logger(__name__)
Never useimport logging/logging.getLogger()/print()in application code — use the observability module
Always use variable namelogger(not_logger, notlog)
Use event name constants from domain-specific modules underai_company.observability.events(e.g.PROVIDER_CALL_STARTfromevents.provider). Import directly:from ai_company.observability.events.<domain> import EVENT_CONSTANT
Use structured logging format: alwayslogger.info(EVENT, key=value)— neverlogger.info('msg %s', val)
Log all error paths at WARNING or ERROR with context before raising exceptions
Log all state transitions at INFO level
Use DEBUG level for object creation, internal flow, entry/exit of key functions
Pure data models, enums, and re-exports do NOT need logging
All provider calls must go throughBaseCompletionProviderwhich applies retry + rate limiting automatically — never implement retry logic in driver subclasses or calling code
SetRetryConfigandRateLimiterConfigper-provider inProviderConfig
Retryable errors (is_retryable=True) include:RateLimitError,ProviderTimeoutError,ProviderConnectionError,ProviderInternalError. Non-retryable errors raise immediately without retry
The rate limiter automatically respectsRateLimitError.retry_afterfrom providers — automatically pauses future requests
NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001,large/medium/smallas aliases
Files:
src/ai_company/config/schema.pysrc/ai_company/engine/agent_engine.pysrc/ai_company/core/resilience_config.pysrc/ai_company/budget/errors.pysrc/ai_company/providers/resilience/__init__.pysrc/ai_company/providers/routing/_strategy_helpers.pysrc/ai_company/budget/__init__.pysrc/ai_company/providers/routing/resolver.pysrc/ai_company/budget/enforcer.pysrc/ai_company/providers/resilience/retry.pysrc/ai_company/providers/resilience/rate_limiter.pysrc/ai_company/providers/routing/strategies.pysrc/ai_company/providers/routing/router.py
pyproject.toml
📄 CodeRabbit inference engine (CLAUDE.md)
pyproject.toml: All dependency versions use==inpyproject.toml(pinned versions)
Organize dependencies into groups:test(pytest + plugins),dev(includes test + ruff, mypy, pre-commit, commitizen). Install withuv sync(installs everything; dev group is default)
Files:
pyproject.toml
src/ai_company/engine/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
RetryExhaustedErrorsignals that all retries failed — the engine layer must catch this to trigger fallback chains
Files:
src/ai_company/engine/agent_engine.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Mark tests with@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e, or@pytest.mark.slow
Prefer@pytest.mark.parametrizefor testing similar cases in test files
Usetest-provider,test-small-001, etc. as generic vendor names in test files
Files:
tests/unit/budget/test_enforcer_quota.pytests/unit/providers/resilience/conftest.pytests/unit/budget/test_errors.pytests/unit/engine/test_agent_engine_budget.pytests/unit/config/conftest.pytests/unit/providers/resilience/test_config.pytests/unit/budget/test_enforcer.pytests/unit/providers/resilience/test_rate_limiter.pytests/unit/providers/drivers/conftest.pytests/integration/providers/test_retry_integration.pytests/unit/providers/resilience/test_retry.pytests/integration/providers/conftest.pytests/unit/engine/test_errors.py
🧠 Learnings (10)
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to src/ai_company/**/*.py : Set `RetryConfig` and `RateLimiterConfig` per-provider in `ProviderConfig`
Applied to files:
src/ai_company/config/schema.pysrc/ai_company/core/resilience_config.pytests/unit/providers/resilience/conftest.pytests/unit/config/conftest.pysrc/ai_company/providers/resilience/__init__.pytests/unit/providers/resilience/test_config.pytests/unit/providers/resilience/test_rate_limiter.pysrc/ai_company/providers/routing/resolver.pytests/unit/providers/drivers/conftest.pytests/integration/providers/test_retry_integration.pytests/unit/providers/resilience/test_retry.pysrc/ai_company/providers/resilience/retry.pysrc/ai_company/providers/resilience/rate_limiter.pysrc/ai_company/providers/routing/router.pyDESIGN_SPEC.md
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to src/ai_company/**/*.py : Retryable errors (`is_retryable=True`) include: `RateLimitError`, `ProviderTimeoutError`, `ProviderConnectionError`, `ProviderInternalError`. Non-retryable errors raise immediately without retry
Applied to files:
src/ai_company/config/schema.pyCLAUDE.mdsrc/ai_company/engine/agent_engine.pysrc/ai_company/core/resilience_config.pytests/unit/budget/test_enforcer_quota.pytests/unit/providers/resilience/conftest.pysrc/ai_company/providers/resilience/__init__.pytests/unit/providers/resilience/test_config.pysrc/ai_company/budget/__init__.pytests/unit/providers/drivers/conftest.pytests/integration/providers/test_retry_integration.pytests/unit/providers/resilience/test_retry.pytests/unit/engine/test_errors.pysrc/ai_company/providers/resilience/retry.py
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to src/ai_company/**/*.py : The rate limiter automatically respects `RateLimitError.retry_after` from providers — automatically pauses future requests
Applied to files:
src/ai_company/config/schema.pysrc/ai_company/core/resilience_config.pytests/unit/providers/resilience/conftest.pysrc/ai_company/providers/resilience/__init__.pytests/unit/providers/resilience/test_config.pytests/unit/providers/resilience/test_rate_limiter.pytests/unit/providers/drivers/conftest.pytests/integration/providers/test_retry_integration.pytests/unit/providers/resilience/test_retry.pysrc/ai_company/providers/resilience/rate_limiter.py
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to pyproject.toml : All dependency versions use `==` in `pyproject.toml` (pinned versions)
Applied to files:
pyproject.toml
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Use Release Please (Google) for automated release management. Merging release PR creates git tag (`vX.Y.Z`) + GitHub Release with changelog. Config in `.github/release-please-config.json` and `.github/.release-please-manifest.json`
Applied to files:
.github/release-please-config.json
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to src/ai_company/engine/**/*.py : `RetryExhaustedError` signals that all retries failed — the engine layer must catch this to trigger fallback chains
Applied to files:
src/ai_company/engine/agent_engine.pysrc/ai_company/budget/errors.pytests/unit/providers/resilience/test_retry.pytests/unit/engine/test_errors.py
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to src/ai_company/**/*.py : Log all error paths at WARNING or ERROR with context before raising exceptions
Applied to files:
src/ai_company/engine/agent_engine.pysrc/ai_company/budget/__init__.py
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to src/ai_company/**/*.py : Use event name constants from domain-specific modules under `ai_company.observability.events` (e.g. `PROVIDER_CALL_START` from `events.provider`). Import directly: `from ai_company.observability.events.<domain> import EVENT_CONSTANT`
Applied to files:
src/ai_company/engine/agent_engine.py
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to src/ai_company/**/*.py : All provider calls must go through `BaseCompletionProvider` which applies retry + rate limiting automatically — never implement retry logic in driver subclasses or calling code
Applied to files:
tests/unit/providers/resilience/conftest.pytests/unit/providers/resilience/test_config.pytests/unit/providers/drivers/conftest.pytests/integration/providers/test_retry_integration.pytests/unit/providers/resilience/test_retry.pysrc/ai_company/providers/resilience/retry.py
📚 Learning: 2026-03-10T22:52:37.949Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T22:52:37.949Z
Learning: Applies to **/*.py : For non-Pydantic internal collections (registries, BaseTool), use `copy.deepcopy()` at construction + `MappingProxyType` wrapping for read-only enforcement
Applied to files:
src/ai_company/providers/routing/strategies.py
🧬 Code graph analysis (23)
src/ai_company/config/schema.py (1)
src/ai_company/core/resilience_config.py (2)
RateLimiterConfig(76-97)RetryConfig(17-73)
src/ai_company/engine/agent_engine.py (2)
src/ai_company/budget/errors.py (1)
BudgetExhaustedError(9-20)src/ai_company/engine/errors.py (1)
ExecutionStateError(12-13)
src/ai_company/core/resilience_config.py (1)
src/ai_company/observability/_logger.py (1)
get_logger(8-28)
tests/unit/budget/test_enforcer_quota.py (1)
src/ai_company/budget/errors.py (1)
QuotaExhaustedError(27-32)
tests/unit/providers/resilience/conftest.py (1)
src/ai_company/core/resilience_config.py (2)
RateLimiterConfig(76-97)RetryConfig(17-73)
tests/unit/budget/test_errors.py (2)
src/ai_company/budget/errors.py (3)
BudgetExhaustedError(9-20)DailyLimitExceededError(23-24)QuotaExhaustedError(27-32)src/ai_company/engine/errors.py (1)
EngineError(4-5)
tests/unit/config/conftest.py (1)
src/ai_company/core/resilience_config.py (2)
RateLimiterConfig(76-97)RetryConfig(17-73)
tests/unit/providers/resilience/test_config.py (1)
src/ai_company/core/resilience_config.py (2)
RateLimiterConfig(76-97)RetryConfig(17-73)
src/ai_company/providers/routing/_strategy_helpers.py (1)
src/ai_company/config/schema.py (1)
RoutingRuleConfig(157-202)
tests/unit/budget/test_enforcer.py (1)
src/ai_company/budget/errors.py (2)
BudgetExhaustedError(9-20)DailyLimitExceededError(23-24)
tests/unit/providers/resilience/test_rate_limiter.py (1)
src/ai_company/core/resilience_config.py (1)
RateLimiterConfig(76-97)
src/ai_company/budget/__init__.py (1)
src/ai_company/budget/errors.py (3)
BudgetExhaustedError(9-20)DailyLimitExceededError(23-24)QuotaExhaustedError(27-32)
src/ai_company/providers/routing/resolver.py (1)
src/ai_company/config/schema.py (1)
ProviderConfig(81-154)
tests/unit/providers/drivers/conftest.py (2)
src/ai_company/config/schema.py (2)
ProviderConfig(81-154)ProviderModelConfig(39-78)src/ai_company/core/resilience_config.py (2)
RateLimiterConfig(76-97)RetryConfig(17-73)
tests/integration/providers/test_retry_integration.py (2)
src/ai_company/config/schema.py (2)
ProviderConfig(81-154)ProviderModelConfig(39-78)src/ai_company/core/resilience_config.py (2)
RateLimiterConfig(76-97)RetryConfig(17-73)
tests/unit/providers/resilience/test_retry.py (1)
src/ai_company/core/resilience_config.py (1)
RetryConfig(17-73)
tests/integration/providers/conftest.py (2)
src/ai_company/config/schema.py (2)
ProviderConfig(81-154)ProviderModelConfig(39-78)src/ai_company/core/resilience_config.py (1)
RetryConfig(17-73)
tests/unit/engine/test_errors.py (2)
src/ai_company/budget/errors.py (1)
BudgetExhaustedError(9-20)src/ai_company/engine/errors.py (1)
EngineError(4-5)
src/ai_company/budget/enforcer.py (2)
src/ai_company/budget/errors.py (3)
BudgetExhaustedError(9-20)DailyLimitExceededError(23-24)QuotaExhaustedError(27-32)src/ai_company/budget/quota.py (1)
QuotaCheckResult(285-314)
src/ai_company/providers/resilience/retry.py (1)
src/ai_company/core/resilience_config.py (1)
RetryConfig(17-73)
src/ai_company/providers/resilience/rate_limiter.py (1)
src/ai_company/core/resilience_config.py (1)
RateLimiterConfig(76-97)
src/ai_company/providers/routing/strategies.py (1)
src/ai_company/config/schema.py (1)
RoutingConfig(205-227)
src/ai_company/providers/routing/router.py (1)
src/ai_company/config/schema.py (2)
ProviderConfig(81-154)RoutingConfig(205-227)
🔇 Additional comments (22)
.github/release-please-config.json (1)
7-7: No action needed—tag format change is safe for this repository.The
"include-component-in-tag": falsesetting is correct for plainvX.Y.Ztag format. Since this repository has no existing tags, there is no risk of historical tag conflicts. The configuration is ready for the first Release Please-managed release.> Likely an incorrect or invalid review comment.pyproject.toml (1)
20-20: litellm version 1.82.1 is valid and secure.Version 1.82.1 exists on PyPI as the latest release and has no known CVEs or security advisories. All dependencies follow the pinning guideline with
==, and the dependency groups (test,dev) are properly organized.src/ai_company/core/resilience_config.py (1)
17-97: Good extraction target for the shared resilience models.Moving these frozen config models into
coreremoves the schema/provider cycle without duplicating validation logic, and the validator still logs invalid config with useful context before failing.src/ai_company/config/schema.py (1)
21-21: Nice compatibility bridge.Importing these types into
config.schemakeeps existingfrom ai_company.config.schema import RetryConfigcall sites working while the canonical definitions move tocore.tests/integration/providers/conftest.py (1)
16-22: Streaming fixtures now match the updated LiteLLM surface.Switching the chunk builders and
async_iter_chunks()toModelResponseStreamkeeps these integration helpers aligned with the stream-specific types used by the updated provider tests.Also applies to: 170-259
src/ai_company/providers/routing/resolver.py (1)
10-24:TYPE_CHECKINGis the right fix for this import cycle.This keeps the
from_config()type information intact without reintroducing a runtime dependency onai_company.config.schema.tests/unit/engine/test_agent_engine_budget.py (1)
53-60: Nice coverage addition for quota preflight failures.Including
QuotaExhaustedErrorhere closes the gap introduced by the new budget-domain exception and keeps the engine contract pinned toTerminationReason.BUDGET_EXHAUSTED.tests/unit/providers/resilience/conftest.py (1)
5-5: LGTM!Import path correctly updated to the new canonical location
ai_company.core.resilience_config. This aligns with the PR's refactoring of resilience configuration models to the core module.src/ai_company/engine/agent_engine.py (2)
12-12: LGTM!Import path correctly updated to
ai_company.budget.errorsforBudgetExhaustedError. This properly reflects the new module hierarchy where budget-related errors are now in the budget package.
22-22: Correct separation of concerns.
ExecutionStateErrorremains imported fromai_company.engine.errorsas expected—it's an engine-layer error, not a budget error. The distinction between engine errors and budget errors is now properly reflected in the import structure.tests/unit/budget/test_enforcer_quota.py (1)
14-14: LGTM!Import path correctly updated to
ai_company.budget.errorsforQuotaExhaustedError. Test markers and generic provider names ("test-provider") are properly used per coding guidelines.tests/unit/engine/test_errors.py (2)
5-5: LGTM!Import path correctly updated to reflect the new module location for
BudgetExhaustedError.
37-41: Test logic correctly updated for the new error hierarchy.The test now properly verifies that
BudgetExhaustedErroris not a subclass ofEngineErrorand inherits directly fromException. This accurately reflects the architectural decision to decouple budget errors from the engine error hierarchy.src/ai_company/providers/routing/strategies.py (1)
10-10: LGTM!
TYPE_CHECKINGguard correctly added forRoutingConfig. SinceRoutingConfigis only used in type annotations (method signatures), deferring the import to type-checking time avoids circular import issues at runtime. This works correctly with Python 3.14's PEP 649 lazy annotation evaluation.Also applies to: 37-39
tests/unit/providers/resilience/test_rate_limiter.py (1)
10-10: LGTM!Import path correctly updated to
ai_company.core.resilience_configforRateLimiterConfig. This aligns with the PR's refactoring of resilience configuration models to the core module.src/ai_company/providers/routing/_strategy_helpers.py (1)
7-8: LGTM!
TYPE_CHECKINGguard correctly added forRoutingConfigandRoutingRuleConfig. Both types are used exclusively in function signatures (type annotations), so deferring imports to type-checking time properly resolves circular import issues without affecting runtime behavior.Also applies to: 22-24
src/ai_company/providers/routing/router.py (1)
7-8: LGTM!
TYPE_CHECKINGguard correctly added forProviderConfigandRoutingConfig. Both types are used only in the__init__signature annotations, so deferring imports to type-checking time properly resolves circular import issues. This completes the routing module's circular import fixes alongsidestrategies.pyand_strategy_helpers.py.Also applies to: 22-24
tests/unit/config/conftest.py (1)
23-23: Canonical resilience-config import looks right.Pointing the fixtures at
ai_company.core.resilience_configkeeps the tests aligned with the new source of truth for provider retry and rate-limit settings.tests/unit/providers/drivers/conftest.py (1)
8-9: Import split matches the new ownership boundary.Keeping
ProviderConfiginai_company.config.schemaand movingRetryConfig/RateLimiterConfigtoai_company.core.resilience_configmakes the test fixture mirror the runtime model layout.tests/unit/budget/test_errors.py (2)
11-15: Test markers are set up correctly.The module timeout plus class-level
@pytest.mark.unitkeeps this file aligned with the suite’s test classification conventions.
31-42: Good coverage for the decoupling contract.These assertions lock in the important behavioral change: budget exhaustion is now independent from
EngineError, and the base exception still preserves its message payload.src/ai_company/budget/errors.py (1)
1-32: Clean leaf-module split for the budget exceptions.Defining this hierarchy in
ai_company.budget.errorswith no intra-project imports is a solid way to break the previous engine↔budget dependency cycle while keeping the subtype relationships explicit.
| from ai_company.budget.errors import ( | ||
| BudgetExhaustedError, | ||
| DailyLimitExceededError, | ||
| QuotaExhaustedError, | ||
| ) |
There was a problem hiding this comment.
Removing the old budget-error aliases is another patch-level API break.
These new exports are fine as the canonical budget namespace, but the PR summary also removes the previous ai_company.engine / ai_company.engine.errors re-exports. Existing consumers importing these exceptions from the old paths will start failing immediately on a fix: release. Keep deprecated aliases for one release, or ship this as an explicit breaking change.
Also applies to: 108-145
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/ai_company/budget/__init__.py` around lines 41 - 45, Restore the
deprecated aliases so existing imports keep working: re-add the old re-exports
that previously lived under ai_company.engine and ai_company.engine.errors
(i.e., ensure BudgetExhaustedError, DailyLimitExceededError, QuotaExhaustedError
are still importable from the old paths) and mark them as deprecated (emit a
DeprecationWarning when imported) so consumers get one release to migrate; apply
the same re-export+warning pattern for the other affected symbols referenced in
lines 108-145.
| from .errors import RetryExhaustedError | ||
| from .rate_limiter import RateLimiter | ||
| from .retry import RetryHandler | ||
|
|
||
| __all__ = [ | ||
| "RateLimiter", | ||
| "RateLimiterConfig", | ||
| "RetryConfig", | ||
| "RetryExhaustedError", | ||
| "RetryHandler", | ||
| ] |
There was a problem hiding this comment.
Keep deprecated config re-exports for one release cycle.
Removing RetryConfig and RateLimiterConfig from this package namespace will break any existing from ai_company.providers.resilience import ... callers immediately. Either keep deprecated aliases here for compatibility, or treat this as an explicit breaking release with migration notes.
♻️ Compatibility-preserving diff
+from ai_company.core.resilience_config import RateLimiterConfig, RetryConfig
from .errors import RetryExhaustedError
from .rate_limiter import RateLimiter
from .retry import RetryHandler
__all__ = [
"RateLimiter",
+ "RateLimiterConfig",
"RetryExhaustedError",
+ "RetryConfig",
"RetryHandler",
]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/ai_company/providers/resilience/__init__.py` around lines 7 - 15, The
package removed deprecated exports `RetryConfig` and `RateLimiterConfig`,
breaking callers that import them from the top-level; restore compatibility by
re-exporting those deprecated names: import `RetryConfig` from `retry` and
`RateLimiterConfig` from `rate_limiter` (or create thin aliases if the originals
moved/renamed), add them to the `__all__` list alongside `RateLimiter`,
`RetryExhaustedError`, and `RetryHandler`, and include a short deprecation
comment noting they will be removed in the next release so callers can migrate.
| from pydantic import ValidationError | ||
|
|
||
| from ai_company.providers.resilience.config import RateLimiterConfig, RetryConfig | ||
| from ai_company.core.resilience_config import RateLimiterConfig, RetryConfig |
There was a problem hiding this comment.
Deleting the old resilience-config shim is a breaking API change.
This import update is fine internally, but the PR summary says ai_company.providers.resilience.config was removed rather than kept as a deprecation shim. Any downstream code still importing RetryConfig or RateLimiterConfig from the old path will fail on the next patch release. Keep the old module re-exporting the new symbols for one release, or mark the release as breaking.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/unit/providers/resilience/test_config.py` at line 6, The removal of the
old module path breaks downstream imports for RetryConfig and RateLimiterConfig;
restore a compatibility shim by re-adding ai_company.providers.resilience.config
that re-exports RateLimiterConfig and RetryConfig from
ai_company.core.resilience_config (i.e., export the same symbols from the new
module path), or if you prefer a breaking change, update release notes to mark
this as breaking—implement the shim so imports like from
ai_company.providers.resilience.config import RetryConfig continue to work
during the next release cycle.
There was a problem hiding this comment.
Code Review
This is a well-executed pull request that successfully resolves circular dependencies through thoughtful refactoring. The updates to dependencies, documentation, and release configuration are also appreciated and correctly implemented. One critical issue was identified outside the scope of this diff: src/ai_company/budget/enforcer.py contains Python 2-style except syntax on lines 133 and 302 (e.g., except MemoryError, RecursionError:). This will cause a SyntaxError in Python 3. The correct syntax is except (MemoryError, RecursionError):. While I cannot comment directly on these lines as they are not part of the changes in this PR, this is a critical fix that is required for the code to be runnable.
- BudgetExhaustedError docstring: mention quota exhaustion, fix "converted into" → "used to build AgentRunResult" - QuotaExhaustedError docstring: replace "tracked in M7" with "not yet implemented" (durable phrasing) - Parametrize repeated subtype tests per project conventions - Remove duplicate security.py entry in DESIGN_SPEC.md events tree
| from litellm.types.utils import ( # type: ignore[attr-defined] | ||
| ChatCompletionToolCallChunk, | ||
| Delta, | ||
| ModelResponseStream, | ||
| StreamingChoices, | ||
| Usage, | ||
| ) |
There was a problem hiding this comment.
Broad type: ignore suppresses all type errors on the import
The # type: ignore[attr-defined] is placed on the entire multi-line import block. This means any future missing or renamed symbol in the same import block will silently pass type checking without any indication. A narrower suppression (or a per-symbol comment) would be safer. If ModelResponseStream is the only symbol not yet in litellm's stubs, consider isolating it:
| from litellm.types.utils import ( # type: ignore[attr-defined] | |
| ChatCompletionToolCallChunk, | |
| Delta, | |
| ModelResponseStream, | |
| StreamingChoices, | |
| Usage, | |
| ) | |
| from litellm.types.utils import ( | |
| ChatCompletionToolCallChunk, | |
| Delta, | |
| ModelResponseStream, # type: ignore[attr-defined] # not yet in litellm stubs | |
| StreamingChoices, | |
| Usage, | |
| ) |
Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/integration/providers/conftest.py
Line: 13-19
Comment:
**Broad `type: ignore` suppresses all type errors on the import**
The `# type: ignore[attr-defined]` is placed on the entire multi-line import block. This means any *future* missing or renamed symbol in the same import block will silently pass type checking without any indication. A narrower suppression (or a per-symbol comment) would be safer. If `ModelResponseStream` is the only symbol not yet in litellm's stubs, consider isolating it:
```suggestion
from litellm.types.utils import (
ChatCompletionToolCallChunk,
Delta,
ModelResponseStream, # type: ignore[attr-defined] # not yet in litellm stubs
StreamingChoices,
Usage,
)
```
How can I resolve this? If you propose a fix, please make it concise.🤖 I have created a release *beep* *boop* --- ## [0.1.0](v0.0.0...v0.1.0) (2026-03-11) ### Features * add autonomy levels and approval timeout policies ([#42](#42), [#126](#126)) ([#197](#197)) ([eecc25a](eecc25a)) * add CFO cost optimization service with anomaly detection, reports, and approval decisions ([#186](#186)) ([a7fa00b](a7fa00b)) * add code quality toolchain (ruff, mypy, pre-commit, dependabot) ([#63](#63)) ([36681a8](36681a8)) * add configurable cost tiers and subscription/quota-aware tracking ([#67](#67)) ([#185](#185)) ([9baedfa](9baedfa)) * add container packaging, Docker Compose, and CI pipeline ([#269](#269)) ([435bdfe](435bdfe)), closes [#267](#267) * add coordination error taxonomy classification pipeline ([#146](#146)) ([#181](#181)) ([70c7480](70c7480)) * add cost-optimized, hierarchical, and auction assignment strategies ([#175](#175)) ([ce924fa](ce924fa)), closes [#173](#173) * add design specification, license, and project setup ([8669a09](8669a09)) * add env var substitution and config file auto-discovery ([#77](#77)) ([7f53832](7f53832)) * add FastestStrategy routing + vendor-agnostic cleanup ([#140](#140)) ([09619cb](09619cb)), closes [#139](#139) * add HR engine and performance tracking ([#45](#45), [#47](#47)) ([#193](#193)) ([2d091ea](2d091ea)) * add issue auto-search and resolution verification to PR review skill ([#119](#119)) ([deecc39](deecc39)) * add mandatory JWT + API key authentication ([#256](#256)) ([c279cfe](c279cfe)) * add memory retrieval, ranking, and context injection pipeline ([#41](#41)) ([873b0aa](873b0aa)) * add pluggable MemoryBackend protocol with models, config, and events ([#180](#180)) ([46cfdd4](46cfdd4)) * add pluggable MemoryBackend protocol with models, config, and events ([#32](#32)) ([46cfdd4](46cfdd4)) * add pluggable output scan response policies ([#263](#263)) ([b9907e8](b9907e8)) * add pluggable PersistenceBackend protocol with SQLite implementation ([#36](#36)) ([f753779](f753779)) * add progressive trust and promotion/demotion subsystems ([#43](#43), [#49](#49)) ([3a87c08](3a87c08)) * add retry handler, rate limiter, and provider resilience ([#100](#100)) ([b890545](b890545)) * add SecOps security agent with rule engine, audit log, and ToolInvoker integration ([#40](#40)) ([83b7b6c](83b7b6c)) * add shared org memory and memory consolidation/archival ([#125](#125), [#48](#48)) ([4a0832b](4a0832b)) * design unified provider interface ([#86](#86)) ([3e23d64](3e23d64)) * expand template presets, rosters, and add inheritance ([#80](#80), [#81](#81), [#84](#84)) ([15a9134](15a9134)) * implement agent runtime state vs immutable config split ([#115](#115)) ([4cb1ca5](4cb1ca5)) * implement AgentEngine core orchestrator ([#11](#11)) ([#143](#143)) ([f2eb73a](f2eb73a)) * implement AuditRepository for security audit log persistence ([#279](#279)) ([94bc29f](94bc29f)) * implement basic tool system (registry, invocation, results) ([#15](#15)) ([c51068b](c51068b)) * implement built-in file system tools ([#18](#18)) ([325ef98](325ef98)) * implement communication foundation — message bus, dispatcher, and messenger ([#157](#157)) ([8e71bfd](8e71bfd)) * implement company template system with 7 built-in presets ([#85](#85)) ([cbf1496](cbf1496)) * implement conflict resolution protocol ([#122](#122)) ([#166](#166)) ([e03f9f2](e03f9f2)) * implement core entity and role system models ([#69](#69)) ([acf9801](acf9801)) * implement crash recovery with fail-and-reassign strategy ([#149](#149)) ([e6e91ed](e6e91ed)) * implement engine extensions — Plan-and-Execute loop and call categorization ([#134](#134), [#135](#135)) ([#159](#159)) ([9b2699f](9b2699f)) * implement enterprise logging system with structlog ([#73](#73)) ([2f787e5](2f787e5)) * implement graceful shutdown with cooperative timeout strategy ([#130](#130)) ([6592515](6592515)) * implement hierarchical delegation and loop prevention ([#12](#12), [#17](#17)) ([6be60b6](6be60b6)) * implement LiteLLM driver and provider registry ([#88](#88)) ([ae3f18b](ae3f18b)), closes [#4](#4) * implement LLM decomposition strategy and workspace isolation ([#174](#174)) ([aa0eefe](aa0eefe)) * implement meeting protocol system ([#123](#123)) ([ee7caca](ee7caca)) * implement message and communication domain models ([#74](#74)) ([560a5d2](560a5d2)) * implement model routing engine ([#99](#99)) ([d3c250b](d3c250b)) * implement parallel agent execution ([#22](#22)) ([#161](#161)) ([65940b3](65940b3)) * implement per-call cost tracking service ([#7](#7)) ([#102](#102)) ([c4f1f1c](c4f1f1c)) * implement personality injection and system prompt construction ([#105](#105)) ([934dd85](934dd85)) * implement single-task execution lifecycle ([#21](#21)) ([#144](#144)) ([c7e64e4](c7e64e4)) * implement subprocess sandbox for tool execution isolation ([#131](#131)) ([#153](#153)) ([3c8394e](3c8394e)) * implement task assignment subsystem with pluggable strategies ([#172](#172)) ([c7f1b26](c7f1b26)), closes [#26](#26) [#30](#30) * implement task decomposition and routing engine ([#14](#14)) ([9c7fb52](9c7fb52)) * implement Task, Project, Artifact, Budget, and Cost domain models ([#71](#71)) ([81eabf1](81eabf1)) * implement tool permission checking ([#16](#16)) ([833c190](833c190)) * implement YAML config loader with Pydantic validation ([#59](#59)) ([ff3a2ba](ff3a2ba)) * implement YAML config loader with Pydantic validation ([#75](#75)) ([ff3a2ba](ff3a2ba)) * initialize project with uv, hatchling, and src layout ([39005f9](39005f9)) * initialize project with uv, hatchling, and src layout ([#62](#62)) ([39005f9](39005f9)) * Litestar REST API, WebSocket feed, and approval queue (M6) ([#189](#189)) ([29fcd08](29fcd08)) * make TokenUsage.total_tokens a computed field ([#118](#118)) ([c0bab18](c0bab18)), closes [#109](#109) * parallel tool execution in ToolInvoker.invoke_all ([#137](#137)) ([58517ee](58517ee)) * testing framework, CI pipeline, and M0 gap fixes ([#64](#64)) ([f581749](f581749)) * wire all modules into observability system ([#97](#97)) ([f7a0617](f7a0617)) ### Bug Fixes * address Greptile post-merge review findings from PRs [#170](https://github.com/Aureliolo/ai-company/issues/170)-[#175](https://github.com/Aureliolo/ai-company/issues/175) ([#176](#176)) ([c5ca929](c5ca929)) * address post-merge review feedback from PRs [#164](https://github.com/Aureliolo/ai-company/issues/164)-[#167](https://github.com/Aureliolo/ai-company/issues/167) ([#170](#170)) ([3bf897a](3bf897a)), closes [#169](#169) * enforce strict mypy on test files ([#89](#89)) ([aeeff8c](aeeff8c)) * harden Docker sandbox, MCP bridge, and code runner ([#50](#50), [#53](#53)) ([d5e1b6e](d5e1b6e)) * harden git tools security + code quality improvements ([#150](#150)) ([000a325](000a325)) * harden subprocess cleanup, env filtering, and shutdown resilience ([#155](#155)) ([d1fe1fb](d1fe1fb)) * incorporate post-merge feedback + pre-PR review fixes ([#164](#164)) ([c02832a](c02832a)) * pre-PR review fixes for post-merge findings ([#183](#183)) ([26b3108](26b3108)) * resolve circular imports, bump litellm, fix release tag format ([#286](#286)) ([a6659b5](a6659b5)) * strengthen immutability for BaseTool schema and ToolInvoker boundaries ([#117](#117)) ([7e5e861](7e5e861)) ### Performance * harden non-inferable principle implementation ([#195](#195)) ([02b5f4e](02b5f4e)), closes [#188](#188) ### Refactoring * adopt NotBlankStr across all models ([#108](#108)) ([#120](#120)) ([ef89b90](ef89b90)) * extract _SpendingTotals base class from spending summary models ([#111](#111)) ([2f39c1b](2f39c1b)) * harden BudgetEnforcer with error handling, validation extraction, and review fixes ([#182](#182)) ([c107bf9](c107bf9)) * harden personality profiles, department validation, and template rendering ([#158](#158)) ([10b2299](10b2299)) * pre-PR review improvements for ExecutionLoop + ReAct loop ([#124](#124)) ([8dfb3c0](8dfb3c0)) * split events.py into per-domain event modules ([#136](#136)) ([e9cba89](e9cba89)) ### Documentation * add ADR-001 memory layer evaluation and selection ([#178](#178)) ([db3026f](db3026f)), closes [#39](#39) * add agent scaling research findings to DESIGN_SPEC ([#145](#145)) ([57e487b](57e487b)) * add CLAUDE.md, contributing guide, and dev documentation ([#65](#65)) ([55c1025](55c1025)), closes [#54](#54) * add crash recovery, sandboxing, analytics, and testing decisions ([#127](#127)) ([5c11595](5c11595)) * address external review feedback with MVP scope and new protocols ([#128](#128)) ([3b30b9a](3b30b9a)) * expand design spec with pluggable strategy protocols ([#121](#121)) ([6832db6](6832db6)) * finalize 23 design decisions (ADR-002) ([#190](#190)) ([8c39742](8c39742)) * update project docs for M2.5 conventions and add docs-consistency review agent ([#114](#114)) ([99766ee](99766ee)) ### Tests * add e2e single agent integration tests ([#24](#24)) ([#156](#156)) ([f566fb4](f566fb4)) * add provider adapter integration tests ([#90](#90)) ([40a61f4](40a61f4)) ### CI/CD * add Release Please for automated versioning and GitHub Releases ([#278](#278)) ([a488758](a488758)) * bump actions/checkout from 4 to 6 ([#95](#95)) ([1897247](1897247)) * bump actions/upload-artifact from 4 to 7 ([#94](#94)) ([27b1517](27b1517)) * bump anchore/scan-action from 6.5.1 to 7.3.2 ([#271](#271)) ([80a1c15](80a1c15)) * bump docker/build-push-action from 6.19.2 to 7.0.0 ([#273](#273)) ([dd0219e](dd0219e)) * bump docker/login-action from 3.7.0 to 4.0.0 ([#272](#272)) ([33d6238](33d6238)) * bump docker/metadata-action from 5.10.0 to 6.0.0 ([#270](#270)) ([baee04e](baee04e)) * bump docker/setup-buildx-action from 3.12.0 to 4.0.0 ([#274](#274)) ([5fc06f7](5fc06f7)) * bump sigstore/cosign-installer from 3.9.1 to 4.1.0 ([#275](#275)) ([29dd16c](29dd16c)) * harden CI/CD pipeline ([#92](#92)) ([ce4693c](ce4693c)) * split vulnerability scans into critical-fail and high-warn tiers ([#277](#277)) ([aba48af](aba48af)) ### Maintenance * add /worktree skill for parallel worktree management ([#171](#171)) ([951e337](951e337)) * add design spec context loading to research-link skill ([8ef9685](8ef9685)) * add post-merge-cleanup skill ([#70](#70)) ([f913705](f913705)) * add pre-pr-review skill and update CLAUDE.md ([#103](#103)) ([92e9023](92e9023)) * add research-link skill and rename skill files to SKILL.md ([#101](#101)) ([651c577](651c577)) * bump aiosqlite from 0.21.0 to 0.22.1 ([#191](#191)) ([3274a86](3274a86)) * bump pyyaml from 6.0.2 to 6.0.3 in the minor-and-patch group ([#96](#96)) ([0338d0c](0338d0c)) * bump ruff from 0.15.4 to 0.15.5 ([a49ee46](a49ee46)) * fix M0 audit items ([#66](#66)) ([c7724b5](c7724b5)) * **main:** release ai-company 0.1.1 ([#282](#282)) ([2f4703d](2f4703d)) * pin setup-uv action to full SHA ([#281](#281)) ([4448002](4448002)) * post-audit cleanup — PEP 758, loggers, bug fixes, refactoring, tests, hookify rules ([#148](#148)) ([c57a6a9](c57a6a9)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Signed-off-by: Aurelio <19254254+Aureliolo@users.noreply.github.com>
Summary
RetryConfig/RateLimiterConfigfromconfig.schemato newcore/resilience_config.py, and moveBudgetExhaustedError/DailyLimitExceededError/QuotaExhaustedErrorfromengine/errors.pyto newbudget/errors.py. Delete theproviders/resilience/config.pyre-export shim. Move routing module imports ofconfig.schemabehindTYPE_CHECKINGguards (placed at end of import sections per convention).ModelResponse→ModelResponseStream)"include-component-in-tag": falseto release-please config so tags arevX.Y.Z(notai-company-vX.Y.Z), matching the Docker CIv*triggerbudget/andcore/tests/unit/budget/test_errors.pyfor budget error hierarchy assertions;QuotaExhaustedErroradded to engine budget handler parametrizeTest plan
ruff check— all checks passedruff format— no changes neededmypy src/ tests/— no issues (848 files)pytest tests/ -n auto --cov=ai_company --cov-fail-under=80— 6653 passed, 8 skipped, 94.80% coverageReview 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.