{"openapi":"3.1.0","info":{"title":"Viki","description":"**Viki** is Victoi's model-agnostic AI orchestration platform.\n\nThis API exposes the platform's current capabilities — the **Driver catalogue** (every model Viki can reach, with live wire-format metadata), the **organ blueprint**, the **MCP tool list**, and Viki's identity. Every introspection endpoint is available both here (REST) and over JSON-RPC on `POST /mcp`.\n\nFoundation surfaces:\n- `/v1/drivers` — list of registered model drivers + filters\n- `/v1/drivers/{id}` — one driver's full record + live probe + RAG markdown\n- `/v1/capabilities` — capability taxonomy + which drivers offer each\n- `/v1/organs` — the 12-organ architecture blueprint\n- `/v1/identity` — Viki's persona, values, brand truths\n- `/v1/architecture` — full architecture doc as structured markdown\n- `/v1/mcp/tools` — MCP tool catalogue, over REST\n- `POST /mcp` — JSON-RPC 2.0 MCP endpoint (initialize, tools/list, tools/call)","version":"0.1.0"},"paths":{"/actuator/health":{"get":{"tags":["actuator"],"summary":"Health","description":"Liveness + readiness. ECS health check hits this every 30s.","operationId":"health_actuator_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Actuator Health Get"}}}}}}},"/actuator/info":{"get":{"tags":["actuator"],"summary":"Info","operationId":"info_actuator_info_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Info Actuator Info Get"}}}}}}},"/actuator/readiness":{"get":{"tags":["actuator"],"summary":"Readiness probe — stricter than /health","description":"Returns ``READY`` only when every provider referenced in the active ModelPolicy has its credential bootstrapped. Useful as an ALB target-group health check after deploys: a misconfigured credential rotation flips this DOWN before any user turn fans out to a credentialless driver.","operationId":"readiness_actuator_readiness_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Readiness Actuator Readiness Get"}}}}}}},"/v1/drivers":{"get":{"tags":["drivers"],"summary":"List all registered drivers","description":"Returns every Driver in the catalogue. Optional filters narrow the result to one capability (e.g. `text.generate`, `embed`, `live.bidi`) or one vendor (e.g. `google`). Each Driver record carries the wire-format metadata the Provider/Adapter layer needs to actually call the model — endpoint template, transport, auth method, pricing, rate limits, health spec.","operationId":"list_drivers_v1_drivers_get","parameters":[{"name":"capability","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to drivers offering this capability tag.","examples":["text.generate","embed","live.bidi","audio.out"],"title":"Capability"},"description":"Filter to drivers offering this capability tag."},{"name":"vendor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to one vendor.","title":"Vendor"},"description":"Filter to one vendor."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriverListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/drivers/{driver_id}":{"get":{"tags":["drivers"],"summary":"Describe one driver — record + probe capture + RAG markdown","description":"Returns the full Driver record, the live wire-format probe capture under `vikii/data/probes/<nick>.json` (if any), and the generated RAG markdown card under `vikii/src/vikii/content/drivers/<nick>.md`. The same payload `vikii.describe_driver` returns over MCP.","operationId":"describe_driver_v1_drivers__driver_id__get","parameters":[{"name":"driver_id","in":"path","required":true,"schema":{"type":"string","title":"Driver Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriverDetailResponse"}}}},"404":{"description":"Unknown driver id."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/models":{"get":{"tags":["drivers"],"summary":"List user-selectable chat models (id + name + description)","description":"Returns the curated set of text models a user may pick for a chat turn, each with a human-readable name + description and a `default` flag marking the model the policy would pick if the user doesn't choose. Send the chosen id back as the `model` field on `POST /v1/chat`. Unlike `/v1/drivers?capability=text.generate`, this hides specialist drivers (live-audio, image, translation-only) so the picker only shows real conversational models.","operationId":"list_chat_models_v1_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Chat Models V1 Models Get"}}}}}}},"/v1/capabilities":{"get":{"tags":["catalogue"],"summary":"List capability tags with driver counts","description":"Returns the Capability taxonomy (text.generate, tool.use, stream, vision.read, audio.in, audio.out, live.bidi, embed, image.generate, image.edit, video.generate, music.generate, search.grounded). Unlike `vikii.capabilities` over MCP, this endpoint resolves the `drivers` list against the live registry — so a caller sees which actual drivers offer each capability right now.","operationId":"list_capabilities_v1_capabilities_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapabilityListResponse"}}}}}}},"/v1/tools/catalog":{"get":{"tags":["catalogue"],"summary":"Tier-filtered tool digest for the mobile mount-time preload","description":"Returns the catalog the mobile app should cache locally so the augmentation envelope can carry tool hints on every chat/voice turn without paying the round-trip cost. Names + 1-line summaries only; full schemas live behind `tools.lookup_spec`. JWT-required. Anon-tier callers get the KB-only allowlist; authenticated callers get the read-eligible registry minus admin/system tools. Sets an `ETag` derived from the registry contents + caller tier so subsequent mounts can `If-None-Match` for a 304.","operationId":"tools_catalog_v1_tools_catalog_get","responses":{"200":{"description":"Tier-filtered catalog.","content":{"application/json":{"schema":{}}}},"304":{"description":"Catalog unchanged; client cache is fresh."},"401":{"description":"Missing or invalid bearer token."}}}},"/v1/organs":{"get":{"tags":["catalogue"],"summary":"List the 12-organ blueprint and per-organ status","description":"Returns the architecture HTML §2.1 organ blueprint — Identity, NervousSystem, Ears, Eyes, Mind, Hands, Mouth, Voice, Imagination, Tongue, Hippocampus, Skin. Each entry carries its responsibility, required capabilities, and a v0 implementation status flag.","operationId":"list_organs_v1_organs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganListResponse"}}}}}}},"/v1/identity":{"get":{"tags":["catalogue"],"summary":"Viki's persona, values, brand truths","description":"Returns the platform's identity — name, persona, values, brand truths. Owned by the system, not by any vendor model. Same payload `vikii.identity` returns over MCP.","operationId":"get_identity_v1_identity_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityResponse"}}}}}}},"/v1/architecture":{"get":{"tags":["catalogue"],"summary":"The architecture-v0 doc as structured markdown","description":"Returns Viki's architecture blueprint, split into sections by `##` heading. Pass `?include_raw=true` to also get the concatenated markdown.","operationId":"get_architecture_v1_architecture_get","parameters":[{"name":"include_raw","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Raw"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArchitectureResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/mcp/tools":{"get":{"tags":["mcp"],"summary":"List the MCP tools Viki exposes","description":"Returns the same catalogue an MCP client would see by calling JSON-RPC `tools/list` against `POST /mcp`. Surfacing it here lets anything that speaks OpenAPI discover Viki's MCP without first having to issue a JSON-RPC call.","operationId":"list_mcp_tools_v1_mcp_tools_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpToolListResponse"}}}}}}},"/v1/tools":{"get":{"tags":["hands"],"summary":"List the platform tools Viki can use","description":"Returns every tool registered in the Hands organ — payments / market / core / knowledge / search / memory / system. Each entry carries its category, risk level, JSON schemas, backing service and compliance notes. Filter by ``category`` or ``risk`` (read, write.user, confirm, escalate, external).","operationId":"list_platform_tools_v1_tools_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"risk","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Risk"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformToolListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tools/{tool_name}":{"get":{"tags":["hands"],"summary":"Describe one platform tool","operationId":"describe_platform_tool_v1_tools__tool_name__get","parameters":[{"name":"tool_name","in":"path","required":true,"schema":{"type":"string","title":"Tool Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformToolModel"}}}},"404":{"description":"Unknown tool name."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tools/{tool_name}/invoke":{"post":{"tags":["hands"],"summary":"Invoke one platform tool against the running session","description":"Runs the named tool with the supplied arguments inside a UserContext. Returns the ToolResult AND the Activity row that was appended to the session's audit trail. Side-effecting tools (risk=confirm) refuse to run unless the session already carries a matching confirmation token.\n\nSession semantics: pass `session_id` to continue an existing trail, omit it to start fresh.","operationId":"invoke_platform_tool_v1_tools__tool_name__invoke_post","parameters":[{"name":"tool_name","in":"path","required":true,"schema":{"type":"string","title":"Tool Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolInvokeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolInvokeResponse"}}}},"404":{"description":"Unknown tool."},"409":{"description":"Tool requires a confirmation token."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions/{session_id}/activity":{"get":{"tags":["hands"],"summary":"Get the activity trail for a session — Viki's thought process","description":"Returns every tool call, with PII-redacted args, that has run in this session — the audit/transparency timeline. The UI renders this as a chronological feed.","operationId":"get_session_activity_v1_sessions__session_id__activity_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Session Activity V1 Sessions  Session Id  Activity Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/permissions":{"get":{"tags":["hands"],"summary":"Read the current per-tool permission state for a session","description":"Returns each registered tool with its **default** permission mode (derived from risk) and the session's current **effective** mode after any overrides. Surface for the docs + playground control buttons.","operationId":"list_permissions_v1_permissions_get","parameters":[{"name":"session_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Permissions V1 Permissions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/permissions/{tool_name}":{"post":{"tags":["hands"],"summary":"Set a tool's permission mode for one session","description":"Set the session-level override for one tool. Valid modes: `allow_always`, `allow_session`, `ask_each_time`, `deny`. Pass `mode=null` (or omit the body) to clear the override and revert to the risk-derived default.","operationId":"set_permission_v1_permissions__tool_name__post","parameters":[{"name":"tool_name","in":"path","required":true,"schema":{"type":"string","title":"Tool Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Permission V1 Permissions  Tool Name  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat":{"post":{"tags":["orchestrator"],"summary":"Chat with Viki — input → plan → tools → response (SSE stream)","description":"Streams a chat turn as Server-Sent Events. Event kinds: `thinking`, `plan_built`, `task_started`, `tool_routed`, `model_tool_use`, `awaiting_approval`, `awaiting_confirmation`, `tool_called`, `model_tool_result`, `answer`, `done`. `model_tool_use` / `model_tool_result` mirror Anthropic's Messages API tool blocks (paired 1:1 by `block_id`) so clients can render the canonical \"model is calling X\" intermediate state. If the stream ends with `awaiting_approval` or `awaiting_confirmation`, POST the user's decision to `/v1/chat/{conversation_id}/approve` to resume.","operationId":"chat_v1_chat_post","parameters":[{"name":"X-Vikii-Locale","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vikii-Locale"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accept-Language"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"SSE stream of ChatEvent objects.","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/sync":{"post":{"tags":["orchestrator"],"summary":"Chat with Viki — non-streaming JSON variant of /v1/chat","description":"Same orchestrator pipeline as `/v1/chat` but returns one JSON object once the turn completes (no SSE). Exists because some HTTP clients — notably React Native's networking on Android — silently hang on `text/event-stream` + chunked transfer-encoding responses. Mobile callers without reliable SSE support should hit this instead.\n\nResponse shape: `conversation_id`, `session_id`, `events` (ordered list of ChatEvent objects identical to the SSE stream), `answer` (final assistant text, may be null), `awaiting` ('approval' | 'confirmation' | null).","operationId":"chat_sync_v1_chat_sync_post","parameters":[{"name":"X-Vikii-Locale","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vikii-Locale"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accept-Language"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Chat Sync V1 Chat Sync Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/{conversation_id}/approve":{"post":{"tags":["orchestrator"],"summary":"Resume a paused chat turn with the user's decision","description":"Continues an orchestrator run that paused on `awaiting_approval` or `awaiting_confirmation`. Body fields:\n* `decision`: `allow_once` | `allow_session` | `deny`","operationId":"approve_v1_chat__conversation_id__approve_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/augmentation-key":{"get":{"tags":["auth"],"summary":"Mint the per-session HMAC key for augmentation-envelope signing","description":"Returns the base64-encoded HMAC key the device uses to sign the augmentation envelope (v1.1 contract). The key is derived server-side via HKDF over the master HS256 secret with the JWT's `(sub, iat)` as salt — distinct sessions / refreshes yield distinct keys; the master secret never crosses the wire. The device caches this in MMKV (biometric-gated) and refreshes after every token rotation. See `vikii/docs/AUGMENTATION.md` v1.1 for the wire contract.","operationId":"get_augmentation_key_v1_auth_augmentation_key_get","responses":{"200":{"description":"Per-session key (base64-encoded, 32 bytes).","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Augmentation Key V1 Auth Augmentation Key Get"}}}},"401":{"description":"Missing or invalid bearer token."}}}},"/v1/chat/{conversation_id}/confirm":{"post":{"tags":["orchestrator"],"summary":"Resume a chat-graph turn paused on awaiting_confirmation (SDK-compatible shape)","description":"Mobile-SDK-compatible variant of `/v1/chat/threads/{conversation_id}/confirm`. Accepts the legacy SDK body `{decision: 'yes' | 'no'}` and resolves the most-recent pending confirmation for the conversation. Returns an SSE stream so the SDK's `chat.confirm()` consumer can flush the contract event without a JSON-vs-SSE mismatch.","operationId":"chat_legacy_confirm_v1_chat__conversation_id__confirm_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/threads/{conversation_id}/confirm":{"post":{"tags":["orchestrator"],"summary":"Record a tap-to-confirm decision for a chat-graph tool call","description":"Tap-to-confirm gate for the LangGraph chat path. The SSE stream emits an `awaiting_confirmation` frame whose `data` carries `tool_call_id`; after the user taps Approve or Deny, POST that id here with `{tool_call_id, approved}`. On approve, a single-use consent token lands in the per-conversation ConfirmationStore; the client should re-submit the same user message to resume — this time the consent gate finds the token and dispatch proceeds.\n\nPlain search (READ-tier tools) never reaches this endpoint.","operationId":"chat_thread_confirm_v1_chat_threads__conversation_id__confirm_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Chat Thread Confirm V1 Chat Threads  Conversation Id  Confirm Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/threads/{conversation_id}/action":{"post":{"tags":["orchestrator"],"summary":"Record the outcome of a MobileAction Viki opened","description":"Closes the action feedback loop. When Viki emits a `MobileAction` (an `awaiting_confirmation` frame carrying `data.action`), the mobile app opens the real in-app route. Once the user opens / dismisses / completes / aborts that flow, POST the outcome here as `{action_id, decision, note?}` where `decision` is `opened|dismissed|executed|aborted`. The outcome is folded into the NEXT turn's context as `[recent_actions]` so a follow-up ('did it go through?') is grounded on what actually happened — Viki never sees the in-app mutation directly, only this signal. Optional `command` (the MobileCommand value) makes the grounding line more legible.","operationId":"chat_thread_action_feedback_v1_chat_threads__conversation_id__action_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Chat Thread Action Feedback V1 Chat Threads  Conversation Id  Action Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/conversations":{"get":{"tags":["orchestrator"],"summary":"List in-memory conversations — powers the history screen","description":"Returns a lightweight directory of every conversation the process has handled since boot (capped at the FIFO eviction limit). Each row carries enough metadata for a list view: ids, user, when, completion status, and a one-line preview of the latest user input. Not paginated — capped pool, so the whole set fits easily in one response.","operationId":"list_conversations_v1_conversations_get","parameters":[{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional filter.","title":"User Id"},"description":"Optional filter."},{"name":"session_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional filter.","title":"Session Id"},"description":"Optional filter."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Conversations V1 Conversations Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/conversations/{conversation_id}/events":{"get":{"tags":["orchestrator"],"summary":"Replay every event a conversation produced — Debug screen feed","description":"Returns the full ordered event log for one conversation. Each event is `{kind, data, ts, meta}`. Powers the Debug screen and the read-only conversation viewer in the playground. Returns 404 when the conversation has been evicted.","operationId":"get_conversation_events_v1_conversations__conversation_id__events_get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Optional — return only events with ts > since (live tailing).","title":"Since"},"description":"Optional — return only events with ts > since (live tailing)."},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Required when hydrating from Aurora (L3): identifies the owner so cross-user reads are blocked. Ignored when the conversation is still in the L1 process cache.","title":"User Id"},"description":"Required when hydrating from Aurora (L3): identifies the owner so cross-user reads are blocked. Ignored when the conversation is still in the L1 process cache."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Conversation Events V1 Conversations  Conversation Id  Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/conversations/{conversation_id}/export":{"get":{"tags":["orchestrator"],"summary":"Export a conversation as JSON or markdown (P0.7)","description":"Reads the conversation timeline from Aurora (the same store P0.6 writes to) and returns either a JSON envelope or a markdown transcript suitable for download. Compliance pre-req for the banking surface — every saved conversation must be exportable for the user without round-tripping the live orchestrator state.\n\nCross-user isolation: caller's JWT user_id must match the conversation owner — repo query LEADS with user_id.","operationId":"export_conversation_v1_conversations__conversation_id__export_get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The user_id that owns the conversation (must match JWT).","title":"User Id"},"description":"The user_id that owns the conversation (must match JWT)."},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"`json` (default) or `markdown`.","default":"json","title":"Format"},"description":"`json` (default) or `markdown`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"string"}],"title":"Response Export Conversation V1 Conversations  Conversation Id  Export Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/{conversation_id}":{"get":{"tags":["orchestrator"],"summary":"Get the current state of one chat conversation","operationId":"get_chat_v1_chat__conversation_id__get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Chat V1 Chat  Conversation Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/feedback":{"post":{"tags":["orchestrator"],"summary":"Record a CSAT thumb / 1-5 rating for one chat turn","description":"Persists user satisfaction signal against a completed turn. Powers the deflection / CSAT dashboards. The mobile bubble's thumbs-up / thumbs-down on an assistant message POSTs here with the conversation's last turn_id.","operationId":"chat_feedback_v1_chat_feedback_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Payload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Chat Feedback V1 Chat Feedback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/signals":{"post":{"tags":["signals"],"summary":"Record one implicit user signal (copy/share/save/regenerate/stop/...)","description":"Anon-friendly. Body keys: signal_kind, surface, modality, client_session, client_ts, user_agent_class, plus optional run_id, conversation_id, turn_id, user_id, value{}. The server rejects payloads carrying assistant text or user prompt content — only counts/durations/share-targets are accepted.","operationId":"post_signal_v1_signals_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Payload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Post Signal V1 Signals Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/signals/batch":{"post":{"tags":["signals"],"summary":"Batch up to 50 implicit signals","operationId":"post_signals_batch_v1_signals_batch_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Payload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Post Signals Batch V1 Signals Batch Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/generate/image":{"post":{"tags":["generate"],"summary":"Generate one or more images from a text prompt","operationId":"generate_image_v1_generate_image_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageGenerateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageGenerateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/generate/video":{"post":{"tags":["generate"],"summary":"Generate a short video from a text prompt (Veo LRO)","operationId":"generate_video_v1_generate_video_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoGenerateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoGenerateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/generate/music":{"post":{"tags":["generate"],"summary":"Generate a music clip from a text prompt (Lyria)","operationId":"generate_music_v1_generate_music_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MusicGenerateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MusicGenerateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/creation/plan":{"post":{"tags":["creation"],"summary":"Creation Plan","description":"One step of the model-authored adaptive question loop.\n\nThe model authors the questions, confidence, and reflect-back line; the\ndevice loops (appending answers) until ``ready``. Always returns a usable\nloop state — a model parse failure or provider outage degrades to a single\nfallback question rather than erroring (no silent failure).","operationId":"creation_plan_v1_creation_plan_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreationPlanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreationPlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/creation/submit":{"post":{"tags":["creation"],"summary":"Creation Submit","description":"Compose the structured intent into a brief and stream the orchestrator turn.\n\nF1: the device sends the structured ``creation`` block (no assembled prompt);\n:func:`build_creation_brief` renders it into a factual brief, and the model\nauthors the final prompt and calls the existing native generation tools\n(``image.generate`` / ``video.generate`` / ``music.generate``). SSE frames\nmirror ``/v1/chat`` so existing consumers need no wire change. ``tier`` comes\nfrom the JWT only.","operationId":"creation_submit_v1_creation_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreationSubmitRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/creation/runs/{run_id}/stream":{"get":{"tags":["creation"],"summary":"Creation Run Stream","description":"Re-attach to a backgrounded movie run's live progress (I2).\n\nThe submit connection can drop (cellular, app backgrounded); the client\nre-attaches here to resume live ``production.*`` progress, or — if the run\nalready finished — receive the terminal artifact/error straight from the\npersisted run row. IDOR-safe: the run is read scoped to the owner.","operationId":"creation_run_stream_v1_creation_runs__run_id__stream_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/creation/runs/{run_id}/artifact":{"get":{"tags":["creation"],"summary":"Creation Artifact","description":"Serve a run's persisted media bytes (History/Files). IDOR-safe: scoped to\nthe owner — a foreign or unknown run_id returns 404, never another user's media.","operationId":"creation_artifact_v1_creation_runs__run_id__artifact_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/creation/runs/{run_id}/scenes":{"get":{"tags":["creation"],"summary":"Creation Run Scenes","description":"List a movie run's scenes (index + duration + summary) for the result\nscrubber's per-scene re-edit markers (I7). IDOR-safe: scoped to the owner;\nan empty list when the run isn't an editable multi-scene movie.","operationId":"creation_run_scenes_v1_creation_runs__run_id__scenes_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Creation Run Scenes V1 Creation Runs  Run Id  Scenes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/creation/runs/{run_id}/scenes/{scene_index}/regenerate":{"post":{"tags":["creation"],"summary":"Creation Scene Regenerate","description":"Re-edit ONE scene of a finished movie (E1 / I7) + re-stitch.\n\nRegenerates only the targeted scene (optionally folding the user's edit\n``instruction`` into its prompt), re-stitches from the durable per-scene\nclips, and updates the run's artifact in place. IDOR-safe: the run is read\nscoped to the owner first; a foreign / unknown run_id → 404 before any work.\nStreams SSE so the scrubber shows progress and lands on the new artifact;\nthe edited movie is served by the existing ``/runs/{id}/artifact`` route.","operationId":"creation_scene_regenerate_v1_creation_runs__run_id__scenes__scene_index__regenerate_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"scene_index","in":"path","required":true,"schema":{"type":"integer","title":"Scene Index"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_creation_scene_regenerate_v1_creation_runs__run_id__scenes__scene_index__regenerate_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/creation/runs/{run_id}/music":{"post":{"tags":["creation"],"summary":"Creation Run Rescore","description":"Re-score a finished movie (E4 / I9): regenerate the music bed (optionally\nfrom a new brief) + re-stitch, replacing only the audio. IDOR-safe; streams\nSSE; the re-scored movie is served by the existing artifact route.","operationId":"creation_run_rescore_v1_creation_runs__run_id__music_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_creation_run_rescore_v1_creation_runs__run_id__music_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/creation/doc/regen":{"post":{"tags":["creation"],"summary":"Creation Doc Regen","description":"Refresh exactly one template slot — the editor's per-text \"rewrite\" and\nper-image \"regenerate\". Independently rate-limited like submit (eng D3).\nReturns just the one slot's new value so the editor patches it in place.","operationId":"creation_doc_regen_v1_creation_doc_regen_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocRegenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocRegenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/notifications/token":{"post":{"tags":["notifications"],"summary":"Register Push Token","description":"Register / refresh this device's push token for the authenticated user.","operationId":"register_push_token_v1_notifications_token_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Register Push Token V1 Notifications Token Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["notifications"],"summary":"Unregister Push Token","description":"Drop a device token (logout / token rotation).","operationId":"unregister_push_token_v1_notifications_token_delete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Unregister Push Token V1 Notifications Token Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/history":{"get":{"tags":["creation-history"],"summary":"List History","description":"The user's creation sessions, newest first.","operationId":"list_history_v1_history_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"before","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Before"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List History V1 History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/files":{"get":{"tags":["creation-history"],"summary":"List Files","description":"The user's generated assets (runs that produced a stored artifact).","operationId":"list_files_v1_files_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"before","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Before"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Files V1 Files Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/inputs/transcribe":{"post":{"tags":["nervous-system"],"summary":"Transcribe an uploaded audio clip to text (server-side STT)","description":"Accepts a short audio recording (multipart ``file``) and returns the transcript. Used by the mobile composer mic button: the device records with expo-av, uploads here, and Gemini transcribes. Replaces the removed on-device ``expo-speech-recognition`` path.","operationId":"transcribe_audio_v1_inputs_transcribe_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_transcribe_audio_v1_inputs_transcribe_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscribeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/studio/runs":{"post":{"tags":["studio"],"summary":"Create + execute a generation run (user-scoped)","operationId":"create_studio_run_v1_studio_runs_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioRunRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/studio/jobs/{job_id}":{"get":{"tags":["studio"],"summary":"Async media job status (user-scoped)","operationId":"get_studio_job_v1_studio_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Studio Job V1 Studio Jobs  Job Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/studio/runs/{run_id}/artifact":{"get":{"tags":["studio"],"summary":"Fetch a produced artifact (user-scoped)","description":"Per-user artifact fetch.\n\nMirrors the admin ``GET /v1/lab/runs/{run_id}/artifact`` serving logic\n(path-traversal safety + presigned-S3 redirect / local-fs streaming /\naudio transcode) but layered on top of an owner check. The mobile\nclient historically sent ``?key=`` while the admin route uses\n``?path=``; we accept either, preferring ``path``.","operationId":"get_studio_artifact_v1_studio_runs__run_id__artifact_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"path","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Path under the run's artifact prefix.","title":"Path"},"description":"Path under the run's artifact prefix."},{"name":"key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Alias for ``path`` (mobile client compatibility).","title":"Key"},"description":"Alias for ``path`` (mobile client compatibility)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/users/{uid}/facts":{"get":{"tags":["admin-memory"],"summary":"List User Facts","description":"All active facts for the user, highest-confidence first.\nExcludes forgotten / decayed / superseded rows.","operationId":"list_user_facts_admin_v1_users__uid__facts_get","parameters":[{"name":"uid","in":"path","required":true,"schema":{"type":"string","title":"Uid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/users/{uid}/facts/{fid}/history":{"get":{"tags":["admin-memory"],"summary":"Fact Supersede History","description":"Walk the supersede chain backwards from ``fid`` to the original\nassertion. Used by the admin UI to show \"what did this fact say\nbefore the user corrected it?\" Returns oldest → newest.","operationId":"fact_supersede_history_admin_v1_users__uid__facts__fid__history_get","parameters":[{"name":"uid","in":"path","required":true,"schema":{"type":"string","title":"Uid"}},{"name":"fid","in":"path","required":true,"schema":{"type":"integer","title":"Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FactDTO"},"title":"Response Fact Supersede History Admin V1 Users  Uid  Facts  Fid  History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/users/{uid}/facts/{fid}":{"patch":{"tags":["admin-memory"],"summary":"Edit Fact","description":"Admin override — change object or confidence on an existing\nfact. Uses the same supersede-chain path as a user-triggered\ncontradiction so the audit trail captures it.","operationId":"edit_fact_admin_v1_users__uid__facts__fid__patch","parameters":[{"name":"uid","in":"path","required":true,"schema":{"type":"string","title":"Uid"}},{"name":"fid","in":"path","required":true,"schema":{"type":"integer","title":"Fid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactDTO"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin-memory"],"summary":"Soft Delete Fact","description":"Soft-delete (forget) a fact. Idempotent — already-forgotten\nrows return 204 too.","operationId":"soft_delete_fact_admin_v1_users__uid__facts__fid__delete","parameters":[{"name":"uid","in":"path","required":true,"schema":{"type":"string","title":"Uid"}},{"name":"fid","in":"path","required":true,"schema":{"type":"integer","title":"Fid"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/users/{uid}/episodes":{"get":{"tags":["admin-memory"],"summary":"List User Episodes","description":"Most-recent episodes within ``days`` for review.\n\nRead-only — doesn't reveal embeddings (admin only sees summary_text\n+ metadata + timestamps). Embeddings are not human-readable anyway\nand would inflate the response.","operationId":"list_user_episodes_admin_v1_users__uid__episodes_get","parameters":[{"name":"uid","in":"path","required":true,"schema":{"type":"string","title":"Uid"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":730,"minimum":1,"default":180,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodesListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/users/{uid}/episodes/{eid}":{"delete":{"tags":["admin-memory"],"summary":"Soft Decay Episode","description":"Mark an episode as decayed (hide from recall). Idempotent.","operationId":"soft_decay_episode_admin_v1_users__uid__episodes__eid__delete","parameters":[{"name":"uid","in":"path","required":true,"schema":{"type":"string","title":"Uid"}},{"name":"eid","in":"path","required":true,"schema":{"type":"integer","title":"Eid"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/users/{uid}/forget-me":{"post":{"tags":["admin-memory"],"summary":"Forget Me Gdpr","description":"GDPR hard-delete: removes ALL facts + ALL episodes for the user.\n\nIrreversible. The admin-panel double-confirms before calling this.\nLogs the admin user_id + target user_id for SIEM audit (required by\nArt. 30 record-keeping).","operationId":"forget_me_gdpr_admin_v1_users__uid__forget_me_post","parameters":[{"name":"uid","in":"path","required":true,"schema":{"type":"string","title":"Uid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgetMeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/activities/by-user/{user_id}":{"get":{"tags":["admin-activity"],"summary":"List recent activity rows for one user across live sessions.","operationId":"list_by_user_admin_v1_activities_by_user__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"tool","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by tool name.","title":"Tool"},"description":"Filter by tool name."},{"name":"since_seconds","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":604800,"minimum":1},{"type":"null"}],"description":"Drop activities older than N seconds (max 7d).","title":"Since Seconds"},"description":"Drop activities older than N seconds (max 7d)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivitiesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/activities/by-conversation/{conversation_id}":{"get":{"tags":["admin-activity"],"summary":"List activity rows for one conversation_id.","operationId":"list_by_conversation_admin_v1_activities_by_conversation__conversation_id__get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"tool","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by tool name.","title":"Tool"},"description":"Filter by tool name."},{"name":"since_seconds","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":604800,"minimum":1},{"type":"null"}],"description":"Drop activities older than N seconds (max 7d).","title":"Since Seconds"},"description":"Drop activities older than N seconds (max 7d)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivitiesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/v1/policy":{"get":{"tags":["admin-policy"],"summary":"Return the active ModelPolicy YAML","description":"Reads the policy YAML resolved by ``get_policy().load()``. Returns the raw text so the admin panel can render it with syntax highlighting + diff against a saved snapshot. Hot-reload is the companion ``POST /admin/policy/reload`` endpoint below.","operationId":"get_active_policy_admin_v1_policy_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEnvelope"}}}}}}},"/admin/v1/policy/reload":{"post":{"tags":["admin-policy"],"summary":"Hot-reload the ModelPolicy YAML from disk","description":"Re-reads the YAML at the path used by ``get_policy()`` and swaps the process singleton. Validators (driver_id resolution, non-empty cascades) run before the swap so an invalid reload leaves the previous policy live. Equivalent to a SIGHUP.","operationId":"reload_policy_admin_v1_policy_reload_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Reload Policy Admin V1 Policy Reload Post"}}}}}}},"/admin/v1/policy/cascade/{task}":{"get":{"tags":["admin-policy"],"summary":"Flatten the (tier × task) cascade for one task","description":"Returns the driver chain that would fire for the given task across every tier. Use this from the admin panel to answer 'why did this user get model X for task Y on tier Z?'.","operationId":"get_cascade_for_task_admin_v1_policy_cascade__task__get","parameters":[{"name":"task","in":"path","required":true,"schema":{"type":"string","title":"Task"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CascadeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/diet-status":{"get":{"tags":["admin"],"summary":"Diet Status","description":"Snapshot of the token-diet rollout. See module docstring.","operationId":"diet_status_v1_admin_diet_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Diet Status V1 Admin Diet Status Get"}}}}}}},"/v1/rooms":{"get":{"tags":["rooms"],"summary":"List Rooms","operationId":"list_rooms_v1_rooms_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/_RoomOut"},"type":"array","title":"Response List Rooms V1 Rooms Get"}}}}}},"post":{"tags":["rooms"],"summary":"Create Room","operationId":"create_room_v1_rooms_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_CreateRoomBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/_RoomOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rooms/{room_id}":{"get":{"tags":["rooms"],"summary":"Get Room","operationId":"get_room_v1_rooms__room_id__get","parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","title":"Room Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/_RoomDetailOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["rooms"],"summary":"Archive Room","operationId":"archive_room_v1_rooms__room_id__delete","parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","title":"Room Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Archive Room V1 Rooms  Room Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rooms/{room_id}/turns":{"post":{"tags":["rooms"],"summary":"Append Turn","operationId":"append_turn_v1_rooms__room_id__turns_post","parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","title":"Room Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_AppendTurnBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Append Turn V1 Rooms  Room Id  Turns Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rooms/{room_id}/close":{"post":{"tags":["rooms"],"summary":"Close Room","operationId":"close_room_v1_rooms__room_id__close_post","parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","title":"Room Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Close Room V1 Rooms  Room Id  Close Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/voice/sessions":{"post":{"tags":["voice"],"summary":"Mint a LiveKit voice session for the authenticated user","description":"Returns a LiveKit room + access token. The voice worker is dispatched in the background and joins the room within ~1s. Client connects to ``livekit_url`` with ``access_token`` and publishes the user's microphone track.","operationId":"start_voice_session_v1_voice_sessions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSessionStartRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/voice/sessions/{session_id}/refresh":{"post":{"tags":["voice"],"summary":"Rotate the LiveKit access token for an active voice session","description":"Re-mints the LiveKit JWT for an existing room so a long voice call survives the access-token TTL. Authed users only — anon sessions are capped at ``voice_anon_max_seconds`` by design. Clients should call ~60s before ``expires_at`` and replace the token on the active LiveKit participant.","operationId":"refresh_voice_session_v1_voice_sessions__session_id__refresh_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/voice/sessions/{session_id}/end":{"post":{"tags":["voice"],"summary":"End an active voice session and tear its worker down","description":"Authoritatively ends a voice session: signals the worker holding the LiveKit room to disconnect + close its Gemini Live socket and flushes the session's bookkeeping. The client calls this when the user closes the voice overlay so teardown never depends on LiveKit delivering a participant-disconnect (a force-quit / network drop may not send one). Idempotent — ending an already-gone session is a no-op. Authenticated by the same voice-session token the vision-frame route uses: the token's ``sid`` claim must equal the path ``session_id``, so a caller can only end the session that token minted (authed + anon alike).","operationId":"end_voice_session_v1_voice_sessions__session_id__end_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response End Voice Session V1 Voice Sessions  Session Id  End Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/voice/sessions/anon":{"post":{"tags":["voice"],"summary":"Mint a short anonymous voice session (marketing site)","description":"No JWT required. Capped at ``voice_anon_max_seconds`` (default 90s). IP-rate-limited to ``voice_anon_per_ip_per_hour`` (default 10). The minted session_token carries ``anon=true`` so the Hands permission layer can deny write tools.","operationId":"start_anon_voice_session_v1_voice_sessions_anon_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnonVoiceSessionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSessionResponse"}}}},"429":{"description":"Anon rate limit exceeded for this IP."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/voice/capabilities":{"get":{"tags":["voice"],"summary":"List the languages Viki can hear, speak, and reason in","description":"Read-only projection of the canonical language catalog (``vikii.content.languages``). Clients use this to drive the language picker, on-device TTS voice fallback, and the accent-disclaimer rider. Static data — safe to cache for hours.","operationId":"voice_capabilities_v1_voice_capabilities_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceCapabilitiesResponse"}}}}}}},"/v1/voice/sessions/{session_id}/vision-frame":{"post":{"tags":["voice"],"summary":"Ingest a camera frame for an active voice session","description":"Accepts a single JPEG (≤200KB, 768px max edge recommended). Throttled to 2 fps per session by the client; the server stores only the latest frame so a slow consumer never falls behind. Honour ``Content-Type: image/jpeg``.\n\nSecurity model: the client MUST send the downgraded voice-session token (``Authorization: Bearer ...`` or a ``X-Vikii-Voice-Session-Token`` header) that ``/v1/voice/sessions`` returned. The token's ``sid`` claim must equal the path ``session_id`` — frames cannot be written into a session the caller does not own, even by guessing the id.","operationId":"ingest_vision_frame_v1_voice_sessions__session_id__vision_frame_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid voice-session token."},"403":{"description":"Token does not own this session_id."},"413":{"description":"Frame exceeded the per-frame byte cap."},"415":{"description":"Unsupported media type (must be image/jpeg)."},"429":{"description":"Frame rate exceeded the per-session ceiling."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/assistant/signal/ack":{"post":{"summary":"Device response to a local_search_request","description":"Validate, sanitise, resolve. See module docstring for the wire\ncontract and error vocabulary.","operationId":"signal_ack_v1_assistant_signal_ack_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistantSignalAckBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Signal Ack V1 Assistant Signal Ack Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attachments":{"post":{"tags":["attachments"],"summary":"Upload Attachment","description":"Upload one attachment for the authenticated user.\n\nReturns the attachment metadata + ``uri`` the chat client passes\nback as a ``VikiiAttachment`` on subsequent ``/v1/chat`` turns.","operationId":"upload_attachment_v1_attachments_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_attachment_v1_attachments_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Upload Attachment V1 Attachments Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attachments/from-url":{"post":{"tags":["attachments"],"summary":"Upload From Url","description":"Server-side fetch a URL and store it as a regular attachment.\n\nMime allowlist + size cap are the same as the upload route. Direct\nmedia URLs only — pages that don't serve the bytes inline (e.g. a\nYouTube watch page) will fail mime validation. A future follow-up\ncan plug yt-dlp / Gemini URL-understanding behind this same route\nso the UI surface stays identical.","operationId":"upload_from_url_v1_attachments_from_url_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body","description":"{ url: string }"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Upload From Url V1 Attachments From Url Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attachments/{attachment_id}":{"get":{"tags":["attachments"],"summary":"Get Attachment","description":"Read back an attachment. Per-user scope is enforced by the\non-disk layout — the route only reads from ``{store}/{user_id}/``\nso cross-user reads can't escape via a guessed id.","operationId":"get_attachment_v1_attachments__attachment_id__get","parameters":[{"name":"attachment_id","in":"path","required":true,"schema":{"type":"string","title":"Attachment Id"}}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents/upload":{"post":{"tags":["documents"],"summary":"Register an attachment as a document + enqueue ingestion","operationId":"upload_document_v1_documents_upload_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUploadRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Upload Document V1 Documents Upload Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents":{"get":{"tags":["documents"],"summary":"List the caller's documents","operationId":"list_documents_v1_documents_get","parameters":[{"name":"tenant_scope","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Scope"}},{"name":"include_deleted","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Deleted"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Documents V1 Documents Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents/search":{"post":{"tags":["documents"],"summary":"Top-K semantic search across the caller's docs","operationId":"search_documents_v1_documents_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentSearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Search Documents V1 Documents Search Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents/{doc_id}/summarize":{"post":{"tags":["documents"],"summary":"Structured long-form summary","operationId":"summarize_document_v1_documents__doc_id__summarize_post","parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DocumentSummarizeBody"},{"type":"null"}],"title":" "}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Summarize Document V1 Documents  Doc Id  Summarize Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents/{doc_id}/audio_overview":{"post":{"tags":["documents"],"summary":"Sulafat-voice audio briefing","operationId":"audio_overview_document_v1_documents__doc_id__audio_overview_post","parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DocumentAudioOverviewBody"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Audio Overview Document V1 Documents  Doc Id  Audio Overview Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents/{doc_id}":{"delete":{"tags":["documents"],"summary":"Soft-delete one document","operationId":"delete_document_v1_documents__doc_id__delete","parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Document V1 Documents  Doc Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/kb/docs":{"get":{"tags":["catalogue"],"summary":"List published Knowledge Base entries (Journal index)","description":"Locale-aware list of published Journal entries. Each entry has title + summary + slug — fetch the full body with ``GET /v1/kb/docs/{slug}``. Falls back to the English row for any doc that has no translation in the requested locale. Source: ``vikii/knowledge/products/*.md`` (read directly from disk, no database).","operationId":"list_kb_docs_v1_kb_docs_get","parameters":[{"name":"locale","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"BCP-47 locale (e.g. 'en', 'fr').","title":"Locale"},"description":"BCP-47 locale (e.g. 'en', 'fr')."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JournalListResponse"}}}},"429":{"description":"Anon rate limit exceeded for this IP."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/kb/docs/{slug}":{"get":{"tags":["catalogue"],"summary":"Fetch one Knowledge Base entry by slug","description":"Returns the full Journal entry including ``body_md`` (raw markdown). Falls back to the English row when no translation exists for ``locale``. 404 when the slug is unknown or unpublished.","operationId":"get_kb_doc_v1_kb_docs__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"locale","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Locale"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JournalEntryResponse"}}}},"404":{"description":"No published entry for slug + locale fallback."},"429":{"description":"Anon rate limit exceeded for this IP."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs":{"post":{"tags":["lab"],"summary":"Create + execute a Lab run","description":"Spawn one Lab run. All known agent types (text, voice, image,\nmusic, video, document) are live; an unknown type returns 400.","operationId":"create_run_v1_lab_runs_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRunRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["lab"],"summary":"List runs (filterable, keyset-paginated)","description":"Paginated runs list. Consumed by Viki Lab's Evaluation tab\n(HumanReviewPanel + FailuresPanel) — the standalone Playground\n``Runs`` page that previously called this was deleted on 2026-05-26,\nbut Evaluation still needs the list for review/triage flows.","operationId":"list_runs_v1_lab_runs_get","parameters":[{"name":"agent_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Type"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"dataset_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Id"}},{"name":"started_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started After"}},{"name":"started_before","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started Before"}},{"name":"tier","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"}},{"name":"parent_run_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Run Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Runs V1 Lab Runs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/{run_id}/variations":{"post":{"tags":["lab"],"summary":"Generate a styled variation of a finished production run","description":"Spawn a fresh run that re-uses the parent's input but overrides\nthe style (+ optionally color) preset. The user subscribes to the\nnew run's SSE stream like any other generation.\n\nWave 4b / CEO D5. JWT scope is enforced two ways: ``require_admin``\ngates the route at the framework layer, and we re-check that the\nparent run belongs to the same admin user before allowing the\nvariation (so admin A doesn't accidentally remix admin B's run).\n\nThe variation endpoint takes the full ``CreateRunRequest`` payload\nin the body alongside the ``VariationRequest`` block — the caller\nis expected to ship the original prompt + assets it has in local\nstate. v2 will read the parent's input from the S3 trace\nautomatically; v1 relies on the UI to carry the input forward.","operationId":"create_variation_v1_lab_runs__run_id__variations_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_create_variation_v1_lab_runs__run_id__variations_post"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/{run_id}/resume":{"post":{"tags":["lab"],"summary":"Resume a paused or crashed production run from its last checkpoint","description":"Re-enter the orchestrator at the last successfully-checkpointed stage.\n\nWave 4b / T5. The orchestrator writes a checkpoint after every agent\nvia ``vikii.services.lab.production.checkpoints.save_checkpoint``.\nThis endpoint reads the latest checkpoint via ``load_checkpoint`` and\nschedules a continuation through the existing run executor.\n\nThree terminal states:\n\n* ``resumed`` — checkpoint loaded, continuation scheduled, the\n  caller subscribes to the existing ``/v1/lab/runs/{run_id}/stream``\n  SSE channel.\n* ``no_checkpoint`` — nothing to resume (404 in body, not HTTP, so\n  the UI can render a \"start over\" affordance instead of erroring).\n* ``already_complete`` — run already terminal (succeeded / failed).\n  Caller should fetch the run row instead of resuming.\n\nJWT scope is enforced by ``require_admin`` (consistent with the\nother ``/v1/lab/runs/...`` routes). The run row's user_id is NOT\nre-checked here because admin tools resume on behalf of users; a\nfuture per-user resume route can layer that check on.","operationId":"resume_run_v1_lab_runs__run_id__resume_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/{run_id}":{"get":{"tags":["lab"],"summary":"Fetch one Lab run","operationId":"get_run_v1_lab_runs__run_id__get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/{run_id}/stream":{"get":{"tags":["lab"],"summary":"SSE stream of trace events for one run","description":"SSE feed of the run's trace events.\n\nAudit follow-up §5 — multi-replica subscribe path is now wired.\nThe endpoint reads from :func:`lab_events.subscribe` which races\nthe local in-process queue against the Redis Pub/Sub channel at\n``vikii:lab:run:{run_id}:events`` (when ``VIKII_REDIS_URL`` is\nset). Events are deduplicated by ``event_id`` so the same frame\nlanding on both paths is emitted exactly once.\n\nThe endpoint terminates on the first ``run_completed`` /\n``run_failed`` event so the client doesn't hang past the run's\nnatural end. If no queue exists for the run_id (because the run\nfinished before this endpoint was hit), we fall through to the\nreplay path below.","operationId":"stream_run_v1_lab_runs__run_id__stream_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/{run_id}/artifact":{"get":{"tags":["lab"],"summary":"Signed S3 redirect for an artifact","description":"Issue a presigned S3 GET URL and 302 to it.\n\nPath-traversal protection lives in :func:`storage.resolve_artifact_uri`.\nRejects ``..`` segments, leading ``/``, and any path that doesn't\nstay under the run's known prefix. Returns 400 on a malformed path\nor 404 when the run doesn't exist.","operationId":"get_run_artifact_v1_lab_runs__run_id__artifact_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Path under the run's S3 prefix.","title":"Path"},"description":"Path under the run's S3 prefix."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/{run_id}/cancel":{"post":{"tags":["lab"],"summary":"Cancel a running execution","description":"Flip the per-run cancellation flag.\n\nPlan §15.1 — the executor checks the flag at every node boundary\ninside ``_run_text`` and raises ``asyncio.CancelledError`` when set.\nThe executor's handler in turn marks the run row ``status='cancelled'``\nand publishes a terminal ``run_completed`` lifecycle frame.\n\nReturns:\n\n* 202 + ``{\"run_id\": ..., \"cancel_requested\": true}`` when a live\n  run was found and the flag was flipped.\n* 404 when no live run exists for the id (either it already\n  finished or it was never started).","operationId":"cancel_run_v1_lab_runs__run_id__cancel_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Cancel Run V1 Lab Runs  Run Id  Cancel Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/{run_id}/approve":{"post":{"tags":["lab"],"summary":"Approve a paused storyboard gate (Music → Video Phase B)","description":"Signal the production orchestrator that the user has reviewed +\napproved the storyboard for ``run_id`` (or rejected it).\n\nBody shape:\n  ``{\"approved\": bool, \"scene_overrides\": {idx: {\"visual_prompt\"?, \"summary\"?}}}``\n\nWhen ``approved=true`` the orchestrator resumes; per-scene overrides\npatch the storyboard before the Veo agents run, letting the user\ntweak a single shot without re-running the full LLM pass.","operationId":"approve_storyboard_v1_lab_runs__run_id__approve_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}],"title":"Body"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Approve Storyboard V1 Lab Runs  Run Id  Approve Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/compare":{"post":{"tags":["lab"],"summary":"Diff two runs","description":"Diff two run traces (events, tool calls, answer text, latency, cost).\n\nAudit follow-up §4.36 — replaces the previous 501 stub. Both runs\nlive in ``playground_runs`` + ``playground_tool_calls`` (plus their\ngzipped trace blob via :func:`storage.fetch_trace`); no new schema.","operationId":"compare_runs_v1_lab_runs_compare_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Compare Runs V1 Lab Runs Compare Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/prompts":{"get":{"tags":["lab"],"summary":"List prompts / filter by agent_type","description":"Return the persisted prompts catalogue, optionally filtered by\n``agent_type``. The Lab UI uses this to render the registry page;\neach row includes the current production version id (or ``None``\nwhen no version has been promoted yet).","operationId":"list_prompts_v1_lab_prompts_get","parameters":[{"name":"agent_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Prompts V1 Lab Prompts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["lab"],"summary":"Create a prompt name","operationId":"create_prompt_v1_lab_prompts_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePromptBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Prompt V1 Lab Prompts Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/prompts/{prompt_id}":{"get":{"tags":["lab"],"summary":"Fetch one prompt + its versions","operationId":"get_prompt_v1_lab_prompts__prompt_id__get","parameters":[{"name":"prompt_id","in":"path","required":true,"schema":{"type":"string","title":"Prompt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Prompt V1 Lab Prompts  Prompt Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/prompts/{prompt_id}/versions":{"post":{"tags":["lab"],"summary":"Add a draft version","operationId":"add_prompt_version_v1_lab_prompts__prompt_id__versions_post","parameters":[{"name":"prompt_id","in":"path","required":true,"schema":{"type":"string","title":"Prompt Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddPromptVersionBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Add Prompt Version V1 Lab Prompts  Prompt Id  Versions Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/prompts/versions/{version_id}/promote":{"post":{"tags":["lab"],"summary":"Promote a prompt version to a stage","operationId":"promote_prompt_version_v1_lab_prompts_versions__version_id__promote_post","parameters":[{"name":"version_id","in":"path","required":true,"schema":{"type":"string","title":"Version Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromotePromptBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Promote Prompt Version V1 Lab Prompts Versions  Version Id  Promote Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/prompts/versions/{version_id}/rollback":{"post":{"tags":["lab"],"summary":"Roll a production version back","operationId":"rollback_prompt_version_v1_lab_prompts_versions__version_id__rollback_post","parameters":[{"name":"version_id","in":"path","required":true,"schema":{"type":"string","title":"Version Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Rollback Prompt Version V1 Lab Prompts Versions  Version Id  Rollback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/models":{"get":{"tags":["lab"],"summary":"Read DRIVER_REGISTRY + ModelPolicy + DB overrides","description":"Serialize the driver registry + the active policy cascades +\nDB-shadow drivers/cascades.\n\nYAML cascades remain the runtime source of truth (per the V007\nplan). The DB lists are surfaced as ``db_drivers`` /\n``db_cascades`` so the Lab UI can render a \"Source: YAML / DB\ndraft\" badge per row.","operationId":"list_models_v1_lab_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Models V1 Lab Models Get"}}}}}}},"/v1/lab/models/drivers":{"post":{"tags":["lab"],"summary":"Upsert a DB-shadow driver row","operationId":"upsert_db_driver_v1_lab_models_drivers_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertDriverBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Upsert Db Driver V1 Lab Models Drivers Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/models/cascades":{"post":{"tags":["lab"],"summary":"Insert a DB-shadow cascade row","operationId":"upsert_db_cascade_v1_lab_models_cascades_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertCascadeBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Upsert Db Cascade V1 Lab Models Cascades Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/tools":{"get":{"tags":["lab"],"summary":"Read TOOL_REGISTRY","description":"Serialize the tool registry.\n\nReturns the full ``to_dict`` projection per tool (name, summary,\nschemas, citation_template, backing_service, risk, category,\ndescription_for_model, when-to-use / when-NOT-to-use, examples).\nAdmin-only, so we use the internal projection rather than\n``to_public_dict`` — staff need to see the upstream paths to\ndebug failures.","operationId":"list_tools_v1_lab_tools_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Tools V1 Lab Tools Get"}}}}}}},"/v1/lab/evals/run":{"post":{"tags":["lab"],"summary":"Run a dataset against a config","operationId":"run_eval_batch_v1_lab_evals_run_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvalRunRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Run Eval Batch V1 Lab Evals Run Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/evals/{batch_id}":{"get":{"tags":["lab"],"summary":"Batch status + aggregated scores","operationId":"get_eval_batch_v1_lab_evals__batch_id__get","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Eval Batch V1 Lab Evals  Batch Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/evals/{batch_id}/report":{"get":{"tags":["lab"],"summary":"Render the batch report","operationId":"get_eval_report_v1_lab_evals__batch_id__report_get","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}},{"name":"fmt","in":"query","required":false,"schema":{"type":"string","pattern":"^(markdown|json|csv)$","default":"markdown","title":"Fmt"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/evals/compare":{"post":{"tags":["lab"],"summary":"Compare two batches","operationId":"compare_eval_batches_v1_lab_evals_compare_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareBatchesBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Compare Eval Batches V1 Lab Evals Compare Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/evals/release-gate":{"post":{"tags":["lab"],"summary":"Release-gate decision","operationId":"release_gate_decision_v1_lab_evals_release_gate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseGateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Release Gate Decision V1 Lab Evals Release Gate Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/release-gates":{"get":{"tags":["lab"],"summary":"List recent release-gate decisions","operationId":"list_release_gates_v1_lab_release_gates_get","parameters":[{"name":"scope","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Release Gates V1 Lab Release Gates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/tool-failures":{"get":{"tags":["lab"],"summary":"Tool failures rolled up by tool name (24h default)","operationId":"list_tool_failures_v1_lab_tool_failures_get","parameters":[{"name":"since_hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"default":24,"title":"Since Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Tool Failures V1 Lab Tool Failures Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/voice/simulate":{"post":{"tags":["lab"],"summary":"Feed a canned text fixture to the voice graph + emit a synthetic timeline","description":"Wave 4 — synthesise a device-side voice timeline + drive the voice graph.\n\nReturns ``{run_id, stream_url, ...}`` matching the text-run shape so\nthe Lab UI can reuse :func:`useRunStream` for the timeline subscription.","operationId":"voice_simulate_v1_lab_voice_simulate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSimulateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/jobs/{job_id}":{"get":{"tags":["lab"],"summary":"Async media job status","description":"Return the current state of a media job.\n\nThe state row is owned by :mod:`vikii.services.lab.media_worker`:\nseeded with ``status='running'`` on submit, updated to\n``status='succeeded'`` (with ``artifact_uri`` + ``result``) or\n``status='failed'`` (with ``error``) once the worker finishes.\n\nReturns 404 when neither Redis nor the persisted run row knows\nabout the id. The route shape mirrors ``/v1/lab/runs/{run_id}``\nfor consistency — callers can poll on the same cadence.","operationId":"get_job_v1_lab_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Job V1 Lab Jobs  Job Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/suggest-options":{"post":{"tags":["lab"],"summary":"Prompt-aware chip suggestions for the + generation dialog","description":"Return up to 3 catalogue ids per relevant field for the given\nprompt + modality. Powers the suggestion chips above the chip\ngroups in the rebuilt generation dialog.\n\nBest-effort: returns empty entries on provider failure so the UI\ndegrades silently.","operationId":"suggest_options_route_v1_lab_suggest_options_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestOptionsBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Suggest Options Route V1 Lab Suggest Options Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/enrich-advanced":{"post":{"tags":["lab"],"summary":"Prompt-aware advanced-field enrichment for the + generation dialog","description":"Return inferred values for the dialog's advanced fields given a\nprompt + modality (e.g. bpm + key for music, camera movement +\nlighting for video, quality tier for image, tone + length for\ndocuments).\n\nBest-effort: returns ``{\"enriched\": {}}`` on provider failure so the\nUI degrades silently and keeps its existing defaults.","operationId":"enrich_advanced_route_v1_lab_enrich_advanced_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichAdvancedBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Enrich Advanced Route V1 Lab Enrich Advanced Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/scene-decompose":{"post":{"tags":["lab"],"summary":"Split one movie prompt into N consecutive scene prompts","description":"Used by the scene composer's 'Auto-decompose from main prompt'\nbutton. Returns up to ``scene_count`` scene objects. Best-effort —\nreturns an empty array on provider failure.","operationId":"scene_decompose_route_v1_lab_scene_decompose_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SceneDecomposeBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Scene Decompose Route V1 Lab Scene Decompose Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/video-decompose":{"post":{"tags":["lab"],"summary":"Decompose a user-uploaded video into narrative scenes","description":"Used by the Video Editor's auto-decompose CTA. Reads the bytes\nof an uploaded attachment, runs ffmpeg shot detection + Gemini\nVision narrative labeling, returns the scene list.","operationId":"video_decompose_route_v1_lab_video_decompose_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoDecomposeBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Video Decompose Route V1 Lab Video Decompose Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/voice-preview":{"get":{"tags":["lab"],"summary":"Stream a short Gemini Live TTS sample for the voice picker","description":"Synthesize a fixed 'Welcome to my channel' sample in the given\nvoice preset and return it inline as audio/mpeg. The Video Editor's\nVoicePresetPicker hits this to preview before committing.","operationId":"voice_preview_route_v1_lab_voice_preview_get","parameters":[{"name":"preset","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"title":"Preset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/synth-preview":{"post":{"tags":["lab"],"summary":"Speak the user's prompt aloud before submit (one-shot WAV)","description":"Synthesise ``text`` via Gemini Live native audio and return a WAV\nblob inline. The admin Lab's GenerationPromptBar speaker icon hits\nthis so users can pre-listen to the prompt the model will see.\n\nReturns ``audio/wav`` (24 kHz mono 16-bit) — the same shape the\nvoiceover-modality artifact pipeline produces. No caching: the user\ncan tweak the prompt freely and re-fetch.","operationId":"synth_preview_route_v1_lab_synth_preview_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SynthPreviewBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/human-reviews":{"post":{"tags":["lab"],"summary":"Record a human review","description":"Persist a 1–5 reviewer score (or pairwise pick) for a run.","operationId":"record_human_review_v1_lab_human_reviews_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanReviewBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Record Human Review V1 Lab Human Reviews Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["lab"],"summary":"List human reviews (by run or batch)","operationId":"list_human_reviews_v1_lab_human_reviews_get","parameters":[{"name":"run_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id"}},{"name":"batch_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Batch Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Human Reviews V1 Lab Human Reviews Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/feedback":{"post":{"tags":["lab"],"summary":"Record one multi-axis feedback event (comment required)","operationId":"post_feedback_v1_lab_feedback_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackEventBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Feedback V1 Lab Feedback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["lab"],"summary":"List feedback events (filterable)","operationId":"list_feedback_v1_lab_feedback_get","parameters":[{"name":"run_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id"}},{"name":"surface","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Surface"}},{"name":"axis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Axis"}},{"name":"rater_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rater Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Feedback V1 Lab Feedback Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/feedback/aggregate":{"get":{"tags":["lab"],"summary":"Trust-weighted axis means for a run","operationId":"aggregate_feedback_v1_lab_feedback_aggregate_get","parameters":[{"name":"run_id","in":"query","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Aggregate Feedback V1 Lab Feedback Aggregate Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/feedback/pair":{"post":{"tags":["lab"],"summary":"Record one pairwise A/B preference (comment required)","operationId":"post_feedback_pair_v1_lab_feedback_pair_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackPairBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Post Feedback Pair V1 Lab Feedback Pair Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/feedback/correction":{"post":{"tags":["lab"],"summary":"Submit a corrected output (fuels SFT/DPO datasets)","operationId":"post_feedback_correction_v1_lab_feedback_correction_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackCorrectionBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Post Feedback Correction V1 Lab Feedback Correction Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/feedback/proposals":{"get":{"tags":["lab"],"summary":"List feedback proposals (audit trail)","operationId":"list_feedback_proposals_v1_lab_feedback_proposals_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Feedback Proposals V1 Lab Feedback Proposals Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/feedback/proposals/{proposal_id}/force_rollback":{"post":{"tags":["lab"],"summary":"Force-rollback a proposal (break-glass; lab lead only)","operationId":"force_rollback_v1_lab_feedback_proposals__proposal_id__force_rollback_post","parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","title":"Proposal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalRollbackBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Force Rollback V1 Lab Feedback Proposals  Proposal Id  Force Rollback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/feedback/freeze":{"post":{"tags":["lab"],"summary":"Halt all autonomous feedback changes (lab lead only)","operationId":"freeze_feedback_v1_lab_feedback_freeze_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Freeze Feedback V1 Lab Feedback Freeze Post"}}}}}}},"/v1/lab/feedback/unfreeze":{"post":{"tags":["lab"],"summary":"Resume autonomous feedback changes","operationId":"unfreeze_feedback_v1_lab_feedback_unfreeze_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Unfreeze Feedback V1 Lab Feedback Unfreeze Post"}}}}}}},"/v1/lab/feedback/reward-model":{"get":{"tags":["lab"],"summary":"Latest fitted reward-model (Bradley-Terry on feedback_pairs)","operationId":"feedback_reward_model_status_v1_lab_feedback_reward_model_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Feedback Reward Model Status V1 Lab Feedback Reward Model Get"}}}}}}},"/v1/lab/feedback/reward-model/lookup":{"get":{"tags":["lab"],"summary":"Reward-model strength for one run (offline ranking helper)","operationId":"feedback_reward_lookup_v1_lab_feedback_reward_model_lookup_get","parameters":[{"name":"run_id","in":"query","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"version","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Feedback Reward Lookup V1 Lab Feedback Reward Model Lookup Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/feedback/reviewer-stats":{"get":{"tags":["lab"],"summary":"Per-reviewer agreement-κ + activity (last 7 days)","description":"Return the calling reviewer's agreement-vs-gold + activity stats.\n\nUsed by the ``/lab/feedback`` dashboard:\n  * \"My κ\" — Cohen's κ against silently-injected gold-standard\n    items over the past 7 days. Drift < 0.7 ⇒ reviewer is\n    demoted to ``contributor`` and the lead is paged (rule\n    enforced by the autonomous brain, not this endpoint).\n  * \"Last week's volume\" — count of feedback events the reviewer\n    wrote in the window.\n  * Per-axis means — scoring distribution, used to spot a\n    reviewer who hands out 5s on every axis.","operationId":"feedback_reviewer_stats_v1_lab_feedback_reviewer_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Feedback Reviewer Stats V1 Lab Feedback Reviewer Stats Get"}}}}}}},"/v1/lab/feedback/queue":{"get":{"tags":["lab"],"summary":"Recent successful runs with no feedback yet (review queue)","operationId":"feedback_review_queue_v1_lab_feedback_queue_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Feedback Review Queue V1 Lab Feedback Queue Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/signals":{"get":{"tags":["lab"],"summary":"List implicit signals (admin read)","operationId":"list_signals_v1_lab_signals_get","parameters":[{"name":"run_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Signals V1 Lab Signals Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/signals/aggregate":{"get":{"tags":["lab"],"summary":"Implicit-signal counts + raw weighted sum for a run","operationId":"aggregate_signals_v1_lab_signals_aggregate_get","parameters":[{"name":"run_id","in":"query","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Aggregate Signals V1 Lab Signals Aggregate Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/signals/weights":{"get":{"tags":["lab"],"summary":"Calibrated implicit-signal weights","operationId":"list_signal_weights_v1_lab_signals_weights_get","parameters":[{"name":"task","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Signal Weights V1 Lab Signals Weights Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/signals/pause":{"post":{"tags":["lab"],"summary":"Pause implicit signal ingestion (break-glass)","operationId":"pause_signals_v1_lab_signals_pause_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Pause Signals V1 Lab Signals Pause Post"}}}}}}},"/v1/lab/signals/resume":{"post":{"tags":["lab"],"summary":"Resume implicit signal ingestion","operationId":"resume_signals_v1_lab_signals_resume_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Resume Signals V1 Lab Signals Resume Post"}}}}}}},"/v1/lab/music-presets":{"get":{"tags":["lab"],"summary":"List storyboard music library presets","description":"Return the curated music preset catalogue the StoryboardOptions\npicker shows in the 'Library' tab.","operationId":"list_music_presets_v1_lab_music_presets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Music Presets V1 Lab Music Presets Get"}}}}}}},"/v1/lab/runs/{run_id}/timeline":{"get":{"tags":["lab"],"summary":"Observability timeline — chronological agent + model events for one run","description":"Return the per-run agent + model event timeline.\n\nDrains live events when the run is still in-flight, replays from\nthe persisted gzipped JSONL trace otherwise. Each event carries the\nfields the observability pane renders inline (prompt / response\npreviews, token counts, cost, latency); the per-event prompt drill-\nin lives at ``/runs/{run_id}/prompts/{event_id}``.","operationId":"get_run_timeline_v1_lab_runs__run_id__timeline_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Run Timeline V1 Lab Runs  Run Id  Timeline Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/runs/{run_id}/prompts/{event_id}":{"get":{"tags":["lab"],"summary":"Full prompt + response detail for one timeline event","description":"Return the un-truncated prompt + response for ``event_id``.\n\nResolves the event by matching the persisted trace row whose\n``event_id`` (stamped by ``lab_events.publish``) or stable hash\nfallback matches the path param. 404 when no row matches.","operationId":"get_run_prompt_detail_v1_lab_runs__run_id__prompts__event_id__get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Run Prompt Detail V1 Lab Runs  Run Id  Prompts  Event Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/datasets":{"get":{"tags":["lab"],"summary":"List / search datasets","operationId":"list_datasets_v1_lab_datasets_get","parameters":[{"name":"agent_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Type"}},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},{"name":"archived","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"title":"Archived"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Datasets V1 Lab Datasets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["lab"],"summary":"Create a dataset","operationId":"create_dataset_v1_lab_datasets_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDatasetBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Dataset V1 Lab Datasets Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/datasets/{dataset_id}":{"get":{"tags":["lab"],"summary":"Fetch one dataset","operationId":"get_dataset_v1_lab_datasets__dataset_id__get","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Dataset V1 Lab Datasets  Dataset Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["lab"],"summary":"Archive (soft-delete) a dataset","operationId":"delete_dataset_v1_lab_datasets__dataset_id__delete","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Dataset V1 Lab Datasets  Dataset Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/datasets/{dataset_id}/items":{"get":{"tags":["lab"],"summary":"Paginated dataset items","operationId":"list_dataset_items_v1_lab_datasets__dataset_id__items_get","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Dataset Items V1 Lab Datasets  Dataset Id  Items Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["lab"],"summary":"Bulk insert dataset items (JSONL or JSON array)","operationId":"upsert_dataset_items_v1_lab_datasets__dataset_id__items_post","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Upsert Dataset Items V1 Lab Datasets  Dataset Id  Items Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/share-links":{"post":{"tags":["share-links"],"summary":"Mint a public share link for a finished Lab run","description":"Create a 16-byte hex share token that points to ``run_id``.","operationId":"mint_share_link_v1_lab_share_links_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MintShareLinkRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MintShareLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lab/share-links/{token}":{"get":{"tags":["share-links"],"summary":"Fetch share-link metadata (public, no auth)","description":"Public endpoint — no auth. IP rate-limited at 30 req / 60s.","operationId":"get_share_link_v1_lab_share_links__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"password","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Password"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicShareLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["share-links"],"summary":"Revoke a share link (creator-only, soft delete)","operationId":"revoke_share_link_v1_lab_share_links__token__delete","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Share Link V1 Lab Share Links  Token  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/brand-kit":{"get":{"tags":["brand-kit"],"summary":"Fetch the caller's brand kit","operationId":"get_brand_kit_v1_brand_kit_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitResponse"}}}}}},"post":{"tags":["brand-kit"],"summary":"Upsert the caller's brand kit","operationId":"save_brand_kit_v1_brand_kit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitPayload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/account/data":{"delete":{"tags":["account"],"summary":"Cascade-delete all of the caller's user-scoped data (GDPR Article 17).","description":"Wipes the caller's profile, episodic memory, soul, documents, conversation state, federated cache, and any pending tool approvals. Requires a re-authenticated JWT (issued in the last 5 minutes) and an explicit ``confirm=delete-my-data`` query parameter. Idempotent.","operationId":"delete_account_data_v1_account_data_delete","parameters":[{"name":"confirm","in":"query","required":true,"schema":{"type":"string","description":"Must be the literal string \"delete-my-data\".","title":"Confirm"},"description":"Must be the literal string \"delete-my-data\"."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Account Data V1 Account Data Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mcp":{"post":{"tags":["mcp"],"summary":"Mcp Jsonrpc","operationId":"mcp_jsonrpc_mcp_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Mcp Jsonrpc Mcp Post"}}}}}}}},"components":{"schemas":{"ActivitiesResponse":{"properties":{"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"},"count":{"type":"integer","title":"Count"},"activities":{"items":{"$ref":"#/components/schemas/ActivityDTO"},"type":"array","title":"Activities"},"truncated":{"type":"boolean","title":"Truncated","default":false}},"type":"object","required":["count","activities"],"title":"ActivitiesResponse"},"ActivityDTO":{"properties":{"id":{"type":"string","title":"Id"},"ts":{"type":"number","title":"Ts"},"tool":{"type":"string","title":"Tool"},"args_redacted":{"additionalProperties":true,"type":"object","title":"Args Redacted"},"result_summary":{"type":"string","title":"Result Summary"},"citations":{"items":{"type":"string"},"type":"array","title":"Citations"},"latency_ms":{"type":"integer","title":"Latency Ms"},"success":{"type":"boolean","title":"Success"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"reasoning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reasoning"},"risk":{"type":"string","title":"Risk"},"category":{"type":"string","title":"Category"},"recommended_controls":{"items":{"type":"string"},"type":"array","title":"Recommended Controls"}},"type":"object","required":["id","ts","tool","args_redacted","result_summary","citations","latency_ms","success","risk","category","recommended_controls"],"title":"ActivityDTO"},"ActivityModel":{"properties":{"id":{"type":"string","title":"Id"},"ts":{"type":"number","title":"Ts"},"tool":{"type":"string","title":"Tool"},"args_redacted":{"additionalProperties":true,"type":"object","title":"Args Redacted"},"result_summary":{"type":"string","title":"Result Summary"},"citations":{"items":{"type":"string"},"type":"array","title":"Citations"},"latency_ms":{"type":"integer","title":"Latency Ms"},"success":{"type":"boolean","title":"Success"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"reasoning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reasoning"},"risk":{"type":"string","title":"Risk"},"category":{"type":"string","title":"Category"},"recommended_controls":{"items":{"type":"string"},"type":"array","title":"Recommended Controls"}},"type":"object","required":["id","ts","tool","args_redacted","result_summary","citations","latency_ms","success","risk","category","recommended_controls"],"title":"ActivityModel"},"AddPromptVersionBody":{"properties":{"body":{"type":"string","title":"Body"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"additionalProperties":false,"type":"object","required":["body"],"title":"AddPromptVersionBody"},"AnonVoiceSessionRequest":{"properties":{"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language","description":"Initial BCP-47 language hint. Defaults to 'en'."},"device_fingerprint":{"anyOf":[{"type":"string","maxLength":128,"minLength":8},{"type":"null"}],"title":"Device Fingerprint","description":"Stable opaque per-device identifier (FingerprintJS hash, browser cookie, or similar). Combined with the client IP to key rate limits and avoid NAT collisions. Optional — IP-only keying applies a stricter per-hour cap as a CAPTCHA proxy."}},"type":"object","title":"AnonVoiceSessionRequest","description":"Marketing-site / unauthed client requesting a short voice session.\n\nCapped at ``voice_anon_max_seconds`` (default 90s) via the LiveKit\naccess-token TTL. Rate-limited per (IP, device_fingerprint) — pure IP\nkeying collided behind NATs and corporate proxies, so the website\nclient SHOULD include a stable browser fingerprint to keep per-user\nquotas distinct."},"ArchitectureResponse":{"properties":{"format":{"type":"string","title":"Format","default":"markdown"},"sections":{"items":{"$ref":"#/components/schemas/ArchitectureSection"},"type":"array","title":"Sections"},"raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raw","description":"Full markdown document concatenated. Only present when ?include_raw=true."}},"type":"object","required":["sections"],"title":"ArchitectureResponse"},"ArchitectureSection":{"properties":{"title":{"type":"string","title":"Title"},"body":{"type":"string","title":"Body"}},"type":"object","required":["title","body"],"title":"ArchitectureSection"},"AssistantSignalAckBody":{"properties":{"request_id":{"type":"string","maxLength":128,"minLength":1,"title":"Request Id"},"user_id":{"type":"string","maxLength":128,"minLength":1,"title":"User Id"},"rows":{"items":{"$ref":"#/components/schemas/SignedRow"},"type":"array","title":"Rows"},"safe_columns_version":{"type":"integer","title":"Safe Columns Version","default":2},"nonce":{"type":"string","maxLength":128,"minLength":8,"title":"Nonce"},"timestamp_unix":{"type":"integer","title":"Timestamp Unix"},"sig":{"type":"string","maxLength":256,"minLength":1,"title":"Sig"}},"type":"object","required":["request_id","user_id","nonce","timestamp_unix","sig"],"title":"AssistantSignalAckBody","description":"Payload shape the device POSTs.\n\nThe ``sig`` is HMAC-SHA256 over the canonical JSON of THIS body with\n``sig`` set to the empty string and keys sorted alphabetically. The\n``user_id`` MUST match the caller's authenticated user_id."},"AudioAsset":{"properties":{"mime":{"type":"string","title":"Mime"},"b64":{"type":"string","title":"B64"},"size_bytes":{"type":"integer","title":"Size Bytes"}},"type":"object","required":["mime","b64","size_bytes"],"title":"AudioAsset"},"Body_create_variation_v1_lab_runs__run_id__variations_post":{"properties":{"body":{"$ref":"#/components/schemas/VariationRequest"},"payload":{"$ref":"#/components/schemas/CreateRunRequest"}},"type":"object","required":["body","payload"],"title":"Body_create_variation_v1_lab_runs__run_id__variations_post"},"Body_creation_run_rescore_v1_creation_runs__run_id__music_post":{"properties":{"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt"}},"type":"object","title":"Body_creation_run_rescore_v1_creation_runs__run_id__music_post"},"Body_creation_scene_regenerate_v1_creation_runs__run_id__scenes__scene_index__regenerate_post":{"properties":{"instruction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instruction"}},"type":"object","title":"Body_creation_scene_regenerate_v1_creation_runs__run_id__scenes__scene_index__regenerate_post"},"Body_transcribe_audio_v1_inputs_transcribe_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"mime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mime"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"driver_id":{"type":"string","title":"Driver Id","default":"google/gemini-3.5-flash"}},"type":"object","required":["file"],"title":"Body_transcribe_audio_v1_inputs_transcribe_post"},"Body_upload_attachment_v1_attachments_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_attachment_v1_attachments_post"},"BrandKitPayload":{"properties":{"logo_attachment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Attachment Id","description":"Attachment id returned by POST /v1/attachments; null clears."},"colors":{"items":{"type":"string"},"type":"array","title":"Colors","description":"1-3 brand colors as '#RRGGBB' hex strings."},"vibe_sentence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vibe Sentence","description":"One-sentence brand vibe (≤240 chars)."},"voice_preset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice Preset","description":"Gemini Live TTS voice preset id (e.g. 'Sulafat')."},"font_attachment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Font Attachment Id","description":"Attachment id of an uploaded font file (.woff2 / .ttf / .otf); null clears."}},"additionalProperties":false,"type":"object","title":"BrandKitPayload"},"BrandKitResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"logo_attachment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Attachment Id"},"colors":{"items":{"type":"string"},"type":"array","title":"Colors","default":[]},"vibe_sentence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vibe Sentence"},"voice_preset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice Preset"},"font_attachment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Font Attachment Id"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["user_id"],"title":"BrandKitResponse"},"CapabilityListResponse":{"properties":{"count":{"type":"integer","title":"Count"},"capabilities":{"items":{"$ref":"#/components/schemas/CapabilityModel"},"type":"array","title":"Capabilities"}},"type":"object","required":["count","capabilities"],"title":"CapabilityListResponse"},"CapabilityModel":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"notes":{"type":"string","title":"Notes"},"drivers":{"items":{"type":"string"},"type":"array","title":"Drivers","description":"Driver ids that offer this capability."}},"type":"object","required":["id","label","notes","drivers"],"title":"CapabilityModel"},"CascadeResponse":{"properties":{"task":{"type":"string","title":"Task"},"cascades":{"items":{"$ref":"#/components/schemas/TierCascade"},"type":"array","title":"Cascades"}},"type":"object","required":["task","cascades"],"title":"CascadeResponse"},"CompareBatchesBody":{"properties":{"batch_a_id":{"type":"string","title":"Batch A Id"},"batch_b_id":{"type":"string","title":"Batch B Id"}},"additionalProperties":false,"type":"object","required":["batch_a_id","batch_b_id"],"title":"CompareBatchesBody"},"CreateDatasetBody":{"properties":{"agent_type":{"type":"string","title":"Agent Type"},"name":{"type":"string","title":"Name"},"kind":{"type":"string","title":"Kind"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"items":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Items"}},"additionalProperties":false,"type":"object","required":["agent_type","name","kind"],"title":"CreateDatasetBody"},"CreatePromptBody":{"properties":{"name":{"type":"string","title":"Name"},"agent_type":{"type":"string","title":"Agent Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"additionalProperties":false,"type":"object","required":["name","agent_type"],"title":"CreatePromptBody"},"CreateRunRequest":{"properties":{"agent_type":{"type":"string","enum":["text","voice","music","video","image","document","video_edit","audio","video_quick","photo_generate","photo_product","photo_restore","music_studio","music_video_from_studio"],"title":"Agent Type","description":"One of 'text','voice','music','video','video_quick','image','document','video_edit','audio','photo_generate','photo_product','photo_restore','music_studio'."},"input":{"title":"Input","description":"Per-modality input. For 'text' agents this is a string or an object with a 'user_text'/'text'/'message'/'prompt' key."},"config":{"anyOf":[{"$ref":"#/components/schemas/RunConfig"},{"type":"null"}]},"dataset_item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Item Id"},"parent_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Run Id"},"wait":{"type":"boolean","title":"Wait","default":true}},"additionalProperties":false,"type":"object","required":["agent_type","input"],"title":"CreateRunRequest"},"CreateRunResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"stream_url":{"type":"string","title":"Stream Url"},"status":{"type":"string","enum":["succeeded","failed","running"],"title":"Status"},"workflow_version":{"type":"string","title":"Workflow Version"},"answer_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Answer Text"},"winning_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Winning Provider"},"final":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Final"}},"type":"object","required":["run_id","stream_url","status","workflow_version"],"title":"CreateRunResponse"},"CreationAnswer":{"properties":{"q_id":{"type":"string","title":"Q Id"},"selected":{"items":{"type":"string"},"type":"array","title":"Selected","description":"Selected option ids (multi-select allowed)."},"freeform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Freeform","description":"Free text when the user picked \"Other\"."}},"additionalProperties":false,"type":"object","required":["q_id"],"title":"CreationAnswer","description":"The device's answer to one :class:`CreationQuestion`."},"CreationAsset":{"properties":{"kind":{"$ref":"#/components/schemas/CreationAssetKind"},"ref":{"type":"string","title":"Ref","description":"Opaque reference: an uploaded attachment id, a Vikii asset id, or an https URL."},"mime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mime","description":"Best-effort MIME hint."},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Display name, if known."},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","description":"What this source feeds (1.4): start_frame | end_frame | product_keyframe | style_ref | source_doc | source_audio | inspiration_url. Free string for forward-compat; None = generic."}},"additionalProperties":false,"type":"object","required":["kind","ref"],"title":"CreationAsset","description":"One optional input the device attached (Section 1 — Assets)."},"CreationAssetKind":{"type":"string","enum":["image","video","document","audio","url","vikii_asset"],"title":"CreationAssetKind","description":"How an attached asset feeds the creation. APPEND-ONLY."},"CreationBlock":{"properties":{"mode":{"$ref":"#/components/schemas/CreationMode"},"objective":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Objective","description":"One line: what success looks like. May be empty pre-loop."},"basic":{"additionalProperties":true,"type":"object","title":"Basic","description":"Mode-specific basic fields (<=6) — mirrors types.ts state shapes."},"advanced":{"additionalProperties":true,"type":"object","title":"Advanced","description":"Mode-specific advanced/technical controls (hidden by default)."},"creative_direction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creative Direction","description":"Single freeform creative line, e.g. \"make this feel cinematic\"."},"assets":{"items":{"$ref":"#/components/schemas/CreationAsset"},"type":"array","title":"Assets"},"answers":{"items":{"$ref":"#/components/schemas/CreationAnswer"},"type":"array","title":"Answers","description":"Adaptive-loop answers gathered so far; grows each loop iteration."},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","description":"Last confidence the backend reported (echoed for the device's own gating).","default":0.0}},"additionalProperties":false,"type":"object","required":["mode"],"title":"CreationBlock","description":"The structured intent the device assembles (the \"prompt package\").\n\nThe device never assembles the natural-language prompt — the backend does\nthat (F1). ``basic`` / ``advanced`` are mode-specific projections of the\nexisting mobile generation state shapes (``types.ts``), left open so each\nmode evolves without a schema change here."},"CreationMode":{"type":"string","enum":["ask","image_generate","image_enhance","product_photography","music","video","ask_document","research","presentation","marketing","social","flyer"],"title":"CreationMode","description":"Creation modes surfaced by the launcher.\n\nAPPEND-ONLY. Adding a member is an additive (minor) change; renaming or\nremoving one is breaking and requires a coordinated client rollout. Clients\nmust tolerate a value they don't recognize (render a generic capture form)\nrather than hard-failing — see the module docstring (DX-2)."},"CreationPlanRequest":{"properties":{"creation":{"$ref":"#/components/schemas/CreationBlock"},"surprise_me":{"type":"boolean","title":"Surprise Me","description":"EX2 zero-question path: force ready=true, let the model decide everything.","default":false},"user_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"User Context","description":"What the device knows about the user (country, locale, profile, recent history). The planner tailors its model-authored questions + options to it."}},"additionalProperties":false,"type":"object","required":["creation"],"title":"CreationPlanRequest","description":"Body of ``POST /v1/creation/plan``."},"CreationPlanResponse":{"properties":{"schema_version":{"type":"string","title":"Schema Version","default":"1.4"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence"},"questions":{"items":{"$ref":"#/components/schemas/CreationQuestion"},"type":"array","maxItems":10,"title":"Questions","description":"Ranked batch of the highest-value remaining questions (may be empty when ready)."},"reflect_back":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reflect Back","description":"EX2 one-line \"here's what I'll make\" the device shows before generating."},"missing_dimensions":{"items":{"type":"string"},"type":"array","title":"Missing Dimensions","description":"Context dimensions still unknown (drives the confidence score)."},"ready":{"type":"boolean","title":"Ready","description":"True when confidence>=threshold, surprise_me, or the question cap is hit."}},"additionalProperties":false,"type":"object","required":["confidence","ready"],"title":"CreationPlanResponse","description":"Response of ``POST /v1/creation/plan`` — model-authored loop step."},"CreationQuestion":{"properties":{"q_id":{"type":"string","title":"Q Id","description":"Stable id the answer references."},"prompt":{"type":"string","title":"Prompt","description":"The question text (contextual, never generic)."},"options":{"items":{"$ref":"#/components/schemas/CreationQuestionOption"},"type":"array","maxItems":3,"title":"Options","description":"Up to 3 options. Empty = freeform-only."},"allow_freeform":{"type":"boolean","title":"Allow Freeform","description":"Whether the \"Other\" freeform escape is offered (spec requires it).","default":true},"dimension":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dimension","description":"Which missing-context dimension this question fills. For image intents the planner draws from a fixed catalogue and the device renders canonical options + info content keyed by this string: goal_success, visual_style, subject_focus, audience, platform_usage, mood_emotion, environment_context, brand_identity, quality_level, constraints. An off-catalogue key falls back to a freeform question."},"rank":{"type":"integer","minimum":0.0,"title":"Rank","description":"Lower = ask first. Lets the client reveal the batch progressively.","default":0},"multi":{"type":"boolean","title":"Multi","description":"Multi-select (1.4). False = single-select. Absent on old clients.","default":false}},"additionalProperties":false,"type":"object","required":["q_id","prompt"],"title":"CreationQuestion","description":"A single model-authored adaptive question.\n\nThe model returns a *ranked batch* of these per ``/v1/creation/plan`` call\n(ENG-3) — the client may reveal them progressively but does not round-trip\nper question. ``allow_freeform`` mirrors the spec's mandatory \"Other\" escape."},"CreationQuestionOption":{"properties":{"id":{"type":"string","title":"Id","description":"Stable option id the client echoes back in the answer."},"label":{"type":"string","title":"Label","description":"Human-readable chip label."},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value","description":"Optional machine value if it differs from the label."}},"additionalProperties":false,"type":"object","required":["id","label"],"title":"CreationQuestionOption","description":"One selectable answer to an adaptive question (card/chip)."},"CreationSubmitRequest":{"properties":{"creation":{"$ref":"#/components/schemas/CreationBlock"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id","description":"Existing conversation to thread the generation run into; new one minted if absent."},"user_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"User Context","description":"Same device-known user context as the plan request; tailors the authored prompt."}},"additionalProperties":false,"type":"object","required":["creation"],"title":"CreationSubmitRequest","description":"Body of ``POST /v1/creation/submit``."},"DocRegenRequest":{"properties":{"template_id":{"type":"string","title":"Template Id"},"slot":{"type":"string","title":"Slot"},"slot_kind":{"type":"string","title":"Slot Kind"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role"},"char_hint":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Char Hint"},"bullets":{"type":"boolean","title":"Bullets","default":false},"aspect":{"type":"string","title":"Aspect","default":"4:5"},"brief":{"type":"string","title":"Brief","description":"The user's intent + any current copy for context.","default":""},"locale":{"type":"string","title":"Locale","default":"en"},"user_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"User Context"}},"additionalProperties":false,"type":"object","required":["template_id","slot","slot_kind"],"title":"DocRegenRequest","description":"Body of ``POST /v1/creation/doc/regen`` — refresh a single slot (the\neditor's per-text \"rewrite\" / per-image \"regenerate\")."},"DocRegenResponse":{"properties":{"slot":{"type":"string","title":"Slot"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"image":{"anyOf":[{"$ref":"#/components/schemas/EditableDocImage"},{"type":"null"}]}},"additionalProperties":false,"type":"object","required":["slot"],"title":"DocRegenResponse","description":"Response of ``POST /v1/creation/doc/regen`` — exactly one slot's new value."},"DocumentAudioOverviewBody":{"properties":{"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url"}},"type":"object","title":"DocumentAudioOverviewBody"},"DocumentSearchRequest":{"properties":{"query":{"type":"string","title":"Query"},"doc_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Doc Ids"},"top_k":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Top K","default":5},"tenant_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Scope"},"lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lang"}},"type":"object","required":["query"],"title":"DocumentSearchRequest"},"DocumentSummarizeBody":{"properties":{},"type":"object","title":"DocumentSummarizeBody"},"DocumentUploadRequest":{"properties":{"attachment_id":{"type":"string","title":"Attachment Id"},"title":{"type":"string","title":"Title"},"mime_type":{"type":"string","title":"Mime Type"},"bytes_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bytes Size"},"tenant_scope":{"type":"string","title":"Tenant Scope","default":"customer"},"org_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Id"}},"type":"object","required":["attachment_id","title","mime_type"],"title":"DocumentUploadRequest"},"DriverDetailResponse":{"properties":{"driver":{"$ref":"#/components/schemas/DriverModel"},"probe":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Probe","description":"The raw probe capture under vikii/data/probes/<nick>.json, or null if no probe has been taken yet."},"doc_markdown":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doc Markdown","description":"The per-model RAG markdown card generated from the probe capture."}},"type":"object","required":["driver"],"title":"DriverDetailResponse","description":"Output of ``GET /v1/drivers/{id}`` — adds probe capture + RAG markdown."},"DriverListResponse":{"properties":{"count":{"type":"integer","title":"Count"},"drivers":{"items":{"$ref":"#/components/schemas/DriverModel"},"type":"array","title":"Drivers"},"filters":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Filters","description":"Echo of the filters that were applied."}},"type":"object","required":["count","drivers"],"title":"DriverListResponse","description":"Output of ``GET /v1/drivers``."},"DriverModel":{"properties":{"id":{"type":"string","title":"Id","description":"Canonical Driver id, e.g. 'google/gemini-3-flash'."},"vendor":{"type":"string","title":"Vendor"},"family":{"type":"string","title":"Family"},"name":{"type":"string","title":"Name"},"version":{"type":"string","title":"Version"},"description":{"type":"string","title":"Description","default":""},"capabilities":{"items":{"type":"string"},"type":"array","title":"Capabilities","description":"Capability tags — text.generate, tool.use, stream, vision.read, audio.in, audio.out, live.bidi, embed, image.generate, image.edit, video.generate, music.generate, search.grounded."},"context_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Tokens"},"max_output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Output Tokens"},"embed_dim":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Embed Dim"},"audio_sample_rate_hz":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Audio Sample Rate Hz"},"locality":{"type":"string","title":"Locality"},"transport":{"type":"string","title":"Transport"},"endpoint_template":{"type":"string","title":"Endpoint Template"},"auth_method":{"type":"string","title":"Auth Method"},"auth_secret_key":{"type":"string","title":"Auth Secret Key"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"pricing":{"$ref":"#/components/schemas/PricingModel"},"rate_limits":{"$ref":"#/components/schemas/RateLimitsModel"},"health":{"$ref":"#/components/schemas/HealthSpecModel"},"adapter_dotted_path":{"type":"string","title":"Adapter Dotted Path"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"deprecated":{"type":"boolean","title":"Deprecated"},"probe_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Probe Path"}},"type":"object","required":["id","vendor","family","name","version","capabilities","locality","transport","endpoint_template","auth_method","auth_secret_key","pricing","rate_limits","health","adapter_dotted_path","tags","deprecated"],"title":"DriverModel","description":"A single Driver record — pure static metadata for one model."},"EditableDocImage":{"properties":{"mime":{"type":"string","title":"Mime"},"b64":{"type":"string","title":"B64"}},"additionalProperties":false,"type":"object","required":["mime","b64"],"title":"EditableDocImage","description":"One generated image filling a template image slot (inline bytes)."},"EnrichAdvancedBody":{"properties":{"prompt":{"type":"string","maxLength":4000,"minLength":1,"title":"Prompt"},"modality":{"type":"string","enum":["image","video","music","documents"],"title":"Modality"}},"additionalProperties":false,"type":"object","required":["prompt","modality"],"title":"EnrichAdvancedBody"},"EpisodeDTO":{"properties":{"episode_id":{"type":"integer","title":"Episode Id"},"user_id":{"type":"string","title":"User Id"},"conv_id":{"type":"string","title":"Conv Id"},"turn_id":{"type":"string","title":"Turn Id"},"ts":{"type":"string","title":"Ts"},"summary_text":{"type":"string","title":"Summary Text"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"similarity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Similarity"}},"type":"object","required":["episode_id","user_id","conv_id","turn_id","ts","summary_text","metadata"],"title":"EpisodeDTO"},"EpisodesListResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"count":{"type":"integer","title":"Count"},"episodes":{"items":{"$ref":"#/components/schemas/EpisodeDTO"},"type":"array","title":"Episodes"}},"type":"object","required":["user_id","count","episodes"],"title":"EpisodesListResponse"},"EvalRunConfig":{"properties":{"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"driver_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Driver Id"},"prompt_version_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Version Id"},"workflow_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Version"},"environment_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Mode"},"simulate":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Simulate"}},"additionalProperties":false,"type":"object","title":"EvalRunConfig"},"EvalRunRequest":{"properties":{"agent_type":{"type":"string","title":"Agent Type"},"dataset_id":{"type":"string","title":"Dataset Id"},"config":{"$ref":"#/components/schemas/EvalRunConfig"},"scorers":{"items":{"type":"string"},"type":"array","title":"Scorers"},"concurrency":{"type":"integer","maximum":32.0,"minimum":1.0,"title":"Concurrency","default":8}},"additionalProperties":false,"type":"object","required":["agent_type","dataset_id"],"title":"EvalRunRequest"},"FactDTO":{"properties":{"fact_id":{"type":"integer","title":"Fact Id"},"user_id":{"type":"string","title":"User Id"},"subject":{"type":"string","title":"Subject"},"predicate":{"type":"string","title":"Predicate"},"object":{"type":"string","title":"Object"},"confidence":{"type":"number","title":"Confidence"},"source_conv_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Conv Id"},"first_seen_at":{"type":"string","title":"First Seen At"},"last_seen_at":{"type":"string","title":"Last Seen At"},"hit_count":{"type":"integer","title":"Hit Count"},"forgotten_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Forgotten At"},"superseded_by":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Superseded By"},"decayed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Decayed At"}},"type":"object","required":["fact_id","user_id","subject","predicate","object","confidence","first_seen_at","last_seen_at","hit_count"],"title":"FactDTO"},"FactPatch":{"properties":{"object":{"anyOf":[{"type":"string","maxLength":2000,"minLength":1},{"type":"null"}],"title":"Object"},"confidence":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Confidence"}},"type":"object","title":"FactPatch"},"FactsListResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"count":{"type":"integer","title":"Count"},"facts":{"items":{"$ref":"#/components/schemas/FactDTO"},"type":"array","title":"Facts"}},"type":"object","required":["user_id","count","facts"],"title":"FactsListResponse"},"FeedbackCorrectionBody":{"properties":{"run_id":{"type":"string","title":"Run Id"},"original_output":{"type":"string","title":"Original Output"},"corrected_output":{"type":"string","minLength":1,"title":"Corrected Output"},"edit_kind":{"type":"string","enum":["rewrite","minor_edit","tone_fix","factual_fix","format_fix","safety_fix"],"title":"Edit Kind"},"feedback_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback Id"},"approved_for_training":{"type":"boolean","title":"Approved For Training","default":false}},"additionalProperties":false,"type":"object","required":["run_id","original_output","corrected_output","edit_kind"],"title":"FeedbackCorrectionBody"},"FeedbackEventBody":{"properties":{"run_id":{"type":"string","title":"Run Id"},"axis":{"type":"string","title":"Axis"},"score_type":{"type":"string","enum":["boolean","categorical","likert_1_5","continuous_0_1","preference"],"title":"Score Type"},"score_value":{"additionalProperties":true,"type":"object","title":"Score Value"},"comment":{"type":"string","minLength":1,"title":"Comment"},"step_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Step Id"},"surface":{"type":"string","enum":["lab_playground","eval_batch"],"title":"Surface","default":"lab_playground"},"rubric_version_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rubric Version Id"},"severity":{"type":"string","enum":["low","normal","high","critical"],"title":"Severity","default":"normal"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"calibration_item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Calibration Item Id"}},"additionalProperties":false,"type":"object","required":["run_id","axis","score_type","score_value","comment"],"title":"FeedbackEventBody"},"FeedbackPairBody":{"properties":{"run_a":{"type":"string","title":"Run A"},"run_b":{"type":"string","title":"Run B"},"winner":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Winner"},"axis":{"type":"string","title":"Axis"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence"},"comment":{"type":"string","minLength":1,"title":"Comment"},"swap_presented":{"type":"boolean","title":"Swap Presented"},"feedback_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback Id"}},"additionalProperties":false,"type":"object","required":["run_a","run_b","axis","confidence","comment","swap_presented"],"title":"FeedbackPairBody"},"ForgetMeResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"facts_deleted":{"type":"integer","title":"Facts Deleted"},"episodes_deleted":{"type":"integer","title":"Episodes Deleted"}},"type":"object","required":["user_id","facts_deleted","episodes_deleted"],"title":"ForgetMeResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthSpecModel":{"properties":{"method":{"type":"string","title":"Method"},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path"},"timeout_ms":{"type":"integer","title":"Timeout Ms"}},"type":"object","required":["method","timeout_ms"],"title":"HealthSpecModel"},"HumanReviewBody":{"properties":{"run_id":{"type":"string","title":"Run Id"},"axis":{"type":"string","title":"Axis"},"score_1_to_5":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Score 1 To 5"},"preferred_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Run Id"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"additionalProperties":false,"type":"object","required":["run_id","axis"],"title":"HumanReviewBody"},"IdentityResponse":{"properties":{"name":{"type":"string","title":"Name"},"tagline":{"type":"string","title":"Tagline"},"codename":{"type":"string","title":"Codename"},"version":{"type":"string","title":"Version"},"persona":{"additionalProperties":{"type":"string"},"type":"object","title":"Persona"},"values":{"items":{"type":"string"},"type":"array","title":"Values"},"brand_truths":{"items":{"type":"string"},"type":"array","title":"Brand Truths"},"whoiam":{"anyOf":[{"$ref":"#/components/schemas/WhoiamModel"},{"type":"null"}]}},"type":"object","required":["name","tagline","codename","version","persona","values","brand_truths"],"title":"IdentityResponse"},"ImageAsset":{"properties":{"mime":{"type":"string","title":"Mime"},"b64":{"type":"string","title":"B64"},"size_bytes":{"type":"integer","title":"Size Bytes"},"index":{"type":"integer","title":"Index"}},"type":"object","required":["mime","b64","size_bytes","index"],"title":"ImageAsset"},"ImageGenerateRequest":{"properties":{"prompt":{"type":"string","maxLength":2000,"minLength":1,"title":"Prompt"},"sample_count":{"type":"integer","maximum":4.0,"minimum":1.0,"title":"Sample Count","default":1},"aspect_ratio":{"type":"string","enum":["1:1","9:16","16:9","3:4","4:3","4:5"],"title":"Aspect Ratio","default":"1:1"},"negative_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Negative Prompt"},"tier":{"type":"string","enum":["plus","pro","premium"],"title":"Tier","default":"plus"},"driver_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Driver Id"},"input_image_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Image Id"},"input_image_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Input Image Ids"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"edit_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Edit Mode"},"output_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output Format"},"output_resolution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output Resolution"}},"additionalProperties":false,"type":"object","required":["prompt"],"title":"ImageGenerateRequest"},"ImageGenerateResponse":{"properties":{"driver_id":{"type":"string","title":"Driver Id"},"latency_ms":{"type":"integer","title":"Latency Ms"},"images":{"items":{"$ref":"#/components/schemas/ImageAsset"},"type":"array","title":"Images"}},"type":"object","required":["driver_id","latency_ms","images"],"title":"ImageGenerateResponse"},"JournalEntryResponse":{"properties":{"doc_id":{"type":"string","title":"Doc Id"},"slug":{"type":"string","title":"Slug"},"locale":{"type":"string","title":"Locale"},"source_locale":{"type":"string","title":"Source Locale"},"category":{"type":"string","title":"Category"},"title":{"type":"string","title":"Title"},"summary":{"type":"string","title":"Summary"},"body_md":{"type":"string","title":"Body Md"},"body_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Html"},"published_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published At"},"last_updated":{"type":"string","title":"Last Updated"}},"type":"object","required":["doc_id","slug","locale","source_locale","category","title","summary","body_md","last_updated"],"title":"JournalEntryResponse","description":"One full Journal entry — markdown body + rendered HTML (when cached)."},"JournalEntrySummary":{"properties":{"doc_id":{"type":"string","title":"Doc Id"},"slug":{"type":"string","title":"Slug"},"locale":{"type":"string","title":"Locale"},"category":{"type":"string","title":"Category"},"title":{"type":"string","title":"Title"},"summary":{"type":"string","title":"Summary"},"published_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published At"},"last_updated":{"type":"string","title":"Last Updated"}},"type":"object","required":["doc_id","slug","locale","category","title","summary","last_updated"],"title":"JournalEntrySummary","description":"One row on the Journal index page — no body."},"JournalListResponse":{"properties":{"locale":{"type":"string","title":"Locale"},"count":{"type":"integer","title":"Count"},"entries":{"items":{"$ref":"#/components/schemas/JournalEntrySummary"},"type":"array","title":"Entries"}},"type":"object","required":["locale","count","entries"],"title":"JournalListResponse"},"McpToolListResponse":{"properties":{"count":{"type":"integer","title":"Count"},"transport":{"type":"string","title":"Transport","default":"json-rpc-2.0/http"},"endpoint":{"type":"string","title":"Endpoint","default":"/mcp"},"tools":{"items":{"$ref":"#/components/schemas/McpToolModel"},"type":"array","title":"Tools"}},"type":"object","required":["count","tools"],"title":"McpToolListResponse"},"McpToolModel":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"inputSchema":{"additionalProperties":true,"type":"object","title":"Inputschema"}},"type":"object","required":["name","description","inputSchema"],"title":"McpToolModel"},"MintShareLinkRequest":{"properties":{"run_id":{"type":"string","maxLength":128,"minLength":1,"title":"Run Id"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At","description":"ISO-8601 timestamp. Null/omitted = never expires."},"password":{"anyOf":[{"type":"string","maxLength":256,"minLength":1},{"type":"null"}],"title":"Password","description":"Optional password gate. Hashed at rest via scrypt."}},"additionalProperties":false,"type":"object","required":["run_id"],"title":"MintShareLinkRequest"},"MintShareLinkResponse":{"properties":{"share_token":{"type":"string","title":"Share Token"},"public_url":{"type":"string","title":"Public Url"}},"type":"object","required":["share_token","public_url"],"title":"MintShareLinkResponse"},"ModelOverrides":{"properties":{"driver_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Driver Id"},"temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Temperature"},"max_tokens":{"anyOf":[{"type":"integer","maximum":200000.0,"minimum":1.0},{"type":"null"}],"title":"Max Tokens"},"top_p":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Top P"},"top_k":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Top K"},"response_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Format"},"response_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Response Schema"},"thinking_budget_tokens":{"anyOf":[{"type":"integer","maximum":200000.0,"minimum":0.0},{"type":"null"}],"title":"Thinking Budget Tokens"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed"}},"additionalProperties":false,"type":"object","title":"ModelOverrides","description":"Audit Wave-2 F10 — strict allowlist for the Lab ``model_overrides`` payload.\n\nPreviously declared as ``dict[str, Any] | None``, which let an\nadmin (or anyone who breached an admin session) pass arbitrary\nkeys that the downstream workflow might interpret as prompt /\ntool / system-prompt overrides. The allowlist below is the only\nsafe surface; unknown keys are refused at validate-time."},"MusicGenerateRequest":{"properties":{"prompt":{"type":"string","maxLength":4000,"minLength":1,"title":"Prompt"},"duration_seconds":{"anyOf":[{"type":"integer","maximum":360.0,"minimum":2.0},{"type":"null"}],"title":"Duration Seconds"},"tier":{"type":"string","enum":["plus","pro","premium"],"title":"Tier","default":"plus"},"driver_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Driver Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"output_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output Format"},"sample_rate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sample Rate"},"channels":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Channels"},"bit_depth":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bit Depth"}},"additionalProperties":false,"type":"object","required":["prompt"],"title":"MusicGenerateRequest"},"MusicGenerateResponse":{"properties":{"driver_id":{"type":"string","title":"Driver Id"},"latency_ms":{"type":"integer","title":"Latency Ms"},"audio":{"$ref":"#/components/schemas/AudioAsset"}},"type":"object","required":["driver_id","latency_ms","audio"],"title":"MusicGenerateResponse"},"OrganListResponse":{"properties":{"count":{"type":"integer","title":"Count"},"organs":{"items":{"$ref":"#/components/schemas/OrganModel"},"type":"array","title":"Organs"}},"type":"object","required":["count","organs"],"title":"OrganListResponse"},"OrganModel":{"properties":{"name":{"type":"string","title":"Name"},"nickname":{"type":"string","title":"Nickname"},"responsibility":{"type":"string","title":"Responsibility"},"required_capabilities":{"items":{"type":"string"},"type":"array","title":"Required Capabilities"},"status":{"type":"string","title":"Status","description":"implemented | partially_implemented | not_yet_implemented"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["name","nickname","responsibility","required_capabilities","status"],"title":"OrganModel"},"PlatformToolListResponse":{"properties":{"count":{"type":"integer","title":"Count"},"tools":{"items":{"$ref":"#/components/schemas/PlatformToolModel"},"type":"array","title":"Tools"},"filters":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Filters"}},"type":"object","required":["count","tools"],"title":"PlatformToolListResponse"},"PlatformToolModel":{"properties":{"name":{"type":"string","title":"Name"},"summary":{"type":"string","title":"Summary"},"description":{"type":"string","title":"Description"},"category":{"type":"string","title":"Category"},"risk":{"type":"string","title":"Risk"},"input_schema":{"additionalProperties":true,"type":"object","title":"Input Schema"},"output_schema":{"additionalProperties":true,"type":"object","title":"Output Schema"},"citation_template":{"type":"string","title":"Citation Template"},"backing_service":{"type":"string","title":"Backing Service"},"upstream_path":{"type":"string","title":"Upstream Path"},"upstream_method":{"type":"string","title":"Upstream Method"},"compliance_notes":{"type":"string","title":"Compliance Notes"},"recommended_controls":{"items":{"type":"string"},"type":"array","title":"Recommended Controls"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"requires_confirmation":{"type":"boolean","title":"Requires Confirmation"},"routes_to_human":{"type":"boolean","title":"Routes To Human"}},"type":"object","required":["name","summary","description","category","risk","input_schema","output_schema","citation_template","backing_service","upstream_path","upstream_method","compliance_notes","recommended_controls","tags","requires_confirmation","routes_to_human"],"title":"PlatformToolModel"},"PolicyCascadeEntry":{"properties":{"driver_id":{"type":"string","title":"Driver Id"},"max_output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Output Tokens"}},"type":"object","required":["driver_id"],"title":"PolicyCascadeEntry"},"PolicyEnvelope":{"properties":{"source_path":{"type":"string","title":"Source Path","description":"Filesystem path of the YAML that was loaded."},"yaml":{"type":"string","title":"Yaml","description":"Raw YAML — the source of truth for routing."},"tiers":{"items":{"type":"string"},"type":"array","title":"Tiers"},"tasks":{"items":{"type":"string"},"type":"array","title":"Tasks"}},"type":"object","required":["source_path","yaml","tiers","tasks"],"title":"PolicyEnvelope"},"PricingModel":{"properties":{"in_per_million_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"In Per Million Usd"},"out_per_million_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Out Per Million Usd"},"per_image_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Per Image Usd"},"per_second_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Per Second Usd"},"notes":{"type":"string","title":"Notes","default":""}},"type":"object","title":"PricingModel"},"PromotePromptBody":{"properties":{"target_status":{"type":"string","enum":["experimental","staging","production"],"title":"Target Status"}},"additionalProperties":false,"type":"object","required":["target_status"],"title":"PromotePromptBody"},"ProposalRollbackBody":{"properties":{"reason":{"type":"string","minLength":1,"title":"Reason"}},"additionalProperties":false,"type":"object","required":["reason"],"title":"ProposalRollbackBody"},"PublicShareLinkResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"artifact_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Uri"},"modality":{"type":"string","title":"Modality"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt"},"created_at":{"type":"string","title":"Created At"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"view_count":{"type":"integer","title":"View Count"}},"type":"object","required":["run_id","artifact_uri","modality","prompt","created_at","expires_at","view_count"],"title":"PublicShareLinkResponse"},"PushTokenRequest":{"properties":{"token":{"type":"string","maxLength":512,"minLength":1,"title":"Token","description":"Expo push token (ExponentPushToken[...])."},"platform":{"type":"string","maxLength":32,"title":"Platform","description":"ios | android | web","default":"unknown"},"provider":{"type":"string","maxLength":32,"title":"Provider","description":"expo | fcm","default":"expo"}},"additionalProperties":false,"type":"object","required":["token"],"title":"PushTokenRequest"},"RateLimitsModel":{"properties":{"rpm":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rpm"},"tpm":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tpm"},"rpd":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rpd"},"concurrency":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Concurrency"}},"type":"object","title":"RateLimitsModel"},"ReleaseGateRequest":{"properties":{"scope":{"type":"string","title":"Scope"},"candidate_batch_id":{"type":"string","title":"Candidate Batch Id"},"baseline_batch_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Baseline Batch Id"},"require_human_review_pass":{"type":"boolean","title":"Require Human Review Pass","default":false},"decision_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Decision By"}},"additionalProperties":false,"type":"object","required":["scope","candidate_batch_id"],"title":"ReleaseGateRequest"},"ResumeRunResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"resumed_from_stage":{"type":"string","title":"Resumed From Stage"},"status":{"type":"string","enum":["resumed","no_checkpoint","already_complete","auth_error"],"title":"Status"},"stream_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stream Url"}},"type":"object","required":["run_id","resumed_from_stage","status"],"title":"ResumeRunResponse","description":"Response shape for POST /v1/lab/runs/{run_id}/resume."},"RunConfig":{"properties":{"tier":{"type":"string","enum":["anon","free","plus","pro","premium"],"title":"Tier","default":"pro"},"environment_mode":{"type":"string","enum":["local","cloud","hybrid","offline_forced","cloud_failure_simulated"],"title":"Environment Mode","default":"cloud"},"workflow_version":{"type":"string","title":"Workflow Version","default":"lab/wave1"},"prompt_version_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Version Id"},"model_overrides":{"anyOf":[{"$ref":"#/components/schemas/ModelOverrides"},{"type":"null"}]},"simulate":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Simulate"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id","description":"LangGraph thread id; auto-minted per run if blank."},"locale":{"type":"string","title":"Locale","default":"en"},"allowed_tools":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Tools"}},"type":"object","title":"RunConfig","description":"Per-run configuration. Mirrors the §3.4 ``POST /v1/lab/runs`` body.\n\nKept Pydantic so the route handler can ``RunConfig.model_validate``\ndirectly and pass it through. ``extra='ignore'`` because the Wave 3\nadmin Lab UI ships a richer config surface (driver_id, agent_mode,\nretrieval_mode, memory_mode, temperature, max_tokens, response_format,\nresponse_schema, tools) than the backend wires today — unknown fields\nare dropped silently so the UI doesn't 422 on every send.\nServer-side handling for the dropped fields can be added incrementally."},"RunDetailResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"agent_type":{"type":"string","title":"Agent Type"},"tier":{"type":"string","title":"Tier"},"environment_mode":{"type":"string","title":"Environment Mode"},"workflow_version":{"type":"string","title":"Workflow Version"},"status":{"type":"string","title":"Status"},"input_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Summary"},"total_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Latency Ms"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd"},"s3_trace_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"S3 Trace Uri"},"s3_artifact_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"S3 Artifact Uri"},"pass_fail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pass Fail"},"pass_fail_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pass Fail Reason"},"tool_calls":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Tool Calls","default":[]},"benchmarks":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Benchmarks","default":[]}},"type":"object","required":["run_id","agent_type","tier","environment_mode","workflow_version","status"],"title":"RunDetailResponse"},"SceneDecomposeBody":{"properties":{"prompt":{"type":"string","maxLength":4000,"minLength":1,"title":"Prompt"},"scene_count":{"type":"integer","maximum":8.0,"minimum":2.0,"title":"Scene Count","default":4}},"additionalProperties":false,"type":"object","required":["prompt"],"title":"SceneDecomposeBody"},"SignedRow":{"properties":{"table":{"type":"string","title":"Table"},"row_id":{"type":"string","title":"Row Id","default":""},"fields":{"additionalProperties":true,"type":"object","title":"Fields"}},"type":"object","required":["table"],"title":"SignedRow"},"StudioRunRequest":{"properties":{"agent_type":{"type":"string","title":"Agent Type"},"input":{"title":"Input"},"config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Config"},"parent_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Run Id"}},"additionalProperties":false,"type":"object","required":["agent_type","input"],"title":"StudioRunRequest","description":"Body for ``POST /v1/studio/runs``.\n\nMirrors the admin ``CreateRunRequest`` but trimmed to the user-facing\nsurface: no ``dataset_item_id`` (admin datasets), no ``wait`` toggle\n(always synchronous submit). ``config`` is accepted as a free dict and\nvalidated into a :class:`RunConfig` server-side so we can force the\ntier before execution."},"StudioRunResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"status":{"type":"string","enum":["succeeded","failed","running"],"title":"Status"},"answer_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Answer Text"},"winning_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Winning Provider"},"final":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Final"}},"type":"object","required":["run_id","status"],"title":"StudioRunResponse"},"SuggestOptionsBody":{"properties":{"prompt":{"type":"string","maxLength":4000,"minLength":1,"title":"Prompt"},"modality":{"type":"string","enum":["image","video","music","documents"],"title":"Modality"}},"additionalProperties":false,"type":"object","required":["prompt","modality"],"title":"SuggestOptionsBody"},"SynthPreviewBody":{"properties":{"text":{"type":"string","maxLength":500,"minLength":1,"title":"Text","description":"Text to speak aloud. Capped at 500 chars to keep the synth round-trip snappy and to prevent abuse."},"voice_preset":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Voice Preset","description":"Gemini Live TTS voice preset id (e.g. 'Sulafat'). Defaults to the batch_tts module default when omitted."}},"additionalProperties":false,"type":"object","required":["text"],"title":"SynthPreviewBody","description":"Request body for ``POST /v1/lab/synth-preview``.\n\nReuses the Live TTS batch pipeline (:func:`batch_tts.synth_voiceover`)\nto let the user hear what their prompt sounds like BEFORE submitting\na generation. Accessibility + double-check value."},"TierCascade":{"properties":{"tier":{"type":"string","title":"Tier"},"chain":{"items":{"$ref":"#/components/schemas/PolicyCascadeEntry"},"type":"array","title":"Chain"}},"type":"object","required":["tier","chain"],"title":"TierCascade"},"ToolInvokeRequest":{"properties":{"arguments":{"additionalProperties":true,"type":"object","title":"Arguments"},"reasoning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reasoning","description":"Why Viki is calling this — appears verbatim on the audit row."},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Optional pre-existing session id; one is auto-generated otherwise."},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id","description":"Caller user id. Only the playground / dev surface accepts this — production callers' identity is taken from the JWT."},"auth_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auth Token","description":"User Bearer JWT — forwarded to downstream Victoi services as `Authorization: Bearer …`. Required for any tool that calls core-api / market-data / payments. Never logged."}},"type":"object","title":"ToolInvokeRequest"},"ToolInvokeResponse":{"properties":{"tool":{"type":"string","title":"Tool"},"success":{"type":"boolean","title":"Success"},"summary":{"type":"string","title":"Summary"},"data":{"additionalProperties":true,"type":"object","title":"Data"},"citations":{"items":{"type":"string"},"type":"array","title":"Citations"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"provider":{"type":"string","title":"Provider"},"activity":{"$ref":"#/components/schemas/ActivityModel"},"session_id":{"type":"string","title":"Session Id"}},"type":"object","required":["tool","success","summary","data","citations","provider","activity","session_id"],"title":"ToolInvokeResponse"},"TranscribeResponse":{"properties":{"text":{"type":"string","title":"Text"},"latency_ms":{"type":"integer","title":"Latency Ms"},"audio_bytes_in":{"type":"integer","title":"Audio Bytes In"},"mime":{"type":"string","title":"Mime"},"driver_id":{"type":"string","title":"Driver Id"}},"type":"object","required":["text","latency_ms","audio_bytes_in","mime","driver_id"],"title":"TranscribeResponse"},"UpsertCascadeBody":{"properties":{"task_kind":{"type":"string","title":"Task Kind"},"tier":{"type":"string","title":"Tier"},"ordered_driver_ids":{"items":{"type":"string"},"type":"array","title":"Ordered Driver Ids"},"status":{"type":"string","title":"Status","default":"draft"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"additionalProperties":false,"type":"object","required":["task_kind","tier","ordered_driver_ids"],"title":"UpsertCascadeBody"},"UpsertDriverBody":{"properties":{"driver_id":{"type":"string","title":"Driver Id"},"vendor":{"type":"string","title":"Vendor"},"family":{"type":"string","title":"Family"},"status":{"type":"string","title":"Status","default":"draft"},"capabilities":{"items":{"type":"string"},"type":"array","title":"Capabilities","default":[]},"cost_in_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost In Per Million"},"cost_out_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Out Per Million"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","default":[]},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","default":{}},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"additionalProperties":false,"type":"object","required":["driver_id","vendor","family"],"title":"UpsertDriverBody"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VariationRequest":{"properties":{"style_preset":{"type":"string","maxLength":80,"title":"Style Preset","description":"Style preset name to apply (e.g. 'Cinematic', 'Documentary', 'Music Video', 'Vintage Film', 'B&W Noir', 'Cyberpunk', 'Anime', 'Pastel Animation', 'Hyperreal')."},"color_preset":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Color Preset","description":"Optional color grade override."}},"type":"object","required":["style_preset"],"title":"VariationRequest","description":"Body for POST /v1/lab/runs/{run_id}/variations."},"VariationResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"parent_run_id":{"type":"string","title":"Parent Run Id"},"style_preset":{"type":"string","title":"Style Preset"},"stream_url":{"type":"string","title":"Stream Url"},"status":{"type":"string","enum":["queued","failed_auth","parent_not_found"],"title":"Status"}},"type":"object","required":["run_id","parent_run_id","style_preset","stream_url","status"],"title":"VariationResponse"},"VideoAsset":{"properties":{"mime":{"type":"string","title":"Mime"},"b64":{"type":"string","title":"B64"},"size_bytes":{"type":"integer","title":"Size Bytes"}},"type":"object","required":["mime","b64","size_bytes"],"title":"VideoAsset"},"VideoDecomposeBody":{"properties":{"attachment_id":{"type":"string","maxLength":128,"minLength":1,"title":"Attachment Id"},"target_scene_count":{"anyOf":[{"type":"integer","maximum":24.0,"minimum":1.0},{"type":"null"}],"title":"Target Scene Count"}},"additionalProperties":false,"type":"object","required":["attachment_id"],"title":"VideoDecomposeBody"},"VideoGenerateRequest":{"properties":{"prompt":{"type":"string","maxLength":4000,"minLength":1,"title":"Prompt"},"duration_seconds":{"type":"integer","maximum":20.0,"minimum":2.0,"title":"Duration Seconds","default":8},"aspect_ratio":{"type":"string","enum":["16:9","9:16","1:1"],"title":"Aspect Ratio","default":"16:9"},"poll_timeout_sec":{"type":"integer","maximum":900.0,"minimum":30.0,"title":"Poll Timeout Sec","default":300},"tier":{"type":"string","enum":["plus","pro","premium"],"title":"Tier","default":"plus"},"driver_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Driver Id"},"input_image_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Image Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"negative_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Negative Prompt"},"generate_audio":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Generate Audio"}},"additionalProperties":false,"type":"object","required":["prompt"],"title":"VideoGenerateRequest"},"VideoGenerateResponse":{"properties":{"driver_id":{"type":"string","title":"Driver Id"},"latency_ms":{"type":"integer","title":"Latency Ms"},"video":{"$ref":"#/components/schemas/VideoAsset"}},"type":"object","required":["driver_id","latency_ms","video"],"title":"VideoGenerateResponse"},"VoiceCapabilitiesResponse":{"properties":{"counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Counts","description":"Coverage stats — total, gemma_text, cloud_stt, cloud_tts, chirp_hd, full_voice."},"default_voice_id":{"type":"string","title":"Default Voice Id","description":"Chirp 3 HD voice ID used unless an override is provided."},"languages":{"items":{"$ref":"#/components/schemas/VoiceCapabilityLanguage"},"type":"array","title":"Languages"}},"type":"object","required":["counts","default_voice_id","languages"],"title":"VoiceCapabilitiesResponse","description":"Capabilities matrix exposed to clients.\n\nMobile / web fallback paths use this to drive their language picker\nand on-device TTS voice selection. The canonical data lives in\n:mod:`vikii.content.languages`; this endpoint is a thin projection."},"VoiceCapabilityLanguage":{"properties":{"code":{"type":"string","title":"Code","description":"ISO 639-1 (or 639-3 if no 639-1) base code."},"code_iso639_3":{"type":"string","title":"Code Iso639 3"},"name_en":{"type":"string","title":"Name En"},"name_native":{"type":"string","title":"Name Native"},"script":{"type":"string","title":"Script","description":"ISO 15924 script code (Latn, Cyrl, ...)."},"rtl":{"type":"boolean","title":"Rtl"},"family":{"type":"string","title":"Family"},"gemma_text":{"type":"string","title":"Gemma Text","description":"\"primary\" | \"secondary\" | \"no\"."},"cloud_stt_locale":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Stt Locale","description":"BCP-47 locale for Cloud Speech-to-Text v2 (null if unsupported)."},"cloud_tts_locale":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Tts Locale","description":"BCP-47 locale for Cloud Text-to-Speech (null if unsupported)."},"chirp_hd":{"type":"boolean","title":"Chirp Hd","description":"True if Chirp 3 HD voices render this language with native prosody."},"has_voice_full":{"type":"boolean","title":"Has Voice Full","description":"STT + TTS + Chirp HD — the gold-standard voice loop."}},"type":"object","required":["code","code_iso639_3","name_en","name_native","script","rtl","family","gemma_text","cloud_stt_locale","cloud_tts_locale","chirp_hd","has_voice_full"],"title":"VoiceCapabilityLanguage","description":"One language row in the voice capabilities matrix."},"VoiceSessionResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"room_name":{"type":"string","title":"Room Name"},"livekit_url":{"type":"string","title":"Livekit Url","description":"WebSocket URL of the LiveKit instance to connect to."},"access_token":{"type":"string","title":"Access Token","description":"LiveKit JWT room-access token. TTL ≤ session lifetime."},"expires_at":{"type":"integer","title":"Expires At","description":"Unix seconds — access_token expiry."},"is_anon":{"type":"boolean","title":"Is Anon","default":false},"session_token":{"type":"string","title":"Session Token","description":"Downgraded voice-session JWT (scope: ``vikii-voice-session``, bound to ``session_id``). Send as ``Authorization: Bearer`` or ``X-Vikii-Voice-Session-Token`` on side-channel writes like ``/v1/voice/sessions/{id}/vision-frame``.","default":""}},"type":"object","required":["session_id","room_name","livekit_url","access_token","expires_at"],"title":"VoiceSessionResponse","description":"LiveKit room handle the client uses to join the voice session."},"VoiceSessionStartRequest":{"properties":{"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language","description":"Initial BCP-47 language hint (e.g. 'en' or 'en-US'). Voice STT auto-detects on the fly; this just primes the worker's first system prompt."},"voice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice Id","description":"Optional Chirp 3 HD voice override (default: Sulafat — warm female)."},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id","description":"Optional existing conversation id to continue context across surfaces."},"user_profile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"User Profile","description":"Optional device profile snapshot — same shape as the chat surface's user_profile (first_name / display_name / account_type / language). Lets Viki address the user by name on voice. The server keeps only low-sensitivity display fields (name / account_type); email and any financial PII are stripped before anything reaches the model or the spoken layer."},"client_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Client Context","description":"Optional live screen scope — same shape as the chat surface's client_context (current_screen + screen.id / title / allowed_actions / context). Folded into the prompt as the [screen] block and used for the per-screen imperative-action gate. Seeds the session; the device refreshes it per-turn over the LiveKit data channel via a {kind:'client.context'} message so it tracks navigation during the call."}},"type":"object","title":"VoiceSessionStartRequest","description":"Authed mobile/desktop client requesting a voice session."},"VoiceSimulateOptions":{"properties":{"cloud_latency_ms":{"anyOf":[{"type":"integer","maximum":60000.0,"minimum":0.0},{"type":"null"}],"title":"Cloud Latency Ms","description":"Delay before the server response begins streaming back."},"cloud_failure_after_ms":{"anyOf":[{"type":"integer","maximum":60000.0,"minimum":0.0},{"type":"null"}],"title":"Cloud Failure After Ms","description":"Simulate a cloud outage at this offset (ms). The device's local llama.cpp fallback takes over."},"bridge_emitted":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Bridge Emitted","description":"True iff the device spoke a bridge utterance via on-device llama.cpp + Piper before the server response arrived."},"barge_in_at_offset_ms":{"anyOf":[{"type":"integer","maximum":60000.0,"minimum":0.0},{"type":"null"}],"title":"Barge In At Offset Ms","description":"Simulate the user starting a new turn at this offset."},"fallback_threshold_ms":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":200.0},{"type":"null"}],"title":"Fallback Threshold Ms","description":"Override the device's bridge-fire timer (default 800ms)."},"cloud_dead_threshold_ms":{"anyOf":[{"type":"integer","maximum":30000.0,"minimum":2000.0},{"type":"null"}],"title":"Cloud Dead Threshold Ms","description":"Override the device's give-up timer (default 6000ms)."}},"additionalProperties":false,"type":"object","title":"VoiceSimulateOptions","description":"Knobs the lab simulator applies to the synthetic timeline.\n\nMirrors plan §6.4. All fields are optional — an empty options block\nyields a \"happy path\" timeline (no bridge, no failures)."},"VoiceSimulateRequest":{"properties":{"transcript":{"type":"string","maxLength":8000,"minLength":1,"title":"Transcript"},"lang":{"type":"string","title":"Lang","description":"ISO 639-1 / regional variant.","default":"en"},"tier":{"type":"string","enum":["anon","free","plus","pro","premium"],"title":"Tier","default":"pro"},"simulate":{"anyOf":[{"$ref":"#/components/schemas/VoiceSimulateOptions"},{"type":"null"}]},"dataset_item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Item Id"},"parent_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Run Id"}},"additionalProperties":false,"type":"object","required":["transcript"],"title":"VoiceSimulateRequest","description":"Body of ``POST /v1/lab/voice/simulate``.\n\nThe simulator NEVER touches real audio — ``transcript`` is the\nalready-transcribed user utterance the device would have produced.\nThe privacy CI gate at ``tests/integration/test_no_audio_leaks.py``\nis the load-bearing guardrail; this route stays clean by design."},"WhoiamModel":{"properties":{"version":{"anyOf":[{"type":"integer"},{"type":"string"},{"type":"null"}],"title":"Version"},"last_updated":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Updated"},"source_of_truth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Of Truth"},"founder":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Founder"},"mission_one_liner":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mission One Liner"},"prompt":{"type":"string","title":"Prompt"}},"type":"object","required":["prompt"],"title":"WhoiamModel","description":"Whoiam metadata + rendered prompt. Mirrors the WHOIAM.md\nfront-matter atoms and exposes the full always-on identity prompt\nso introspection clients (admin panel, MCP inspector) can audit\nwhat Viki is loading on every turn."},"_AppendTurnBody":{"properties":{"role":{"type":"string","enum":["user","assistant","tool"],"title":"Role"},"content":{"type":"string","maxLength":64000,"minLength":1,"title":"Content"}},"type":"object","required":["role","content"],"title":"_AppendTurnBody"},"_CreateRoomBody":{"properties":{"modality":{"type":"string","title":"Modality","description":"chat | document | photo | video | music | image_gen | link"},"title":{"type":"string","maxLength":200,"minLength":1,"title":"Title"},"primary_attachment_uri":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Primary Attachment Uri"}},"type":"object","required":["modality","title"],"title":"_CreateRoomBody"},"_RoomDetailOut":{"properties":{"id":{"type":"string","title":"Id"},"modality":{"type":"string","title":"Modality"},"title":{"type":"string","title":"Title"},"primary_attachment_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Attachment Uri"},"created_at":{"type":"string","title":"Created At"},"last_active_at":{"type":"string","title":"Last Active At"},"status":{"type":"string","title":"Status"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"recent_turns":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Recent Turns"}},"type":"object","required":["id","modality","title","primary_attachment_uri","created_at","last_active_at","status","summary","recent_turns"],"title":"_RoomDetailOut"},"_RoomOut":{"properties":{"id":{"type":"string","title":"Id"},"modality":{"type":"string","title":"Modality"},"title":{"type":"string","title":"Title"},"primary_attachment_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Attachment Uri"},"created_at":{"type":"string","title":"Created At"},"last_active_at":{"type":"string","title":"Last Active At"},"status":{"type":"string","title":"Status"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"}},"type":"object","required":["id","modality","title","primary_attachment_uri","created_at","last_active_at","status","summary"],"title":"_RoomOut"}}},"tags":[{"name":"drivers","description":"Model catalogue — every Driver Viki can reach. Each entry is backed by a live wire-format probe."},{"name":"catalogue","description":"Platform blueprint — capabilities, organs, identity, architecture."},{"name":"mcp","description":"MCP server — tool catalogue + JSON-RPC endpoint."},{"name":"actuator","description":"Liveness / readiness / metrics — Spring-Boot-shaped probe paths."},{"name":"nervous-system","description":"Intent classification, identity selection, task planning, voice transcribe — the entry pipeline."},{"name":"hands","description":"Platform tool catalogue (Hands organ) — what Viki can DO on Victoi. Every call leaves a transparent audit trail."},{"name":"orchestrator","description":"Full chat orchestration — plan → tools → response, with permission gates and live SSE streams."},{"name":"voice","description":"Real-time voice (live.bidi organ) — LiveKit-backed bidirectional speech with Google Cloud STT + Cloud TTS (Chirp 3 HD, Sulafat voice) and the Mind organ for the LLM."}]}