Skip to content

fix(core): reconcile duplicate AgentAdapter protocols - #430

Merged
frankbria merged 1 commit into
mainfrom
fix/reconcile-agent-adapter-protocols
Mar 9, 2026
Merged

fix(core): reconcile duplicate AgentAdapter protocols#430
frankbria merged 1 commit into
mainfrom
fix/reconcile-agent-adapter-protocols

Conversation

@frankbria

@frankbria frankbria commented Mar 9, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes a conflict introduced when #409 was merged — PR #408 had already introduced AgentAdapter at codeframe/core/adapters/agent_adapter.py (used by 14 modules), but #409 created a duplicate at codeframe/core/agent_adapter.py with an incompatible interface.

This PR reconciles them by:

  • Merging new types (AgentContext, AdapterTokenUsage, AgentResultStatus) into the canonical codeframe/core/adapters/agent_adapter.py
  • Extending existing types: AgentResult gains token_usage/duration_ms, AgentEvent gains message/timestamp
  • Removing duplicate codeframe/core/agent_adapter.py
  • Updating tests to import from canonical location
  • Exporting new types from codeframe.core.adapters.__init__

Why this happened

Issue #409 was written before PR #408 was merged. Both defined AgentAdapter but with different interfaces (execute() vs run()). The canonical run() interface is already wired into runtime, registry, and all adapter implementations.

Test Plan

  • All 1598 core tests passing
  • Both test files (tests/core/test_agent_adapter.py + tests/core/adapters/test_agent_adapter.py) pass
  • Ruff linting clean
  • No import changes needed in existing adapter code (backward compatible)

Closes #409

Summary by CodeRabbit

  • Refactor
    • Reorganized agent adapter API structure across modules
    • Agent results now include token usage and duration tracking
    • Agent events now include explicit message and timestamp information
    • New agent context and status types added for execution tracking

…location

PR #408 already introduced AgentAdapter at codeframe/core/adapters/agent_adapter.py
with run()-based interface used by 14 modules. PR #409 created a duplicate at
codeframe/core/agent_adapter.py with execute()-based interface used by nothing.

This reconciles them:
- Merge new types (AgentContext, AdapterTokenUsage, AgentResultStatus) into canonical
- Add token_usage/duration_ms to AgentResult, message/timestamp to AgentEvent
- Remove duplicate codeframe/core/agent_adapter.py
- Update tests to import from canonical location
- Export new types from codeframe.core.adapters.__init__
@coderabbitai

coderabbitai Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR relocates agent adapter type definitions from codeframe/core/agent_adapter.py to codeframe/core/adapters/agent_adapter.py, introduces new dataclass fields (token_usage, duration_ms) to AgentResult, and extends AgentEvent with message and timestamp fields. Tests and exports are updated accordingly.

Changes

Cohort / File(s) Summary
Agent Adapter Type Migration
codeframe/core/adapters/agent_adapter.py, codeframe/core/agent_adapter.py
Relocated AgentResultStatus enum, AdapterTokenUsage, AgentContext, AgentResult, AgentEvent, and AgentAdapter protocol to adapters module. Extended AgentResult with token_usage (optional) and duration_ms fields; added message and timestamp fields to AgentEvent with UTC timezone defaults.
Package Exports
codeframe/core/adapters/__init__.py
Exported AdapterTokenUsage, AgentContext, and AgentResultStatus from the adapters module to public API via __all__ list.
Test Updates
tests/core/test_agent_adapter.py
Updated import paths to reflect new module location (codeframe.core.adapters.agent_adapter); adjusted test assertions to validate updated field signatures and default values.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #428: Moves agent adapter types (AgentResultStatus, AdapterTokenUsage, AgentContext, AgentEvent, AgentAdapter protocol) to codeframe/core/adapters/agent_adapter.py with updated signatures.
  • PR #429: Directly related refactoring that modifies the same core agent adapter types and reorganizes their module structure.

Poem

🐰 Through codebase paths the rabbit hops,
Adapters move to new code shops,
Token counts and timestamps now bloom,
Reorganized in adapters' room! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: consolidating duplicate AgentAdapter protocol definitions into a canonical location.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ 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/reconcile-agent-adapter-protocols

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

@claude

claude Bot commented Mar 9, 2026

Copy link
Copy Markdown

Review: fix(core): reconcile duplicate AgentAdapter protocols

This is a clean and necessary fix for the conflict from the merge ordering of #408 and #409. The approach is correct — preserve the canonical run()-based interface and fold in the new types. Overall looks good with a few things worth noting.

What works well

  • Removing codeframe/core/agent_adapter.py eliminates the ambiguity cleanly with no dangling imports (confirmed zero references remain to the old path)
  • The merged fields (token_usage, duration_ms on AgentResult; message, timestamp on AgentEvent) are additive and backward compatible
  • AgentContext is a genuinely useful addition for the Phase 4 adapter architecture
  • Protocol compliance tests (including streaming via on_event) properly live in tests/core/adapters/test_agent_adapter.py

Issue: AgentResultStatus enum is stranded (moderate)

AgentResultStatus is added and exported, but AgentResult.status is still typed as Literal['completed', 'failed', 'blocked']. Two problems:

  1. The enum has 4 values (COMPLETED, FAILED, BLOCKED, TIMEOUT) but the Literal only covers 3 — AgentResultStatus.TIMEOUT cannot be assigned to AgentResult.status without a type error.
  2. Any caller who imports AgentResultStatus expecting it to work with AgentResult.status will hit a mismatch.

