Skip to content

Fix: Generic type parameters not preserved when subclassing AtomicAgent - #187

Merged
Eigenwise merged 1 commit into
mainfrom
fix/generic-type-preservation-subclassing
Nov 20, 2025
Merged

Eigenwise merged 1 commit into
mainfrom
fix/generic-type-preservation-subclassing

Conversation

@Eigenwise

Copy link
Copy Markdown
Owner

Problem

When you subclass AtomicAgent with a custom constructor, the generic type parameters get lost. The input_schema and output_schema properties end up returning BasicChatInputSchema and BasicChatOutputSchema instead of the types you actually specified.

Example that was broken:

class MyAgent(AtomicAgent[MyInputSchema, MyOutputSchema]):
    def __init__(self, extra_param):
        self.extra_param = extra_param
        super().__init__(config)

agent = MyAgent("test")
# These would incorrectly return Basic* schemas instead of My* schemas
print(agent.input_schema)
print(agent.output_schema)

The issue is that __orig_class__ only gets set for direct instantiation, not when subclassing.

Solution

Added __init_subclass__ to capture the generic parameters at class creation time. This is the same approach already used by BasePrompt, BaseTool, and BaseResource, so it's consistent with the codebase.

The schema properties now check in this order:

  1. Class attributes (set by __init_subclass__) - handles subclassing
  2. Instance __orig_class__ - handles direct instantiation
  3. Default schemas - handles untyped usage

Testing

  • Added test_subclass_with_custom_constructor() to verify the fix
  • All existing tests still pass (35/35)
  • Code formatted and linted

Notes

This is backward compatible - doesn't break any existing usage patterns. Direct instantiation still works the same way it did before.

When subclassing AtomicAgent with a custom constructor, the generic type
parameters weren't being preserved. This caused input_schema and output_schema
to fall back to BasicChatInputSchema/BasicChatOutputSchema instead of using
the actual types specified.

Added __init_subclass__ to capture the generic parameters at class creation
time, following the same pattern used in BasePrompt, BaseTool, and BaseResource.

The schema properties now use a three-level fallback:
1. Class attributes (from __init_subclass__)
2. Instance __orig_class__ (for direct instantiation)
3. Default schemas (for untyped usage)

Added test case to verify subclassing with custom constructors works correctly.
@Eigenwise

Copy link
Copy Markdown
Owner Author

Fixes #185

@Eigenwise
Eigenwise merged commit ae1236c into main Nov 20, 2025
4 checks passed
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.

1 participant