|
12 | 12 | from src.models import GraphState |
13 | 13 | from src.models.visualization_intent import VisualizationIntent, VisualizationPlotSpec |
14 | 14 | from src.services.viz_param_extractor import ( |
15 | | - canonicalize_requested_plot_vars, |
16 | 15 | convert_prompt_seconds_to_solver_time, |
17 | 16 | extract_viz_params_from_prompt, |
| 17 | + resolve_viz_field_mapping, |
18 | 18 | ) |
19 | 19 |
|
20 | 20 |
|
@@ -84,6 +84,7 @@ def build_visualization_intent( |
84 | 84 | requested_plot_vars: list[str] | None = None, |
85 | 85 | visualization_config: dict[str, Any] | None = None, |
86 | 86 | prior_intent: dict[str, Any] | None = None, |
| 87 | + mapping_diagnostics_out: dict[str, Any] | None = None, |
87 | 88 | ) -> VisualizationIntent: |
88 | 89 | """ |
89 | 90 | Build a canonical visualization_intent payload. |
@@ -112,12 +113,21 @@ def build_visualization_intent( |
112 | 113 | + list(prior_fields) |
113 | 114 | + list(prior_vars) |
114 | 115 | ) |
115 | | - if solver_name: |
116 | | - merged_requested = canonicalize_requested_plot_vars( |
| 116 | + mapping_diagnostics: dict[str, Any] = { |
| 117 | + "resolved_fields": list(merged_requested), |
| 118 | + "candidate_fields_by_token": {}, |
| 119 | + "unresolved_tokens": [], |
| 120 | + "ambiguous_tokens": [], |
| 121 | + "mapping_source": "semantic_only" if merged_requested else "none", |
| 122 | + "mapping_confidence": 1.0, |
| 123 | + } |
| 124 | + if solver_name and merged_requested: |
| 125 | + mapping_diagnostics = resolve_viz_field_mapping( |
117 | 126 | merged_requested, |
118 | 127 | code_name=solver_name, |
119 | 128 | repo_root=repo_root, |
120 | 129 | ) |
| 130 | + merged_requested = list(mapping_diagnostics.get("resolved_fields", [])) |
121 | 131 |
|
122 | 132 | merged_config: dict[str, Any] = {} |
123 | 133 | if isinstance(extracted_config, dict): |
@@ -184,6 +194,10 @@ def build_visualization_intent( |
184 | 194 | if source not in {"prompt", "clarification", "default"}: |
185 | 195 | source = "default" |
186 | 196 |
|
| 197 | + if isinstance(mapping_diagnostics_out, dict): |
| 198 | + mapping_diagnostics_out.clear() |
| 199 | + mapping_diagnostics_out.update(mapping_diagnostics) |
| 200 | + |
187 | 201 | return VisualizationIntent( |
188 | 202 | requested_fields=merged_requested, |
189 | 203 | cadence_prompt_seconds=cadence_prompt_seconds, |
@@ -248,18 +262,24 @@ def visualization_intent_node(state: GraphState) -> dict[str, Any]: |
248 | 262 | prompt = str(state.get("prompt") or state.get("user_requirement") or "") |
249 | 263 | prior_intent = state.get("visualization_intent") if isinstance(state.get("visualization_intent"), dict) else {} |
250 | 264 |
|
| 265 | + mapping: dict[str, Any] = {} |
251 | 266 | model = build_visualization_intent( |
252 | 267 | prompt=prompt, |
253 | 268 | solver_name=solver_name, |
254 | 269 | repo_root=repo_root, |
255 | 270 | requested_plot_vars=[], |
256 | 271 | visualization_config={}, |
257 | 272 | prior_intent=prior_intent, |
| 273 | + mapping_diagnostics_out=mapping, |
258 | 274 | ) |
259 | 275 | intent = model.model_dump() |
260 | 276 |
|
261 | 277 | return { |
262 | 278 | "visualization_intent": intent, |
263 | 279 | "requested_plot_vars": list(model.requested_fields), |
264 | 280 | "visualization_config": dict(intent.get("visualization_config", {})), |
| 281 | + "visualization_mapping_candidates": dict(mapping.get("candidate_fields_by_token", {})), |
| 282 | + "visualization_mapping_unresolved": list(mapping.get("unresolved_tokens", [])), |
| 283 | + "visualization_mapping_source": mapping.get("mapping_source"), |
| 284 | + "visualization_mapping_confidence": mapping.get("mapping_confidence"), |
265 | 285 | } |
0 commit comments