Options to fix:

  • Use the enum as the type: status: AgentResultStatus and add timeout handling downstream
  • Add 'timeout' to the Literal and keep enum values aligned
  • Defer exporting AgentResultStatus until it is actually used in production code

Issue: Test file split is undocumented

tests/core/test_agent_adapter.py now tests AgentContext, AdapterTokenUsage, AgentResultStatus, while tests/core/adapters/test_agent_adapter.py covers AgentResult, AgentEvent, and protocol compliance. This is a reasonable split, but a brief comment at the top of the former explaining the division would prevent future confusion.

Minor observations

  • Callable imported in agent_adapter.py is correctly used in the run() signature
  • The old AgentEvent.metadata field is not missed; the canonical data dict covers the same purpose
  • AgentContext has no production callers yet — expected for Phase 4 groundwork

Summary

The duplicate removal and type merges are correct. The main item to address is the AgentResultStatus/Literal inconsistency — either align them or defer the enum export until it is actually wired in. Right now it is exported but effectively unusable with AgentResult.status without a type error.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/core/test_agent_adapter.py (1)

20-175: Cover the new codeframe.core.adapters re-exports too.

These tests only import from codeframe.core.adapters.agent_adapter, so they never exercise the package surface added in codeframe/core/adapters/__init__.py. A small from codeframe.core.adapters import AdapterTokenUsage, AgentContext, AgentResultStatus smoke test would catch broken re-exports.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/core/test_agent_adapter.py` around lines 20 - 175, Add a tiny smoke
test that imports the re-exported symbols from the package-level module to
exercise codeframe.core.adapters; specifically add a test (e.g., in the existing
TestAgentAdapter suite) that does "from codeframe.core.adapters import
AdapterTokenUsage, AgentContext, AgentResultStatus" and then asserts simple
properties (e.g., instantiate AdapterTokenUsage and AgentContext and check
AgentResultStatus.COMPLETED.value) so the package-level re-exports in
__init__.py are validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@codeframe/core/adapters/agent_adapter.py`:
- Around line 17-23: AgentResult currently can't represent the new timeout
terminal state: update the AgentResult.status field to include the "timeout"
value by typing it to the AgentResultStatus enum (replace the current union of
string literals `"completed" | "failed" | "blocked"` with `AgentResultStatus`)
so the added AgentResultStatus.TIMEOUT is accepted and the enum remains
canonical; adjust any related type annotations or validations in the AgentResult
class/constructor (references: AgentResultStatus, AgentResult.status) to use the
enum rather than a restricted string union.

---

Nitpick comments:
In `@tests/core/test_agent_adapter.py`:
- Around line 20-175: Add a tiny smoke test that imports the re-exported symbols
from the package-level module to exercise codeframe.core.adapters; specifically
add a test (e.g., in the existing TestAgentAdapter suite) that does "from
codeframe.core.adapters import AdapterTokenUsage, AgentContext,
AgentResultStatus" and then asserts simple properties (e.g., instantiate
AdapterTokenUsage and AgentContext and check AgentResultStatus.COMPLETED.value)
so the package-level re-exports in __init__.py are validated.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 101d12a5-32eb-4e14-b8d4-b12691ba772e

📥 Commits

Reviewing files that changed from the base of the PR and between 623cfbd and 6e0b7a8.

📒 Files selected for processing (4)
  • codeframe/core/adapters/__init__.py
  • codeframe/core/adapters/agent_adapter.py
  • codeframe/core/agent_adapter.py
  • tests/core/test_agent_adapter.py
💤 Files with no reviewable changes (1)
  • codeframe/core/agent_adapter.py

Comment on lines +17 to +23
class AgentResultStatus(str, Enum):
"""Terminal status from an agent execution."""

COMPLETED = "completed"
FAILED = "failed"
BLOCKED = "blocked"
TIMEOUT = "timeout"

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.

⚠️ Potential issue | 🟠 Major

AgentResult still cannot represent the new timeout terminal state.

Line 23 adds AgentResultStatus.TIMEOUT, but Line 63 still constrains AgentResult.status to "completed", "failed", and "blocked". A timed-out adapter result now has to either violate the declared contract or be downgraded to another state. Please widen the field to include "timeout"; if the enum is meant to be canonical, typing the field from AgentResultStatus would keep these definitions from drifting again.

🔧 Minimal fix
 `@dataclass`
 class AgentResult:
     """Result from an agent adapter execution."""
 
-    status: Literal["completed", "failed", "blocked"]
+    status: Literal["completed", "failed", "blocked", "timeout"]

Also applies to: 59-69

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@codeframe/core/adapters/agent_adapter.py` around lines 17 - 23, AgentResult
currently can't represent the new timeout terminal state: update the
AgentResult.status field to include the "timeout" value by typing it to the
AgentResultStatus enum (replace the current union of string literals
`"completed" | "failed" | "blocked"` with `AgentResultStatus`) so the added
AgentResultStatus.TIMEOUT is accepted and the enum remains canonical; adjust any
related type annotations or validations in the AgentResult class/constructor
(references: AgentResultStatus, AgentResult.status) to use the enum rather than
a restricted string union.

@frankbria
frankbria merged commit c37498f into main Mar 9, 2026
13 checks passed
@frankbria
frankbria deleted the fix/reconcile-agent-adapter-protocols branch March 24, 2026 23:29
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.

[Phase 4] Agent Adapter Protocol Definition

1 participant