This capability is granted by an API key scoped to any of the ai-suite, vagary-voice products (product face). See the product reference below.
Conversation orchestration as a shared capability — turn management, intent detection, tool-calling, safety-gating, barge-in/cancel, streaming assembly. It CONSUMES other capabilities (provider-gateway for the LLM, retrieval for RAG context, stt/tts for the audio legs) and owns only the dialogue control flow. D-2: retrieval is a SEPARATE capability (C9) — dialog-core calls it, never embeds it.
- Group: Voice & AI
- Contract:
contracts/dialog-core/v1/openapi.yaml
- Console: this capability is granted by more than one product — manage whichever one your key is scoped to:
- Runbook: operational checklist for
dialog-core — internal (Vagary Labs ops; not part of this public site): docs/runbooks/capability-operations.md#dialog-core
- Public base:
https://api.vagarylabs.com (the consolidated API gateway — one host, per-brand sibling api.<zone>)
- Auth: a product API key (
vgk_…) issued from the console — Authorization: Bearer vgk_…
- Product face (customer-keyed):
https://api.vagarylabs.com/product/v1/dialog/turns
- Capability face (internal first-party — NOT customer-keyed):
https://api.vagarylabs.com/v1/turn
Edge route table
The routes this capability actually serves on the public edge — live-synced from GET https://api.vagarylabs.com/product/v1/_meta/catalog (snapshot v1). The metric is the request-granularity billing counter; the scope is the key permission required.
Product face (customer-keyed)
| Method | Path | Metric | Scope |
|---|
POST | /product/v1/dialog/turns | dialog_turns | read |
Capability face (internal first-party — NOT customer-keyed)
Endpoints
| Method | Path | Summary |
|---|
POST | /v1/turn | Process one conversational turn (intent → optional tools + retrieval → LLM → safety → stream) |
POST | /v1/turn/{session_id}/cancel | barge-in — cancel the in-flight turn |
POST | /v1/greeting/prerender | Proactively render + cache a generation's opening line, so the FIRST call on it is fast |
GET | /health | liveness |
GET | /context-health | which context legs are enabled/disabled (default-deployment posture is otherwise silent) |
GET | /metrics | Prometheus |
Product face
The external, paying-customer surface served by the edge at /product/v1/* (contracts/dialog-core/product/v1/openapi.yaml).
| Method | Path | Summary |
|---|
POST | /turns | Process one conversational turn (managed, metered) — wraps the capability's orchestration |
Schemas
TurnRequest
| Field | Type | Description |
|---|
organization_id | string | |
session_id | string | |
input | string | |
stream | boolean | |
model | string | LLM model hint forwarded to provider-gateway (which owns provider selection) |
system | string | item 6 — per-caller system-prompt override; default is the service preamble |
history | boolean | item 1 — enable/disable multi-turn conversation history for this turn (overrides the DIALOG_HISTORY_ENABLED default) |
messages | array | item 1 — OPTIONAL client-supplied PRIOR conversation window ({role,content} list, EXCLUDING the current input). When present it is used as the history for this turn (durable/cross-replica product-face state), taking precedence over the in-process store. Absent => backward-compatible (in-process store when history is on, else stateless). |
retrieval | object | opt-in RAG params — dialog-core calls the retrieval capability (C9), never embeds it |
tools | array | function-calling tool definitions passed through to provider-gateway; returned tool_calls are surfaced (guarded) — or EXECUTED when execute_tools=true (T5-3) |
execute_tools | boolean | T5-3 — OPT-IN: run the agentic execute-then-continue loop (execute each tool_call, feed the result back, re-call, until a final answer). Requires tools. Absent/false => tool_calls are only surfaced (byte-identical to the pre-loop turn). |
tool_dispatch | object | T5-3 — how the executor DISPATCHES each tool by name to the caller's own HTTP endpoint (I5: core hosts no business tool). name -> {url, method?, headers?}. A tool with no entry yields a fail-open tool_not_dispatchable result the model can recover from. |
GreetingPrerenderRequest
| Field | Type | Description |
|---|
organization_id | string | |
flow_id | string | |
version | integer | the EXACT definition version to warm — never the live pointer |
definition_hash | string | the flow content pin; also the cache key component, so changed content is automatically a miss |
timeout_seconds | number | how long to wait for the out-of-band render to land before returning pending (default 8, capped at 30). A timeout is not a failure — the render may still land. |
GreetingPrerenderResponse
| Field | Type | Description |
|---|
status | string | cached = an asset already existed for this content (no render paid); rendered = a fresh render landed within the wait; pending = the capture was requested but had not landed yet; skipped = this profile carries no extractable opening line, so no asset will ever be produced for it (permanent, reported synchronously rather than as a never-resolving pending); not_permitted = the flow failed the same admission a live call runs; unavailable = no Redis configured; error = malformed request or capture publish failed. |
definition_hash | string | |
reason | string | |
TurnResponse
| Field | Type | Description |
|---|
session_id | string | |
content | string | |
intent | string | |
tool_calls | array | |
tool_trace | array | T5-3 — present only when execute_tools ran: the ordered trace of executed tool_calls (args + result + latency), never silent. |
tool_stop_reason | string | T5-3 — why the execute-then-continue loop stopped (present only when it ran) |
safety | object | |
Error
| Field | Type | Description |
|---|
error | string | |
ContextHealthResponse
| Field | Type | Description |
|---|
retrieval | object | |
history | object | |
memory | object | |
fast_path | object | |
tool_executor | object | |
plugin_registry | object | |
realtime | object | |
default_posture | string | literal summary: "[system, user] only" when both history and memory are disabled, else "context-enriched" |
LlmTokensEmit
| Field | Type | Description |
|---|
type | string | chunk = streamed word-buffer content; clear = flush-buffer control (no text); filler/fallback retained for voice parity (dialog-core emits chunk/clear — provider-gateway owns failover); prerendered = greeting pre-render asset reference (2026-09-19, see greeting_prerender.py); greeting_capture = one-shot capture request on the synthetic session:greeting_capture:llm_tokens channel |
text | string | REQUIRED for chunk/filler/fallback/greeting_capture; OMITTED for clear and prerendered (control/reference messages) |
timestamp | number | unix float seconds at emit; present on every message |
org_id | string | ADDITIVE tenant org_id threaded from the transcript envelope; absent on clear; nullable for API-key (no-org) sessions; also carries the capture-request org on greeting_capture |
consent_ref | string | ADDITIVE D22 consent lineage threaded from the transcript envelope; present on text-bearing kinds, absent on clear |
pcm_key | string | ADDITIVE, prerendered only: Redis key holding the base64 pre-rendered PCM to replay instead of live synthesis |
definition_hash | string | ADDITIVE, greeting_capture only: the published flow content-hash cache key component |
voice_id | string | ADDITIVE, greeting_capture only: informational voice identifier |
FlowTraceEmit
| Field | Type | Description |
|---|
type | string | |
session_store_id | string | Actual session-store-generated ID; distinct from the Voice session UUID. |
flow_id | string | |
flow_version | integer | |
Generated by scripts/gen-capability-docs.py from contracts/dialog-core/v1/openapi.yaml — the contract IS the source of truth; edit the contract, not this page. The Edge route table section is synced from the live edge catalog snapshot (v1) — re-sync with python3 scripts/sync-edge-catalog.py.