hedit 0.7.11.dev7__tar.gz → 0.7.11.dev10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hedit-0.7.11.dev7/hedit.egg-info → hedit-0.7.11.dev10}/PKG-INFO +1 -1
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10/hedit.egg-info}/PKG-INFO +1 -1
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/pyproject.toml +1 -1
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/validation_agent.py +21 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/api/main.py +24 -1
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/version.py +1 -1
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_validation_agent.py +18 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/LICENSE +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/PKG_README.md +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/README.md +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/hedit.egg-info/SOURCES.txt +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/hedit.egg-info/dependency_links.txt +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/hedit.egg-info/entry_points.txt +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/hedit.egg-info/requires.txt +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/hedit.egg-info/top_level.txt +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/setup.cfg +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/annotation_agent.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/assessment_agent.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/evaluation_agent.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/feedback_summarizer.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/feedback_triage_agent.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/state.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/vision_agent.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/agents/workflow.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/api/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/api/models.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/api/security.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/api_executor.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/client.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/commands/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/commands/lsp.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/config.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/executor.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/local_executor.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/main.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/cli/output.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/data/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/data/hed-docs/02_Terminology.md +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/data/hed-docs/HedAnnotationSemantics.md +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/data/hed-docs/manifest.json +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/lsp/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/lsp/client.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/lsp/daemon.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/lsp/protocol.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/scripts/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/scripts/process_feedback.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/telemetry/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/telemetry/collector.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/telemetry/schema.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/telemetry/storage.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/anthropic_llm.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/error_remediation.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/github_client.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/hed_comprehensive_guide.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/hed_docs_loader.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/image_processing.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/json_schema_loader.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/llm_usage.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/utils/schema_loader.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/validation/__init__.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/validation/hed_lsp.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/src/validation/hed_validator.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_annotation_agent.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_anthropic_llm.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_api_endpoints.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_cli_client.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_cli_config.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_cli_integration.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_cli_main.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_cli_usage_report.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_comprehensive_guide.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_error_remediation.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_feedback_integration.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_feedback_triage.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_fetch_hed_docs.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_github_client.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_hed_docs_loader.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_integration_anthropic.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_json_schema_loader.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_llm_usage.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_no_extend_propagation.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_schema_loader.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_security.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_state.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_telemetry.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_validation.py +0 -0
- {hedit-0.7.11.dev7 → hedit-0.7.11.dev10}/tests/test_version.py +0 -0
|
@@ -244,6 +244,27 @@ class ValidationAgent:
|
|
|
244
244
|
|
|
245
245
|
return result_dict
|
|
246
246
|
|
|
247
|
+
def probe(self, schema_version: str = "8.4.0") -> bool:
|
|
248
|
+
"""Confirm the active validator backend can actually run a validation.
|
|
249
|
+
|
|
250
|
+
Validates a known-valid HED string ("Red") through the same backend
|
|
251
|
+
real requests use. A broken backend (Node missing, hed-javascript not
|
|
252
|
+
built, schema unavailable) surfaces either as an exception or as a
|
|
253
|
+
VALIDATOR_INIT_ERROR result, both of which return False here.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
schema_version: Schema version to validate against
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
True only when the backend produced a valid result for "Red"
|
|
260
|
+
"""
|
|
261
|
+
try:
|
|
262
|
+
result = self._run_validation("Red", schema_version)
|
|
263
|
+
except Exception:
|
|
264
|
+
logger.exception("Validator probe failed")
|
|
265
|
+
return False
|
|
266
|
+
return result.is_valid
|
|
267
|
+
|
|
247
268
|
def _get_or_create_validator(
|
|
248
269
|
self, schema_version: str
|
|
249
270
|
) -> HedJavaScriptValidator | HedPythonValidator:
|
|
@@ -671,6 +671,29 @@ async def audit_logging_middleware(request: Request, call_next):
|
|
|
671
671
|
raise
|
|
672
672
|
|
|
673
673
|
|
|
674
|
+
# A schema loader existing does not prove the JavaScript validator can run
|
|
675
|
+
# (Node missing, hed-javascript not built), so /health runs a real validation
|
|
676
|
+
# through the workflow's backend. The probe spawns a Node subprocess on the
|
|
677
|
+
# JS path, so its result is cached and refreshed at most once per TTL.
|
|
678
|
+
_VALIDATOR_PROBE_TTL_SECONDS = 300.0
|
|
679
|
+
_validator_probe: dict[str, float | bool] = {"functional": False, "checked_at": float("-inf")}
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
async def _validator_functional() -> bool:
|
|
683
|
+
"""Return whether the active validator backend passes a functional probe."""
|
|
684
|
+
now = time.monotonic()
|
|
685
|
+
if now - _validator_probe["checked_at"] < _VALIDATOR_PROBE_TTL_SECONDS:
|
|
686
|
+
return bool(_validator_probe["functional"])
|
|
687
|
+
|
|
688
|
+
functional = False
|
|
689
|
+
if workflow is not None:
|
|
690
|
+
schema_version = os.getenv("HED_SCHEMA_VERSION", "8.4.0")
|
|
691
|
+
functional = await asyncio.to_thread(workflow.validation_agent.probe, schema_version)
|
|
692
|
+
_validator_probe["functional"] = functional
|
|
693
|
+
_validator_probe["checked_at"] = now
|
|
694
|
+
return functional
|
|
695
|
+
|
|
696
|
+
|
|
674
697
|
@app.get("/health", response_model=HealthResponse)
|
|
675
698
|
async def health_check() -> HealthResponse:
|
|
676
699
|
"""Health check endpoint.
|
|
@@ -679,7 +702,7 @@ async def health_check() -> HealthResponse:
|
|
|
679
702
|
Health status and service availability
|
|
680
703
|
"""
|
|
681
704
|
llm_available = workflow is not None and _llm_credentials_ok
|
|
682
|
-
validator_available = schema_loader is not None
|
|
705
|
+
validator_available = schema_loader is not None and await _validator_functional()
|
|
683
706
|
|
|
684
707
|
status = "healthy" if (llm_available and validator_available) else "degraded"
|
|
685
708
|
|
|
@@ -428,3 +428,21 @@ class TestGetOrCreateValidatorSchemaVersionWarning:
|
|
|
428
428
|
validation_agent._get_or_create_validator("8.4.0")
|
|
429
429
|
|
|
430
430
|
assert not any("reusing cached" in record.message for record in caplog.records)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
class TestValidationAgentProbe:
|
|
434
|
+
"""Tests for the health-check probe (#27)."""
|
|
435
|
+
|
|
436
|
+
@pytest.fixture
|
|
437
|
+
def validation_agent(self):
|
|
438
|
+
"""Create a validation agent using the Python validator."""
|
|
439
|
+
loader = HedSchemaLoader()
|
|
440
|
+
return ValidationAgent(loader, use_javascript=False)
|
|
441
|
+
|
|
442
|
+
def test_probe_returns_true_on_working_backend(self, validation_agent):
|
|
443
|
+
"""A functional backend validates "Red" cleanly."""
|
|
444
|
+
assert validation_agent.probe("8.4.0") is True
|
|
445
|
+
|
|
446
|
+
def test_probe_returns_false_on_broken_backend(self, validation_agent):
|
|
447
|
+
"""An unloadable schema version fails the probe instead of raising."""
|
|
448
|
+
assert validation_agent.probe("not-a-real-version") is False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|