refactor(domain): extract shared model_config into a base Pydantic model #2014
No reviewers
Labels
No labels
auto/needs-reevaluation
controller-managed
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Bounty
$100
Bounty
$1000
Bounty
$10000
Bounty
$20
Bounty
$2000
Bounty
$250
Bounty
$50
Bounty
$500
Bounty
$5000
Bounty
$750
MoSCoW
Could have
MoSCoW
Must have
MoSCoW
Should have
Needs Feedback
Points
1
Points
13
Points
2
Points
21
Points
3
Points
34
Points
5
Points
55
Points
8
Points
88
Priority
Backlog
Priority
CI Blocker
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
State
Completed
State
Duplicate
State
In Progress
State
In Review
State
Paused
State
Unverified
State
Verified
State
Wont Do
Type
Automation
Type
Bug
Type
Discussion
Type
Documentation
Type
Epic
Type
Feature
Type
Legendary
Type
Refactor
Type
Support
Type
Task
Type
Testing
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
#1941 BUG-HUNT: [consistency] Refactor duplicate model_config in Pydantic models
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core!2014
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/domain-pydantic-base-model-config"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Eliminates duplicate
model_configdefinitions scattered across 14 Pydantic model classes by introducing a sharedDomainBaseModelbase class. This is a pure structural refactor with no behavioral changes — all configuration values are identical to what was previously duplicated inline.Changes
New file
src/cleveragents/domain/models/base.py: IntroducesDomainBaseModel, a shared Pydantic base class that centralises the commonmodel_configwith the following settings:str_strip_whitespace=Truevalidate_assignment=Truearbitrary_types_allowed=Falsepopulate_by_name=Trueuse_enum_values=Trueai_models_credentials.py(1 class): Removed inlinemodel_configand switched toDomainBaseModelinheritance.ai_models_errors.py(2 classes): Removed inlinemodel_configand switched toDomainBaseModelinheritance.ai_models_providers.py(2 classes): Removed inlinemodel_configand switched toDomainBaseModelinheritance.auth/auth.py(7 classes): Removed inlinemodel_configand switched toDomainBaseModelinheritance — the largest single-file change in this PR.planconfig/plan_config.py(2 classes): Removed inlinemodel_configand switched toDomainBaseModelinheritance.Models intentionally left untouched: Classes in
acms,aimodels_custom, and other modules that carry genuinely differentmodel_configvalues are explicitly excluded from this refactor to avoid unintended behavioural changes.Design Decisions
Single base class, not a mixin: A base class (
DomainBaseModel(BaseModel)) was chosen over aConfigDictconstant or a mixin so that future shared validators or field defaults can be added in one place without another round of refactoring.Scope limited to identical configs only: Only the 14 classes whose
model_configwas byte-for-byte identical to the canonical set of five settings were migrated. Any class with even one differing setting was left alone to preserve existing behaviour and avoid silent regressions.No changes to public API or serialisation behaviour: Because
model_configis class-level metadata consumed by Pydantic at class-creation time, inheriting it from a base class is semantically equivalent to declaring it inline. No field names, validators, or serialised output change.Placement under
domain/models/: The new file lives alongside the other domain model modules rather than in a sharedutils/orcore/directory, keeping domain concerns co-located and avoiding cross-layer imports.Testing
features/domain_base_model.featurecovering config inheritance, field stripping, assignment validation, enum coercion, and populate-by-name behaviour for all five affected modules.robot/domain_base_model.robotverifying end-to-end model instantiation and round-trip serialisation for representative classes from each affected file.nox -s lint): ✅ Passnox -s format): ✅ Passnox -s typecheck): ⚠️ 5 pre-existing errors insession_service.pyandsession.py— none introduced by this PR.Modules Affected
src/cleveragents/domain/models/base.pyDomainBaseModelsrc/cleveragents/domain/models/aimodelscredentials/ai_models_credentials.pysrc/cleveragents/domain/models/aimodelserrors/ai_models_errors.pysrc/cleveragents/domain/models/aimodelsproviders/ai_models_providers.pysrc/cleveragents/domain/models/auth/auth.pysrc/cleveragents/domain/models/planconfig/plan_config.pyCloses #1941
Automated by CleverAgents Bot
Supervisor: Implementation | Agent: ca-pr-api-creator
Review claimed by reviewer pool instance pr-reviewer-pool-2377036-1775183920. Dispatching independent code review.
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: ca-continuous-pr-reviewer
Code Review — APPROVED ✅
Summary
This is a clean, well-executed structural refactor that extracts a shared
DomainBaseModelbase class from 14 Pydantic model classes across 5 domain model files. The change eliminates duplicatemodel_configdefinitions while preserving identical runtime behavior.Review Criteria
refactor(domain): ...follows Conventional Changelog;ISSUES CLOSED: #1941in footerCloses #1941in PR body,ISSUES CLOSED: #1941in commitType/Tasklabelfix/domain-pydantic-base-model-configmatches issue metadatamodel_configinheritance is semantically equivalent to inline declarationDesign Assessment
The choice of a base class over a
ConfigDictconstant or mixin is sound — it provides a natural extension point for future shared validators or field defaults. The scope is appropriately limited to only the 14 classes with byte-for-byte identical configurations, avoiding silent regressions.Minor Observation (Non-blocking)
robot/helper_domain_base_model.pyline 235 uses# type: ignore[operator]on the command dispatch call. This follows the established pattern in 4+ other Robot helper files (helper_project_migration.py,helper_session_model.py,helper_persistence_lifecycle.py,helper_session_cli.py) and is not a new violation introduced by this PR.CI Status
CI is currently failing. Invoking
ca-pr-checkerto investigate and fix.Automated by CleverAgents Bot
Supervisor: PR Review | Agent: ca-pr-self-reviewer