Files
cleveragents-core/robot/helper_domain_base_model.py
T
freemo 650b1038b6
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Failing after 19s
CI / typecheck (pull_request) Failing after 56s
CI / security (pull_request) Failing after 56s
CI / coverage (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
CI / unit_tests (pull_request) Failing after 2m4s
CI / docker (pull_request) Has been skipped
CI / build (pull_request) Successful in 16s
CI / helm (pull_request) Successful in 23s
CI / quality (pull_request) Successful in 3m42s
CI / e2e_tests (pull_request) Failing after 15m14s
CI / integration_tests (pull_request) Failing after 22m3s
CI / status-check (pull_request) Failing after 1s
refactor(domain): extract shared model_config into a base Pydantic model
Introduce DomainBaseModel in src/cleveragents/domain/models/base.py that
defines the single shared model_config (str_strip_whitespace, validate_assignment,
arbitrary_types_allowed=False, populate_by_name, use_enum_values) previously
duplicated verbatim across five domain model files.

Update 14 classes across five files to inherit from DomainBaseModel instead
of pydantic.BaseModel directly, removing all inline model_config duplication:
- aimodelscredentials/ai_models_credentials.py (ModelProviderOption)
- aimodelserrors/ai_models_errors.py (ModelError, FallbackResult)
- aimodelsproviders/ai_models_providers.py (ModelProviderExtraAuthVars,
  ModelProviderConfigSchema)
- auth/auth.py (AuthHeader, TrialPlansExceededError, TrialMessagesExceededError,
  BillingError, ApiError, ClientAccount, ClientAuth)
- planconfig/plan_config.py (PlanConfig, ConfigSetting)

Pure structural refactor — no behavioral changes. Models with different
configurations (acms, aimodels_custom, etc.) are left untouched.

Add BDD feature (22 scenarios) and Robot integration tests (8 test cases)
verifying inheritance, config correctness, and no-duplication invariants.

ISSUES CLOSED: #1941
2026-04-03 02:01:45 +00:00

240 lines
7.2 KiB
Python

"""Helper script for DomainBaseModel Robot integration tests.
Verifies that the structural refactor (extracting shared model_config into
DomainBaseModel) has not changed the observable behaviour of any affected
domain model class.
"""
from __future__ import annotations
import sys
from pydantic import BaseModel
from cleveragents.domain.models.base import DomainBaseModel
def _test_domain_base_model_importable() -> None:
"""DomainBaseModel is importable and is a pydantic BaseModel subclass."""
assert issubclass(DomainBaseModel, BaseModel)
print("domain-base-model-importable-ok")
def _test_domain_base_model_config() -> None:
"""DomainBaseModel carries the expected shared model_config."""
cfg = DomainBaseModel.model_config
assert cfg.get("str_strip_whitespace") is True
assert cfg.get("validate_assignment") is True
assert cfg.get("arbitrary_types_allowed") is False
assert cfg.get("populate_by_name") is True
assert cfg.get("use_enum_values") is True
print("domain-base-model-config-ok")
def _test_model_provider_option() -> None:
"""ModelProviderOption behaviour is unchanged after refactor."""
from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
ModelProviderOption,
)
from cleveragents.domain.models.aimodelsproviders.ai_models_providers import (
ModelProviderConfigSchema,
)
from cleveragents.domain.models.core.enums import ModelProvider, ModelPublisher
assert issubclass(ModelProviderOption, DomainBaseModel)
config = ModelProviderConfigSchema(
provider=ModelProvider.OPENAI, baseUrl="https://api.openai.com/v1"
)
publishers = {"primary": {ModelPublisher.OPENAI: True}}
model = ModelProviderOption(publishers=publishers, config=config, priority=1)
assert model.priority == 1
assert model.config is not None
assert model.config.base_url == "https://api.openai.com/v1"
# Verify str_strip_whitespace is active via inherited config
assert model.model_config.get("str_strip_whitespace") is True
print("model-provider-option-ok")
def _test_model_error() -> None:
"""ModelError behaviour is unchanged after refactor."""
from cleveragents.domain.models.aimodelserrors.ai_models_errors import ModelError
from cleveragents.domain.models.core.enums import ModelErrKind
assert issubclass(ModelError, DomainBaseModel)
err = ModelError(kind=ModelErrKind.OVERLOADED, retriable=True, retryafterseconds=30)
assert err.retriable is True
assert err.retryafterseconds == 30
print("model-error-ok")
def _test_fallback_result() -> None:
"""FallbackResult behaviour is unchanged after refactor."""
from cleveragents.domain.models.aimodelserrors.ai_models_errors import (
FallbackResult,
)
from cleveragents.domain.models.core.enums import FallbackType
assert issubclass(FallbackResult, DomainBaseModel)
result = FallbackResult(
fallbacktype=FallbackType.ERROR,
isfallback=True,
modelroleconfig=None,
basemodelconfig=None,
)
assert result.isfallback is True
print("fallback-result-ok")
def _test_auth_models() -> None:
"""Auth model behaviour is unchanged after refactor."""
from cleveragents.domain.models.auth.auth import (
ApiError,
ApiErrorType,
AuthHeader,
BillingError,
ClientAccount,
ClientAuth,
TrialMessagesExceededError,
TrialPlansExceededError,
)
for cls in (
AuthHeader,
TrialPlansExceededError,
TrialMessagesExceededError,
BillingError,
ApiError,
ClientAccount,
ClientAuth,
):
assert issubclass(cls, DomainBaseModel), f"{cls.__name__} not DomainBaseModel"
header = AuthHeader(token="tok", orgId="org-1", hash="abc")
assert header.org_id == "org-1"
trial_plans = TrialPlansExceededError(maxPlans=5)
assert trial_plans.max_plans == 5
trial_msgs = TrialMessagesExceededError(maxMessages=100)
assert trial_msgs.max_messages == 100
billing = BillingError(hasBillingPermission=False, isTrial=True)
assert billing.is_trial is True
api_err = ApiError(type_=ApiErrorType.AUTH, status=401, msg="Unauthorized")
assert api_err.status == 401
account = ClientAccount(
isCloud=True,
host="app.cleverthis.com",
email="user@example.com",
userName="testuser",
userId="uid-1",
token="tok-1",
isLocalMode=False,
isTrial=False,
)
assert account.is_cloud is True
auth = ClientAuth(
orgId="org-1",
orgName="Test Org",
orgIsTrial=False,
integratedModelsMode=True,
)
assert auth.org_name == "Test Org"
print("auth-models-ok")
def _test_plan_config_models() -> None:
"""PlanConfig and ConfigSetting behaviour is unchanged after refactor."""
from cleveragents.domain.models.planconfig.plan_config import (
AutoModeType,
ConfigSetting,
PlanConfig,
)
assert issubclass(PlanConfig, DomainBaseModel)
assert issubclass(ConfigSetting, DomainBaseModel)
plan = PlanConfig(
autoMode=AutoModeType.AUTO,
editor="vim",
editorCommand="vim",
editorOpenManually=False,
autoContinue=True,
autoBuild=False,
autoUpdateContext=True,
autoContext=True,
smartContext=True,
autoApply=False,
autoCommit=False,
skipCommit=False,
canExec=True,
autoExec=False,
autoDebug=False,
autoDebugTries=3,
autoRevertOnRewind=False,
skipChangesMenu=False,
)
assert plan.editor == "vim"
assert plan.auto_mode == AutoModeType.AUTO
setting = ConfigSetting(
name="autoMode",
desc="Auto mode setting",
hascustomchoice=False,
sortkey="a",
)
assert setting.name == "autoMode"
print("plan-config-models-ok")
def _test_whitespace_stripping() -> None:
"""str_strip_whitespace is active on all refactored models."""
from cleveragents.domain.models.aimodelsproviders.ai_models_providers import (
ModelProviderConfigSchema,
)
from cleveragents.domain.models.core.enums import ModelProvider
schema = ModelProviderConfigSchema(
provider=ModelProvider.OPENAI,
baseUrl=" https://api.openai.com/v1 ",
)
assert schema.base_url == "https://api.openai.com/v1", (
f"Expected stripped URL, got: {schema.base_url!r}"
)
print("whitespace-stripping-ok")
_COMMANDS: dict[str, object] = {
"importable": _test_domain_base_model_importable,
"config": _test_domain_base_model_config,
"model-provider-option": _test_model_provider_option,
"model-error": _test_model_error,
"fallback-result": _test_fallback_result,
"auth-models": _test_auth_models,
"plan-config-models": _test_plan_config_models,
"whitespace-stripping": _test_whitespace_stripping,
}
def main() -> None:
if len(sys.argv) < 2:
raise SystemExit("Expected command argument")
command = sys.argv[1]
fn = _COMMANDS.get(command)
if fn is None:
raise SystemExit(f"Unknown helper command: {command!r}")
fn() # type: ignore[operator]
if __name__ == "__main__":
main()