Core changes: - Add @defgroup/@ingroup to 1791 C2+ contracts (555 files) for HCA 128× pre-training DSA grouping - Add §0.1 Pre-Training Frequency matrix to semantics-core - Add §VIII Attention Architecture rules (ATTN_1-4) with MLA/CSA/HCA/DSA mechanics - Add @defgroup/@ingroup to canonical syntax (§II) and all contract examples Agent prompts (5 files): - Add ZERO-STATE RATIONALE with MLA/CSA/HCA/DSA compression mechanics - Add pre-training note: @RATIONALE/@REJECTED are in-context learned tags - svelte-coder: add missing #region contract, fix Svelte rule violations - python-coder/fullstack-coder: honor function contracts from speckit plan - qa-tester: add attention compliance audit (P3 ATTN_1-4 checks) Skills (6 files): - Translate all axiom_config descriptions to English - Fix doc_dirs to index .opencode/ and .specify/ - Deduplicate 5× complexity_rules → single global_tags catalog - Reduce semantics-svelte 591→485 lines (remove duplicate code blocks) - Fix semantics-testing: 'Short IDs' → 'Short hierarchical IDs' - Fix all examples: flat IDs → hierarchical Domain.Name format - Fix Svelte examples: replace raw Tailwind + <button> with semantic tokens + /ui Speckit workflow (commands + templates): - speckit.plan: add Function-Level Contracts for C3+ with @PRE/@POST/@TEST_EDGE - speckit.plan: add Attention Compliance Gate (ATTN_1-4 before contract generation) - speckit.tasks: add function contract inlining format (constraints in task description) - speckit.specify: load semantics-core for spec density rules - spec-template: add #region contract, @SEMANTICS grouping, hierarchical IDs - ux-reference-template: add #region wrapper - plan-template: add attention gate, @defgroup/@ingroup guidance - tasks-template: add attention audit + rebuild + orphan check tasks - constitution.md: translate to English, add Principle VIII (attention-optimized contracts) Reference modules rewritten (hierarchical IDs + full contracts): - Auth.Jwt: 6 child contracts with @RATIONALE/@REJECTED/@TEST_EDGE - Api.Auth: 5 endpoints with @TEST_EDGE + molecular CoT markers - Migration.Model: @defgroup Migration with 18 @ACTION + 6 @INVARIANT Scripts: - add_defgroup_ingroup.py: zero-risk additive @ingroup migration (1791 insertions) - migrate_hierarchical.py: flat→hierarchical ID dry-run analysis (792 contracts) - merge_prompts.py: merge all prompts/skills/commands into one review file Config: - axiom_config.yaml: 749→395 lines (-47%), English, doc_dirs include prompts - Fix test_datasets.py import collision (rename → test_datasets_routes.py) - Fix test_preview.py: SupersetClient→get_superset_client, AsyncMock, logger f-string
144 lines
7.0 KiB
Python
144 lines
7.0 KiB
Python
# #region RunSourceFetcher [C:3] [TYPE Module] [SEMANTICS translate, source, fetch, superset, preview]
|
|
# @defgroup Translate Module group.
|
|
# @BRIEF Fetch source rows for translation runs from Superset datasource or preview session.
|
|
# Extracted from RunExecutionService to comply with INV_7 (< 400 lines/module).
|
|
# @LAYER Domain
|
|
# @RELATION DEPENDS_ON -> [TranslationJob], [TranslationPreviewSession]
|
|
# @RELATION DEPENDS_ON -> [SupersetClient]
|
|
# @RELATION DEPENDS_ON -> [ConfigManager]
|
|
# @PRE job_id exists in DB.
|
|
# @POST Returns list of dicts with source data (text, row_index, approved_translation, source_data).
|
|
# @SIDE_EFFECT Makes HTTP call to Superset chart data API when datasource is configured.
|
|
# @RATIONALE Extracted from RunExecutionService (620 lines) — _fetch_source_rows alone was ~100 lines.
|
|
# @REJECTED Inline fetch logic in execute_run — made execute_run exceed 150 lines.
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from ...core.config_manager import ConfigManager
|
|
from ...core.logger import belief_scope, logger
|
|
from ...models.translate import TranslationJob, TranslationPreviewRecord, TranslationPreviewSession
|
|
|
|
MAX_ROWS_PER_RUN = 10000
|
|
|
|
|
|
# #region fetch_source_rows [C:3] [TYPE Function] [SEMANTICS translate, source, fetch]
|
|
# @ingroup Translate
|
|
# @BRIEF Fetch source rows from Superset datasource or preview session fallback.
|
|
async def fetch_source_rows(db: Session, config_manager: ConfigManager, job_id: str, run_id: str) -> list[dict[str, Any]]:
|
|
"""Fetch source rows from Superset datasource or preview session fallback."""
|
|
with belief_scope("RunSourceFetcher.fetch_source_rows"):
|
|
job = db.query(TranslationJob).filter(TranslationJob.id == job_id).first()
|
|
|
|
if job and job.source_datasource_id:
|
|
try:
|
|
logger.reason("Fetching full dataset from Superset datasource", {
|
|
"run_id": run_id, "datasource_id": job.source_datasource_id,
|
|
"environment_id": job.environment_id,
|
|
})
|
|
environments = config_manager.get_environments()
|
|
target_env_id = job.environment_id or job.source_dialect or ""
|
|
env_config = next((e for e in environments if e.id == target_env_id), None)
|
|
if not env_config and environments:
|
|
env_config = environments[0]
|
|
|
|
if env_config:
|
|
from ...core.utils.client_registry import get_superset_client
|
|
client = await get_superset_client(env_config)
|
|
dataset_detail = await client.get_dataset_detail(int(job.source_datasource_id))
|
|
query_context = client.build_dataset_preview_query_context(
|
|
dataset_id=int(job.source_datasource_id), dataset_record=dataset_detail,
|
|
template_params={}, effective_filters=[],
|
|
)
|
|
queries = query_context.get("queries", [])
|
|
if queries:
|
|
queries[0]["row_limit"] = MAX_ROWS_PER_RUN
|
|
queries[0].pop("result_type", None)
|
|
queries[0]["metrics"] = []
|
|
query_context["result_type"] = "samples"
|
|
form_data = query_context.get("form_data", {})
|
|
form_data.pop("query_mode", None)
|
|
|
|
response = await client.network.request(
|
|
method="POST", endpoint="/api/v1/chart/data",
|
|
data=json.dumps(query_context), headers={"Content-Type": "application/json"},
|
|
)
|
|
rows = _extract_chart_data_rows(response)
|
|
if rows:
|
|
logger.reason(f"Fetched {len(rows)} rows from Superset datasource", {"run_id": run_id})
|
|
source_rows = []
|
|
for idx, row in enumerate(rows):
|
|
sd = dict(row) if row else None
|
|
st = str(row.get(job.translation_column, "")) if job.translation_column else json.dumps(row)
|
|
source_rows.append({
|
|
"row_index": str(idx), "source_text": st,
|
|
"approved_translation": None, "source_object_name": f"Row {idx}",
|
|
"source_data": sd,
|
|
})
|
|
return source_rows
|
|
logger.explore("Superset datasource returned no rows", {"run_id": run_id, "datasource_id": job.source_datasource_id})
|
|
else:
|
|
logger.explore("No environment config found", {"env_id": target_env_id})
|
|
except Exception as e:
|
|
logger.explore("Failed to fetch full dataset from Superset, falling back to preview",
|
|
{"run_id": run_id, "error": str(e)})
|
|
|
|
session = (
|
|
db.query(TranslationPreviewSession)
|
|
.filter(TranslationPreviewSession.job_id == job_id, TranslationPreviewSession.status == "APPLIED")
|
|
.order_by(TranslationPreviewSession.created_at.desc())
|
|
.first()
|
|
)
|
|
if not session:
|
|
logger.explore("No accepted preview session found", {"job_id": job_id})
|
|
return []
|
|
|
|
records = (
|
|
db.query(TranslationPreviewRecord)
|
|
.filter(TranslationPreviewRecord.session_id == session.id,
|
|
TranslationPreviewRecord.status.in_(["APPROVED", "PENDING"]))
|
|
.all()
|
|
)
|
|
source_rows = []
|
|
for rec in records:
|
|
sd = None
|
|
if hasattr(rec, "source_data") and rec.source_data:
|
|
sd = dict(rec.source_data)
|
|
source_rows.append({
|
|
"row_index": rec.source_object_id or "0",
|
|
"source_text": rec.source_sql or "",
|
|
"approved_translation": rec.target_sql if rec.status == "APPROVED" else None,
|
|
"source_object_name": rec.source_object_name or "",
|
|
"source_data": sd,
|
|
})
|
|
logger.reason(f"Fetched {len(source_rows)} source rows from preview fallback",
|
|
{"run_id": run_id, "session_id": session.id})
|
|
return source_rows
|
|
# #endregion fetch_source_rows
|
|
|
|
|
|
# #region _extract_chart_data_rows [C:1] [TYPE Function]
|
|
def _extract_chart_data_rows(response: dict[str, Any]) -> list[dict[str, Any]]:
|
|
"""Extract data rows from Superset chart data API response."""
|
|
result = response.get("result")
|
|
if isinstance(result, list):
|
|
for item in result:
|
|
if isinstance(item, dict):
|
|
data = item.get("data")
|
|
if isinstance(data, list) and data:
|
|
return data
|
|
if isinstance(result, dict):
|
|
data = result.get("data")
|
|
if isinstance(data, list) and data:
|
|
return data
|
|
data = response.get("data")
|
|
if isinstance(data, list) and data:
|
|
return data
|
|
if isinstance(result, list):
|
|
return result
|
|
return []
|
|
# #endregion _extract_chart_data_rows
|
|
# #endregion RunSourceFetcher
|