|
1 | 1 | """ |
2 | 2 | Models package for MCP as a Judge. |
3 | 3 |
|
4 | | -This package contains all data models used throughout the application, |
5 | | -including task metadata, enhanced responses, and workflow guidance models. |
| 4 | +This package re-exports models for convenient `from mcp_as_a_judge.models import ...` |
| 5 | +usage. The canonical `WorkflowGuidance` lives in `workflow/workflow_guidance.py` and |
| 6 | +is imported here for a single source of truth. |
6 | 7 | """ |
7 | 8 |
|
8 | 9 | # Task metadata models |
|
49 | 50 | "WorkflowGuidanceUserVars", |
50 | 51 | ] |
51 | 52 |
|
52 | | -# Import additional models from the original models.py file |
53 | | -# Import them here to avoid circular imports |
54 | | -try: |
55 | | - import importlib.util |
56 | | - import os |
| 53 | +# Import additional models from the file `src/mcp_as_a_judge/models.py`. |
| 54 | +# We use a lightweight file-based import to avoid the Python package/module name |
| 55 | +# collision and keep downstream imports stable. |
| 56 | +import importlib.util |
| 57 | +import os |
| 58 | +from typing import Any |
57 | 59 |
|
58 | | - # Get the path to models.py |
59 | | - current_dir = os.path.dirname(__file__) |
60 | | - models_py_path = os.path.join(os.path.dirname(current_dir), "models.py") |
61 | | - |
62 | | - if os.path.exists(models_py_path): |
63 | | - spec = importlib.util.spec_from_file_location("models_py", models_py_path) |
64 | | - if spec is not None: |
65 | | - models_py = importlib.util.module_from_spec(spec) |
66 | | - if spec.loader is not None: |
67 | | - spec.loader.exec_module(models_py) # type: ignore[union-attr] |
68 | | - |
69 | | - # Import the models we need |
70 | | - ElicitationFallbackUserVars = models_py.ElicitationFallbackUserVars |
71 | | - JudgeCodeChangeUserVars = models_py.JudgeCodeChangeUserVars |
72 | | - JudgeCodingPlanUserVars = models_py.JudgeCodingPlanUserVars |
73 | | - ResearchValidationResponse = models_py.ResearchValidationResponse |
74 | | - ResearchValidationUserVars = models_py.ResearchValidationUserVars |
75 | | - WorkflowGuidanceUserVars = models_py.WorkflowGuidanceUserVars |
76 | | - DynamicSchemaUserVars = models_py.DynamicSchemaUserVars |
77 | | - ValidationErrorUserVars = models_py.ValidationErrorUserVars |
78 | | - SystemVars = models_py.SystemVars |
79 | | - |
80 | | - # Import research-related models |
81 | | - ResearchComplexityFactors = models_py.ResearchComplexityFactors |
82 | | - ResearchRequirementsAnalysis = models_py.ResearchRequirementsAnalysis |
83 | | - ResearchRequirementsAnalysisUserVars = ( |
84 | | - models_py.ResearchRequirementsAnalysisUserVars |
85 | | - ) |
86 | | - URLValidationResult = models_py.URLValidationResult |
87 | | - |
88 | | -except Exception: |
89 | | - # Fallback if models.py doesn't exist or has issues |
90 | | - # Create minimal fallback classes to prevent import errors |
91 | | - from pydantic import BaseModel, Field |
92 | | - |
93 | | - class ElicitationFallbackUserVars(BaseModel): |
94 | | - pass |
95 | | - |
96 | | - class JudgeCodeChangeUserVars(BaseModel): |
97 | | - pass |
| 60 | +from pydantic import BaseModel, Field |
98 | 61 |
|
99 | | - class JudgeCodingPlanUserVars(BaseModel): |
100 | | - pass |
101 | 62 |
|
102 | | - class ResearchValidationResponse(BaseModel): |
103 | | - pass |
104 | | - |
105 | | - class ResearchValidationUserVars(BaseModel): |
106 | | - pass |
107 | | - |
108 | | - class WorkflowGuidanceUserVars(BaseModel): |
109 | | - pass |
110 | | - |
111 | | - class DynamicSchemaUserVars(BaseModel): |
112 | | - pass |
113 | | - |
114 | | - class SystemVars(BaseModel): |
115 | | - pass |
116 | | - |
117 | | - class ResearchComplexityFactors(BaseModel): |
118 | | - domain_specialization: str = Field(default="general") |
119 | | - technology_maturity: str = Field(default="established") |
120 | | - integration_scope: str = Field(default="moderate") |
121 | | - existing_solutions: str = Field(default="limited") |
122 | | - risk_level: str = Field(default="medium") |
| 63 | +def _load_models_py() -> Any | None: |
| 64 | + current_dir = os.path.dirname(__file__) |
| 65 | + models_py_path = os.path.join(os.path.dirname(current_dir), "models.py") |
| 66 | + if not os.path.exists(models_py_path): |
| 67 | + return None |
| 68 | + spec = importlib.util.spec_from_file_location("models_py", models_py_path) |
| 69 | + if spec is None or spec.loader is None: # type: ignore[truthy-function] |
| 70 | + return None |
| 71 | + module = importlib.util.module_from_spec(spec) |
| 72 | + spec.loader.exec_module(module) # type: ignore[attr-defined] |
| 73 | + return module |
123 | 74 |
|
124 | | - class ResearchRequirementsAnalysis(BaseModel): |
125 | | - expected_url_count: int = Field(default=3) |
126 | | - minimum_url_count: int = Field(default=2) |
127 | | - reasoning: str = Field(default="Fallback analysis") |
128 | | - complexity_factors: ResearchComplexityFactors = Field( |
129 | | - default_factory=ResearchComplexityFactors |
130 | | - ) |
131 | | - quality_requirements: list[str] = Field(default_factory=list) |
132 | 75 |
|
133 | | - class ResearchRequirementsAnalysisSystemVars(BaseModel): |
134 | | - pass |
| 76 | +models_py = _load_models_py() |
135 | 77 |
|
136 | | - class ResearchRequirementsAnalysisUserVars(BaseModel): |
137 | | - pass |
| 78 | +# Names to re-export from models.py |
| 79 | +_NAMES = [ |
| 80 | + "ElicitationFallbackUserVars", |
| 81 | + "JudgeCodeChangeUserVars", |
| 82 | + "JudgeCodingPlanUserVars", |
| 83 | + "ResearchValidationResponse", |
| 84 | + "ResearchValidationUserVars", |
| 85 | + "WorkflowGuidanceUserVars", |
| 86 | + "DynamicSchemaUserVars", |
| 87 | + "ValidationErrorUserVars", |
| 88 | + "SystemVars", |
| 89 | + "ResearchComplexityFactors", |
| 90 | + "ResearchRequirementsAnalysis", |
| 91 | + "ResearchRequirementsAnalysisUserVars", |
| 92 | + "URLValidationResult", |
| 93 | +] |
138 | 94 |
|
139 | | - class URLValidationResult(BaseModel): |
140 | | - adequate: bool = Field(default=False) |
141 | | - provided_count: int = Field(default=0) |
142 | | - expected_count: int = Field(default=3) |
143 | | - minimum_count: int = Field(default=2) |
144 | | - feedback: str = Field(default="Fallback validation") |
145 | | - meets_quality_standards: bool = Field(default=False) |
| 95 | +for _name in _NAMES: |
| 96 | + if models_py is not None and hasattr(models_py, _name): |
| 97 | + globals()[_name] = getattr(models_py, _name) |
| 98 | + else: |
| 99 | + # Minimal, safe placeholders only used if models.py cannot be loaded |
| 100 | + if _name in { |
| 101 | + "ResearchComplexityFactors", |
| 102 | + "ResearchRequirementsAnalysis", |
| 103 | + "URLValidationResult", |
| 104 | + }: |
| 105 | + # Provide slightly richer defaults for research-related types |
| 106 | + if _name == "ResearchComplexityFactors": |
| 107 | + class ResearchComplexityFactors(BaseModel): # type: ignore[no-redef] |
| 108 | + domain_specialization: str = Field(default="general") |
| 109 | + technology_maturity: str = Field(default="established") |
| 110 | + integration_scope: str = Field(default="moderate") |
| 111 | + existing_solutions: str = Field(default="limited") |
| 112 | + risk_level: str = Field(default="medium") |
| 113 | + |
| 114 | + globals()[_name] = ResearchComplexityFactors |
| 115 | + elif _name == "ResearchRequirementsAnalysis": |
| 116 | + class ResearchRequirementsAnalysis(BaseModel): # type: ignore[no-redef] |
| 117 | + expected_url_count: int = Field(default=3) |
| 118 | + minimum_url_count: int = Field(default=1) |
| 119 | + reasoning: str = Field(default="Fallback analysis") |
| 120 | + complexity_factors: Any = Field(default=None) |
| 121 | + quality_requirements: list[str] = Field(default_factory=list) |
| 122 | + |
| 123 | + globals()[_name] = ResearchRequirementsAnalysis |
| 124 | + else: # URLValidationResult |
| 125 | + class URLValidationResult(BaseModel): # type: ignore[no-redef] |
| 126 | + adequate: bool = Field(default=False) |
| 127 | + provided_count: int = Field(default=0) |
| 128 | + expected_count: int = Field(default=0) |
| 129 | + minimum_count: int = Field(default=0) |
| 130 | + feedback: str = Field(default="Fallback validation") |
| 131 | + meets_quality_standards: bool = Field(default=False) |
| 132 | + |
| 133 | + globals()[_name] = URLValidationResult |
| 134 | + else: |
| 135 | + # Generic placeholder |
| 136 | + globals()[_name] = type(_name, (BaseModel,), {}) |
0 commit comments