Voice Agent scaffold
A complete program, not a fragment: it compiles as written. Copy it, rename the
placeholder identifiers to your domain, and run axon check — the compiler will
tell you what your renaming broke. An MCP client can also generate it through the
axon.compose tool by naming the voice domain.
// AXON Voice Agent scaffold — audio-in / audio-out conversational agent
// with declared `ots:` codec transformations (μ-law 8kHz ↔ PCM16).
//
// This scaffold targets PSTN-style integrations (Twilio, Vonage) where
// inbound audio arrives μ-law-encoded and the LLM-streaming side
// expects PCM16. The ots declarations are first-class transformation
// surfaces; the runtime dispatches to native or ffmpeg backends.
// ── Types ─────────────────────────────────────────────────────────
type AudioFrame {
samples: Bytes
sample_rate: Int
codec: Text
}
type Transcript { text: Text }
type Token { piece: Text }
type VoiceCallRequest { frame: AudioFrame }
// ── Closed-catalogue OTS transformations ──────────────────────────
ots InboundMulawToPcm16 {
teleology: "Decode mu-law 8kHz inbound audio for LLM-streaming pipelines"
homotopy_search: shallow
loss_function: "RMSE on reconstructed waveform"
}
ots OutboundPcm16ToMulaw {
teleology: "Encode PCM16 LLM output back to mu-law for the carrier"
homotopy_search: shallow
loss_function: "RMSE on reconstructed waveform"
}
// ── Identity + grounding ──────────────────────────────────────────
persona VoiceConcierge {
domain: ["voice-assistant", "phone-concierge"]
tone: empathetic
confidence_threshold: 0.7
cite_sources: false
}
context VoiceCall {
memory: session
language: "en"
depth: standard
max_tokens: 1024
temperature: 0.5
}
anchor SpeakClearly {
require: source_citation
confidence_floor: 0.6
unknown_response: "Sorry, I didn't catch that. Could you repeat?"
on_violation: log
}
// ── Tool — streaming backend ──────────────────────────────────────
tool VoiceBackend {
// LLM-routed: the tool IS the model. No `provider:` (v2.69.0). `openai` was not a real provider slug.
effects: <network, stream:drop_oldest>
timeout: 30s
}
// ── Streaming flow ────────────────────────────────────────────────
flow HandleVoiceFrame(frame: AudioFrame) -> Stream<Token> {
step Transcribe {
given: frame
apply: InboundMulawToPcm16
ask: "Transcribe the decoded audio frame."
output: FlowEnvelope<Transcript>
}
step Respond {
given: Transcribe.output
apply: VoiceBackend
ask: "Reply token-by-token in natural speech."
output: Stream<Token>
}
return Respond.output
}
// ── HTTP boundary (SSE-back for streaming audio) ──────────────────
axonendpoint VoiceCallAPI {
method: post
path: "/v1/voice/call"
body: VoiceCallRequest
execute: HandleVoiceFrame
output: Stream<Token>
backend: auto
transport: sse(axon)
retries: 0
timeout: 60s public: true
}