{"openapi":"3.1.0","info":{"title":"Haiven Agent Briefing","description":"Scope-aware briefing agent that generates daily summaries, end-of-day reports,\ntask artifact reviews, and knowledge context assembly. Pulls data from work-hub\nand haiven-knowledge, generates briefings via LiteLLM (GLM-4.7-Flash), and\ndelivers output through notification-hub.\n\n## GLM Response Handling\nGLM-4.7-Flash has thinking mode ON by default. The service extracts the answer\nfrom `reasoning_content` when `content` is null. For task extraction, thinking is\ndisabled explicitly via `enable_thinking: false` to improve JSON reliability.\n\n## Scheduled Triggers\n- `haiven-briefing-morning.timer` — Mon–Fri 07:30, scope=daily, notify=true\n- `haiven-briefing-eod.timer` — Mon–Fri 17:30, scope=end_of_day, notify=true\n\n## Base URLs\n- Production (Traefik): https://briefing.haiven.site\n- Internal (Docker): http://agent-briefing:8000\n- Direct host access: http://localhost:8035\n\n## Authentication\nNo authentication required. Service is LAN-only on the `web` + `backend` Docker networks.\n","version":"0.1.0","contact":{"name":"Haiven Infrastructure","url":"https://home.haiven.site"}},"servers":[{"url":"https://briefing.haiven.site","description":"Production (Traefik HTTPS, haiven.site)"},{"url":"http://agent-briefing:8000","description":"Internal (Docker network)"},{"url":"http://localhost:8035","description":"Direct host access"}],"tags":[{"name":"Briefing","description":"Briefing generation endpoints"},{"name":"Observability","description":"Health check and Prometheus metrics"}],"paths":{"/briefing":{"post":{"summary":"Generate a scope-specific briefing","description":"Dispatches to one of four scope handlers based on the `scope` field:\n\n- **daily**: Fetches open tasks (limit 20), completed tasks (limit 10), and recent KB\n  entries (limit 10), fills a Langfuse template, calls GLM, optionally notifies and\n  extracts tasks.\n- **end_of_day**: Fetches task counts only, no KB query. Lighter than daily.\n- **review**: Requires `task_id` and `voice_instructions`. Reads the current task\n  artifact, queries KB with the voice instructions, calls GLM, patches the task.\n- **context_assembly**: Requires `task_id`. Runs 4 parallel KB queries keyed to the\n  task topic, deduplicates, writes assembled context JSON to the task, sets status\n  to `context_ready`.\n","operationId":"briefing","tags":["Briefing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefingRequest"},"examples":{"daily":{"summary":"Standard daily morning briefing","value":{"scope":"daily","template":"briefing-daily","notify":false,"extract_tasks":false}},"daily_with_notification":{"summary":"Daily briefing with notification delivery","value":{"scope":"daily","template":"briefing-daily","notify":true,"extract_tasks":false}},"daily_with_task_extraction":{"summary":"Daily briefing that auto-creates work-hub tasks from output","value":{"scope":"daily","template":"briefing-daily","notify":false,"extract_tasks":true}},"end_of_day":{"summary":"End-of-day summary","value":{"scope":"end_of_day","template":"briefing-eod","notify":true}},"review":{"summary":"Revise a task artifact with voice instructions","value":{"scope":"review","task_id":"550e8400-e29b-41d4-a716-446655440000","voice_instructions":"Make it shorter and add a concrete next action","notify":false}},"context_assembly":{"summary":"Assemble KB context for a task","value":{"scope":"context_assembly","task_id":"550e8400-e29b-41d4-a716-446655440000","notify":false}}}}}},"responses":{"200":{"description":"Briefing generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefingResponse"},"examples":{"daily_response":{"summary":"Daily briefing response","value":{"scope":"daily","briefing":"Good morning. You have 12 open tasks. Top priorities for today: ...","data_sources":{"open_tasks":12,"completed_tasks":3,"kb_results":8,"template":"briefing-daily","model":"glm-4-7-flash"},"notified":false,"created_task_ids":[]}},"end_of_day_response":{"summary":"EOD briefing response","value":{"scope":"end_of_day","briefing":"Today you completed 4 tasks. 8 remain open tomorrow.","data_sources":{"completed_tasks":4,"open_tasks":8,"template":"briefing-eod","model":"glm-4-7-flash"},"notified":true,"created_task_ids":[]}},"context_assembly_response":{"summary":"Context assembly response","value":{"scope":"context_assembly","briefing":"Assembled 22 unique knowledge points for task 'RAGAS evaluation' across 4 query facets.","data_sources":{"task_id":"550e8400-e29b-41d4-a716-446655440000","topic":"RAGAS evaluation","total_sources":22,"context_patched":true,"status_patched":true},"notified":false,"created_task_ids":[]}}}}}},"400":{"description":"Bad request — unknown scope or missing required fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"unknown_scope":{"value":{"detail":"Unknown scope 'foo'. Valid: daily, end_of_day, review, context_assembly."}},"missing_task_id":{"value":{"detail":"review scope requires 'task_id'"}}}}}},"404":{"description":"Task not found in work-hub","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"detail":"Task '550e8400-e29b-41d4-a716-446655440000' not found"}}}},"500":{"description":"Internal error — upstream service unreachable or LLM failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/health":{"get":{"summary":"Liveness probe","description":"Returns 200 if the process is running. Does not check upstream dependencies.","operationId":"health","tags":["Observability"],"responses":{"200":{"description":"Service is up","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"example":{"status":"ok","service":"haiven-agent-briefing"}}}}}}},"/metrics":{"get":{"summary":"Prometheus metrics","description":"Prometheus-format metrics endpoint. Auto-discovered via Docker labels:\n`prometheus.scrape=true`, `prometheus.port=8000`, `prometheus.path=/metrics`.\n","operationId":"metrics","tags":["Observability"],"responses":{"200":{"description":"Prometheus text format metrics","content":{"text/plain":{"schema":{"type":"string"}}}}}}}},"components":{"schemas":{"BriefingRequest":{"type":"object","properties":{"scope":{"type":"string","enum":["daily","end_of_day","review","context_assembly"],"default":"daily","description":"Which briefing to generate:\n- `daily` — morning briefing (tasks + KB context)\n- `end_of_day` — task count summary\n- `review` — revise task artifact with voice instructions (requires task_id + voice_instructions)\n- `context_assembly` — gather KB context for a task (requires task_id)\n"},"template":{"type":"string","default":"briefing-daily","description":"Langfuse prompt name to use as the generation template. Falls back to\nbundled hardcoded template if Langfuse is unavailable or credentials are absent.\n"},"notify":{"type":"boolean","default":false,"description":"When true, pushes the briefing to notification-hub after generation.\nNotification failures are logged but never block the briefing response.\n"},"task_id":{"type":"string","nullable":true,"default":null,"description":"work-hub task UUID. Required for `review` and `context_assembly` scopes.","example":"550e8400-e29b-41d4-a716-446655440000"},"voice_instructions":{"type":"string","nullable":true,"default":null,"description":"For `review` scope: revision instructions passed to the LLM. Also used as\nKB search query to find relevant context.\nFor `daily` scope: injected as a system message before the prompt.\n","example":"Make it more concise and add a clear next action"},"extract_tasks":{"type":"boolean","default":false,"description":"For `daily` scope only. When true, makes a second LLM call to extract\nactionable tasks from the briefing text and POSTs them to work-hub.\nDeduplicates against existing open tasks before creating.\n"}}},"BriefingResponse":{"type":"object","required":["scope","briefing","data_sources","notified","created_task_ids"],"properties":{"scope":{"type":"string","description":"The scope that was executed.","example":"daily"},"briefing":{"type":"string","description":"The generated briefing text. For `context_assembly`, this is a\nhuman-readable summary of how many sources were assembled.\n"},"data_sources":{"type":"object","description":"Scope-dependent metadata about what data was fetched.\n- daily: open_tasks (int), completed_tasks (int), kb_results (int), template (str), model (str)\n- end_of_day: completed_tasks (int), open_tasks (int), template (str), model (str)\n- review: task_id (str), kb_results (int), patched (bool)\n- context_assembly: task_id (str), topic (str), total_sources (int), context_patched (bool), status_patched (bool)\n","additionalProperties":true},"notified":{"type":"boolean","description":"Whether notification-hub returned HTTP 200.","example":false},"created_task_ids":{"type":"array","items":{"type":"string"},"description":"work-hub task IDs created by the `extract_tasks` feature. Empty array\nwhen `extract_tasks` is false or when no actionable tasks were found.\n","example":[]}}},"HealthResponse":{"type":"object","required":["status","service"],"properties":{"status":{"type":"string","enum":["ok"],"example":"ok"},"service":{"type":"string","example":"haiven-agent-briefing"}}},"ErrorResponse":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string","description":"Human-readable error description."}}}}}}