Current section
Files
Jump to
Current section
Files
priv/proto/vox.proto
syntax = "proto3";
package vox;
import "google/protobuf/struct.proto";
service HealthService {
rpc Health(HealthRequest) returns (HealthResponse);
rpc ListLoaded(ListLoadedRequest) returns (ListLoadedResponse);
}
service ModelService {
rpc Pull(PullRequest) returns (stream PullProgress);
rpc List(ListModelsRequest) returns (ListModelsResponse);
rpc Show(ShowRequest) returns (ShowResponse);
rpc Delete(DeleteRequest) returns (DeleteResponse);
}
service TranscriptionService {
rpc Transcribe(TranscribeRequest) returns (TranscribeResponse);
rpc Annotate(AnnotateRequest) returns (AnnotateResponse);
}
service SynthesisService {
rpc Synthesize(SynthesizeRequest) returns (stream AudioChunk);
rpc ListVoices(ListVoicesRequest) returns (ListVoicesResponse);
rpc CreateVoice(CreateVoiceRequest) returns (CreateVoiceResponse);
rpc DeleteVoice(DeleteVoiceRequest) returns (DeleteVoiceResponse);
}
message HealthRequest {}
message HealthResponse {
string status = 1;
}
message ListLoadedRequest {}
message ListLoadedResponse {
repeated LoadedModel models = 1;
}
message LoadedModel {
string name = 1;
string tag = 2;
string type = 3;
string device = 4;
int64 vram_bytes = 5;
double loaded_at = 6;
double last_used = 7;
int32 ref_count = 8;
}
message PullRequest {
string name = 1;
string variant = 2;
}
message PullProgress {
string status = 1;
string error = 2;
int32 completed = 3;
int32 total = 4;
}
message ListModelsRequest {}
message ListModelsResponse {
repeated ModelInfo models = 1;
}
message ModelInfo {
string name = 1;
string type = 2;
string format = 3;
string architecture = 4;
int64 size_bytes = 5;
string description = 6;
}
message ShowRequest {
string name = 1;
}
message ShowResponse {
string name = 1;
map<string, string> config = 2;
repeated LayerInfo layers = 3;
}
message LayerInfo {
string media_type = 1;
string digest = 2;
int64 size = 3;
string filename = 4;
}
message DeleteRequest {
string name = 1;
}
message DeleteResponse {
string status = 1;
}
message TranscribeRequest {
bytes audio = 1;
string model = 2;
string language = 3;
bool word_timestamps = 4;
float temperature = 5;
string response_format = 6;
string format_hint = 7;
}
message TranscribeResponse {
string model = 1;
string text = 2;
string language = 3;
int32 duration_ms = 4;
int32 processing_ms = 5;
repeated TranscriptSegment segments = 6;
repeated Entity entities = 7;
repeated string topics = 8;
}
message Entity {
string type = 1;
string text = 2;
uint32 start_char = 3;
uint32 end_char = 4;
}
message AnnotateRequest {
string text = 1;
string language = 2;
}
message AnnotateResponse {
repeated Entity entities = 1;
repeated string topics = 2;
}
message TranscriptSegment {
string text = 1;
int32 start_ms = 2;
int32 end_ms = 3;
repeated WordTimestamp words = 4;
}
message WordTimestamp {
string word = 1;
int32 start_ms = 2;
int32 end_ms = 3;
optional float confidence = 4;
}
message SynthesizeRequest {
string model = 1;
string input = 2;
string voice = 3;
float speed = 4;
string language = 5;
string response_format = 6;
google.protobuf.Struct params = 7;
}
message AudioChunk {
bytes audio = 1;
int32 sample_rate = 2;
bool is_final = 3;
}
service StreamingService {
rpc StreamTranscribe(stream StreamInput) returns (stream StreamOutput);
}
message StreamInput {
oneof msg {
StreamConfig config = 1;
AudioFrame audio = 2;
OpusFrame opus_frame = 3;
EncodedAudioFrame encoded_audio = 4;
EndOfStream end_of_stream = 5;
}
}
message EndOfStream {}
message StreamConfig {
string language = 1;
uint32 sample_rate = 2;
string model = 3;
bool partials = 4;
uint32 partial_window_ms = 5;
uint32 partial_stride_ms = 6;
bool include_word_timestamps = 7;
float temperature = 8;
}
message AudioFrame {
bytes pcm16 = 1;
uint32 sample_rate = 2;
}
message OpusFrame {
bytes data = 1;
uint32 sample_rate = 2;
uint32 channels = 3;
}
message EncodedAudioFrame {
bytes data = 1;
string format = 2;
}
message StreamOutput {
oneof msg {
StreamReady ready = 1;
StreamSpeechStarted speech_started = 2;
StreamSpeechStopped speech_stopped = 3;
StreamTranscriptResult transcript = 4;
StreamErrorMessage error = 5;
}
}
message StreamReady {}
message StreamSpeechStarted {
uint32 timestamp_ms = 1;
}
message StreamSpeechStopped {
uint32 timestamp_ms = 1;
}
message StreamTranscriptResult {
string text = 1;
bool is_partial = 2;
uint32 start_ms = 3;
uint32 end_ms = 4;
uint32 audio_duration_ms = 5;
uint32 processing_duration_ms = 6;
string model = 7;
optional float eou_probability = 8;
repeated Entity entities = 9;
repeated string topics = 10;
repeated WordTimestamp words = 11;
repeated TranscriptSegment segments = 12;
}
message StreamErrorMessage {
string message = 1;
}
message ListVoicesRequest {
string model = 1;
}
message ListVoicesResponse {
repeated VoiceInfo voices = 1;
}
message CreateVoiceRequest {
string name = 1;
bytes audio = 2;
string language = 3;
string gender = 4;
string reference_text = 5;
string format_hint = 6;
}
message CreateVoiceResponse {
VoiceInfo voice = 1;
int64 created_at = 2;
}
message DeleteVoiceRequest {
string id = 1;
}
message DeleteVoiceResponse {
string id = 1;
bool deleted = 2;
}
message VoiceInfo {
string id = 1;
string name = 2;
string language = 3;
string gender = 4;
string description = 5;
bool is_cloned = 6;
string model = 7;
}
// ---------------------------------------------------------------------------
// ConversationService: bidi streaming for agent-facing voice orchestration.
// The agent (any language) terminates WebRTC/SIP/etc. on its own and streams
// PCM into Vox; Vox runs VAD+STT+EOU+state-machine+TTS and streams back
// transcripts, state changes, and synthesized audio.
// ---------------------------------------------------------------------------
service ConversationService {
rpc Converse(stream ConverseClientMessage) returns (stream ConverseServerMessage);
}
service RtcService {
rpc CreateSession(RtcCreateSessionRequest) returns (RtcSessionBootstrap);
rpc Control(stream RtcControlClientMessage) returns (stream RtcControlServerMessage);
}
message RtcCreateSessionRequest {
optional bool browser_events = 1;
}
message RtcIceServer {
repeated string urls = 1;
string username = 2;
string credential = 3;
}
message RtcSessionBootstrap {
string session_id = 1;
reserved 2, 4;
reserved "client_token", "join_token_ttl_seconds";
string expires_at = 3;
repeated RtcIceServer ice_servers = 5;
uint32 attach_ttl_seconds = 6;
}
message RtcSessionDescription {
string type = 1;
string sdp = 2;
}
message RtcControlAnswer {
string session_id = 1;
RtcSessionDescription answer = 2;
}
message RtcIceCandidate {
string candidate = 1;
optional string sdp_mid = 2;
optional uint32 sdp_m_line_index = 3;
optional string username_fragment = 4;
}
message RtcIceCandidatesComplete {}
message RtcControlOffer {
RtcSessionDescription offer = 1;
bool restart = 2;
}
message RtcControlClose {
string reason = 1;
}
message RtcControlClosed {
string session_id = 1;
string reason = 2;
}
message RtcSignalingError {
string message = 1;
}
message RtcWireEvent {
string type = 1;
string payload_json = 2;
}
message ConverseClientMessage {
oneof msg {
ConversationSessionUpdate session_update = 1;
ConversationAudioAppend audio_append = 2;
// field 3 reserved (was ConversationResponseCreate — superseded by start/delta/commit)
ConversationResponseCancel response_cancel = 4;
ConversationResponseStart response_start = 5;
ConversationResponseDelta response_delta = 6;
ConversationResponseCommit response_commit = 7;
ConversationResponseReplaceText response_replace_text = 8;
}
reserved 3;
reserved "response_create";
}
message RtcControlClientMessage {
oneof msg {
RtcControlAttach attach = 1;
ConversationSessionUpdate session_update = 2;
// field 3 reserved (was ConversationResponseCreate — superseded by start/delta/commit)
ConversationResponseCancel response_cancel = 4;
ConversationResponseStart response_start = 5;
ConversationResponseDelta response_delta = 6;
ConversationResponseCommit response_commit = 7;
RtcClientEvent client_event = 8;
ConversationResponseReplaceText response_replace_text = 9;
RtcControlOffer offer = 10;
RtcIceCandidate candidate = 11;
RtcIceCandidatesComplete candidates_complete = 12;
RtcControlClose close = 13;
}
reserved 3;
reserved "response_create";
}
message RtcControlServerMessage {
oneof msg {
RtcSessionAttached attached = 1;
RtcControlAnswer answer = 2;
RtcIceCandidate candidate = 3;
RtcIceCandidatesComplete candidates_complete = 4;
ConverseServerMessage conversation = 5;
RtcSignalingError error = 6;
RtcControlClosed closed = 7;
RtcClientEvent browser_event = 8;
RtcWireEvent event = 9;
}
}
message RtcControlAttach {
string session_id = 1;
}
message ConverseServerMessage {
oneof msg {
ConversationSessionCreated session_created = 1;
ConversationSpeechStarted speech_started = 2;
ConversationSpeechStopped speech_stopped = 3;
ConversationTranscriptDone transcript_done = 4;
ConversationResponseCreated response_created = 5;
ConversationAudioDelta audio_delta = 6;
ConversationResponseDone response_done = 7;
ConversationResponseCancelled response_cancelled = 8;
ConversationStateChanged state_changed = 9;
ConversationError error = 10;
ConversationResponseCommitted response_committed = 11;
ConversationAudioClear audio_clear = 12;
ConversationInterruptionDetected interruption_detected = 13;
ConversationInterruptionFalsePositive interruption_false_positive = 14;
ConversationTurnEouPredicted turn_eou_predicted = 15;
ConversationTranscriptDelta transcript_delta = 18;
}
reserved 16, 17;
reserved "rtc_session_attached", "client_event";
}
message RtcSessionAttached {
string session_id = 1;
string provider = 2;
}
message RtcClientEvent {
string event = 1;
string payload_json = 2;
}
message ConversationResponseCommitted {
string response_id = 1;
}
message ConversationTurnPolicy {
optional bool allow_interrupt_while_speaking = 1;
optional uint32 min_interrupt_duration_ms = 2;
optional uint32 max_endpointing_delay_ms = 3;
optional uint32 stable_speaking_min_ms = 4;
optional uint32 false_interruption_timeout_ms = 5;
optional uint32 min_interrupt_words = 6;
optional bool partial_interrupts = 7;
optional bool dynamic_endpointing = 8;
optional uint32 min_endpointing_delay_ms = 9;
optional uint32 speaking_interrupt_min_duration_ms = 10;
optional uint32 speaking_interrupt_min_words = 11;
optional uint32 self_echo_min_words = 12;
optional float self_echo_min_overlap = 13;
optional uint32 aec_warmup_ms = 14;
optional uint32 backchannel_end_cooldown_ms = 15;
optional uint32 vad_min_silence_ms = 16;
}
message ConversationSessionUpdate {
string stt_model = 1;
string tts_model = 2;
string voice = 3;
string language = 4;
uint32 sample_rate = 5;
ConversationTurnPolicy policy = 6;
string vad_backend = 7;
string turn_detector = 8;
string turn_profile = 9;
bool include_word_timestamps = 10;
}
message ConversationAudioAppend {
bytes pcm16 = 1;
uint32 sample_rate = 2;
}
message ConversationResponseStart {
optional bool allow_interruptions = 1;
}
message ConversationResponseDelta {
string delta = 1;
optional bool allow_interruptions = 2;
}
message ConversationResponseCommit {}
message ConversationResponseCancel {}
message ConversationResponseReplaceText {
string text = 1;
optional bool allow_interruptions = 2;
}
message ConversationSessionCreated {
string turn_profile = 1;
ConversationTurnPolicy policy = 2;
}
message ConversationSpeechStarted {
uint32 timestamp_ms = 1;
}
message ConversationSpeechStopped {
uint32 timestamp_ms = 1;
}
message ConversationTranscriptDelta {
string delta = 1;
uint32 start_ms = 2;
uint32 end_ms = 3;
}
message ConversationTranscriptDone {
string transcript = 1;
string language = 2;
uint32 start_ms = 3;
uint32 end_ms = 4;
optional float eou_probability = 5;
repeated Entity entities = 6;
repeated string topics = 7;
repeated WordTimestamp words = 8;
}
message ConversationResponseCreated {
string response_id = 1;
}
message ConversationAudioDelta {
bytes audio = 1;
uint32 sample_rate = 2;
string response_id = 3;
uint32 sequence = 4;
}
message ConversationAudioClear {
string response_id = 1;
}
message ConversationInterruptionDetected {
string response_id = 1;
uint32 vad_active_ms = 2;
string partial_transcript = 3;
}
message ConversationInterruptionFalsePositive {
string response_id = 1;
uint32 vad_active_ms = 2;
string partial_transcript = 3;
string reason = 4;
}
message ConversationTurnEouPredicted {
float probability = 1;
float threshold = 2;
string decision = 3;
string action = 4;
uint32 delay_ms = 5;
string turn_detector = 6;
uint32 start_ms = 7;
uint32 end_ms = 8;
}
message ConversationResponseDone {
string response_id = 1;
}
message ConversationResponseCancelled {
string response_id = 1;
}
message ConversationStateChanged {
string state = 1;
string previous_state = 2;
}
message ConversationError {
string message = 1;
}