Repository navigation
feat(agent): structured Monitor->Diagnostic handoff (typed, not prose) - #87
Merged
Merged
Conversation
Closes #80. MonitorToDiagnosticHandoff.anomaly_context was a raw prose string, the #1 context-passing anti-pattern: the Diagnostic sub-agent had to re-parse a narrative to recover what breached, by how much, and where. The downstream DiagnosisReport already uses structured claim-source records, so the first handoff now matches. - New DetectedAnomaly model (anomaly_type, summary, detected_at, plus optional metric / observed_value / baseline / threshold / breach_direction / affected_component / source_signal_ids) carries typed context. - MonitorToDiagnosticHandoff.anomaly: DetectedAnomaly replaces the string; the size-guard now truncates the only unbounded field (summary) so an over-long narrative can never overflow the diagnostic prompt. - _detect_anomalies returns DetectedAnomaly | None: it injects the schema into the detection prompt and parses the conclusion via _parse_detection, which falls back to wrapping prose in summary so detection always yields a typed object (no crash, no extra LLM call, detection stays one response). - _spawn_diagnostic_agent takes the typed anomaly and injects its JSON; runbook resolution runs off anomaly.summary (keeps _resolve_runbooks' string contract, so steering/runbook tests are untouched). Single-agent extractor uses the typed fields. Tests: DetectedAnomaly required/optional/round-trip, handoff typed + summary truncation + round-trip, _parse_detection JSON + prose fallback, and _detect_anomalies returns typed anomaly / None. Full suite 229 passed; ruff + mypy clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #80.
Problem
MonitorToDiagnosticHandoff.anomaly_contextwas a raw prose string, the #1 context-passing anti-pattern from the multi-agent pattern. The Diagnostic sub-agent had to re-parse a narrative to recover what breached, by how much, and where. The downstreamDiagnosisReportalready uses structured claim-source records, so the first handoff should match.Fix
DetectedAnomalymodel:anomaly_type,summary,detected_at, plus optionalmetric/observed_value/baseline/threshold/breach_direction/affected_component/source_signal_ids.MonitorToDiagnosticHandoff.anomaly: DetectedAnomalyreplaces the string. The size-guard now truncates the only unbounded field (summary) so an over-long narrative can't overflow the diagnostic prompt._detect_anomaliesreturnsDetectedAnomaly | None: injects the schema into the detection prompt and parses the conclusion via_parse_detection, which falls back to wrapping prose insummaryso detection always yields a typed object. No extra LLM call; detection stays one response, so orchestration call-counts are unchanged._spawn_diagnostic_agenttakes the typed anomaly and injects its JSON. Runbook resolution runs offanomaly.summary, keeping_resolve_runbooks' string contract so the steering/runbook tests are untouched. Single-agent extractor uses the typed fields.Tests
DetectedAnomalyrequired/optional/round-trip; handoff typed + summary truncation + round-trip;_parse_detectionJSON success + prose fallback;_detect_anomaliesreturns typed anomaly /Nonewhen healthy.Full suite 229 passed; ruff + mypy clean.
https://claude.ai/code/session_01R5VygSzbGTggW7mHd3PVwE