A (very vibe coded) email management agent for Fastmail

rose-llm: fix triage_decision_schema rejected by Anthropic's real API

triage_decision_schema() had a top-level oneOf (no_op | notify variants), which Anthropic's Messages API rejects on a tool's input_schema root: '400: input_schema does not support oneOf, allOf, or anyOf at the top level'. Every unit test used RecordingLlmTransport (a canned-response fake), so nothing ever round-tripped the schema through the real endpoint — this hit every single email that reached LLM triage in production (i.e. constantly, since a fresh install starts with zero plugins) and was never caught locally. Flattened to a single object with kind as an enum and summary optional; the 'notify requires summary' constraint moves from the schema into rose_core:: TriageDecision's own required field (serde already enforces it on deserialize). Tightened the system prompt to state the per-kind field requirement explicitly now that the schema can't express it structurally. Added a regression test asserting no top-level schema function emits a root oneOf/allOf/anyOf, so this class of bug fails cargo test next time instead of only surfacing against the live API in production. Verified against the real Anthropic API (not just RecordingLlmTransport): both the no_op and notify branches now return 200 and deserialize cleanly.


Author
Date Commit Parent 0566725d Change ID
+39 -22
2 changed files
+39 -22
2 changed files