Files
handler-base/proto/messages/v1/messages.proto
Billy D. 13ef1df109
Some checks failed
CI / Lint (push) Failing after 3m2s
CI / Test (push) Successful in 3m44s
CI / Release (push) Has been skipped
CI / Notify Downstream (chat-handler) (push) Has been skipped
CI / Notify Downstream (pipeline-bridge) (push) Has been skipped
CI / Notify Downstream (stt-module) (push) Has been skipped
CI / Notify Downstream (tts-module) (push) Has been skipped
CI / Notify Downstream (voice-assistant) (push) Has been skipped
CI / Notify (push) Successful in 1s
feat!: replace msgpack with protobuf for all NATS messages
BREAKING CHANGE: All NATS message serialization now uses Protocol Buffers.
- Added proto/messages/v1/messages.proto with 22 message types
- Generated Go code at gen/messagespb/
- messages/ package now exports type aliases to proto types
- natsutil.Publish/Request/Decode use proto.Marshal/Unmarshal
- Removed legacy MessageHandler, OnMessage, wrapMapHandler
- TypedMessageHandler now returns (proto.Message, error)
- EffectiveQuery is now a free function: messages.EffectiveQuery(req)
- Removed msgpack dependency entirely
2026-02-21 14:58:05 -05:00

258 lines
9.7 KiB
Protocol Buffer

// Homelab AI service message contracts.
//
// This is the single source of truth for all NATS message types.
// Generated Go code lives in handler-base/gen/messagespb.
//
// Naming: field numbers are stable across versions — add new fields,
// never reuse or renumber existing ones.
syntax = "proto3";
package messages.v1;
option go_package = "git.daviestechlabs.io/daviestechlabs/handler-base/gen/messagespb";
// ─────────────────────────────────────────────────────────────────────────────
// Common
// ─────────────────────────────────────────────────────────────────────────────
// ErrorResponse is the standard error reply from any handler.
message ErrorResponse {
bool error = 1;
string message = 2;
string type = 3;
}
// ─────────────────────────────────────────────────────────────────────────────
// Chat (companions-frontend ↔ chat-handler)
// ─────────────────────────────────────────────────────────────────────────────
// LoginEvent is published when a user authenticates.
// Subject: ai.chat.user.{user_id}.login
message LoginEvent {
string user_id = 1;
string username = 2;
string nickname = 3;
bool premium = 4;
int64 timestamp = 5; // Unix seconds
}
// GreetingRequest asks the LLM to generate a personalised greeting.
// Subject: ai.chat.user.{user_id}.greeting.request
message GreetingRequest {
string user_id = 1;
string username = 2;
string nickname = 3;
bool premium = 4;
}
// GreetingResponse carries the generated greeting text.
// Subject: ai.chat.user.{user_id}.greeting.response
message GreetingResponse {
string user_id = 1;
string greeting = 2;
}
// ChatRequest is an incoming chat message routed via NATS.
// Subject: ai.chat.user.{user_id}.message
message ChatRequest {
string request_id = 1;
string user_id = 2;
string username = 3;
string message = 4;
string query = 5; // alternative to message (EffectiveQuery picks first non-empty)
bool premium = 6;
bool enable_rag = 7;
bool enable_reranker = 8;
bool enable_streaming = 9;
int32 top_k = 10;
string collection = 11;
bool enable_tts = 12;
string system_prompt = 13;
string response_subject = 14;
}
// ChatResponse is the full reply to a ChatRequest.
// Subject: ai.chat.response.{request_id} (or ChatRequest.response_subject)
message ChatResponse {
string user_id = 1;
string response = 2;
string response_text = 3;
bool used_rag = 4;
repeated string rag_sources = 5;
bool success = 6;
bytes audio = 7;
string error = 8;
}
// ChatStreamChunk is one piece of a streaming LLM response.
// Subject: ai.chat.response.stream.{request_id}
message ChatStreamChunk {
string request_id = 1;
string type = 2; // "chunk" | "done"
string content = 3;
bool done = 4;
int64 timestamp = 5;
}
// ─────────────────────────────────────────────────────────────────────────────
// Voice Assistant
// ─────────────────────────────────────────────────────────────────────────────
// VoiceRequest is an incoming voice-to-voice request.
// Subject: ai.voice.request
message VoiceRequest {
string request_id = 1;
bytes audio = 2;
string language = 3;
string collection = 4;
}
// DocumentSource is a single RAG search-result citation.
message DocumentSource {
string text = 1;
double score = 2;
}
// VoiceResponse is the reply to a VoiceRequest.
// Subject: ai.voice.response.{request_id}
message VoiceResponse {
string request_id = 1;
string response = 2;
bytes audio = 3;
string transcription = 4;
repeated DocumentSource sources = 5;
string error = 6;
}
// ─────────────────────────────────────────────────────────────────────────────
// TTS Module
// ─────────────────────────────────────────────────────────────────────────────
// TTSRequest is a text-to-speech synthesis request.
// Subject: ai.voice.tts.request.{session_id}
message TTSRequest {
string text = 1;
string speaker = 2;
string language = 3;
string speaker_wav_b64 = 4;
bool stream = 5;
}
// TTSAudioChunk is a streamed audio chunk from TTS synthesis.
// Subject: ai.voice.tts.audio.{session_id}
message TTSAudioChunk {
string session_id = 1;
int32 chunk_index = 2;
int32 total_chunks = 3;
bytes audio = 4;
bool is_last = 5;
int64 timestamp = 6;
int32 sample_rate = 7;
}
// TTSFullResponse is a non-streamed TTS response (whole audio blob).
// Subject: ai.voice.tts.audio.{session_id}
message TTSFullResponse {
string session_id = 1;
bytes audio = 2;
int64 timestamp = 3;
int32 sample_rate = 4;
}
// TTSStatus is a TTS processing status update.
// Subject: ai.voice.tts.status.{session_id}
message TTSStatus {
string session_id = 1;
string status = 2;
string message = 3;
int64 timestamp = 4;
}
// TTSVoiceInfo is summary info about a custom voice.
message TTSVoiceInfo {
string name = 1;
string language = 2;
string model_type = 3;
string created_at = 4;
}
// TTSVoiceListResponse is the reply to a voice list request.
// Subject: ai.voice.tts.voices.list (request-reply)
message TTSVoiceListResponse {
string default_speaker = 1;
repeated TTSVoiceInfo custom_voices = 2;
int64 last_refresh = 3;
int64 timestamp = 4;
}
// TTSVoiceRefreshResponse is the reply to a voice refresh request.
// Subject: ai.voice.tts.voices.refresh (request-reply)
message TTSVoiceRefreshResponse {
int32 count = 1;
repeated TTSVoiceInfo custom_voices = 2;
int64 timestamp = 3;
}
// ─────────────────────────────────────────────────────────────────────────────
// STT Module
// ─────────────────────────────────────────────────────────────────────────────
// STTStreamMessage is any message on the ai.voice.stream.{session_id} subject.
message STTStreamMessage {
string type = 1; // "start" | "chunk" | "state_change" | "end"
bytes audio = 2;
string state = 3;
string speaker_id = 4;
}
// STTTranscription is the transcription result published by the STT module.
// Subject: ai.voice.transcription.{session_id}
message STTTranscription {
string session_id = 1;
string transcript = 2;
int32 sequence = 3;
bool is_partial = 4;
bool is_final = 5;
int64 timestamp = 6;
string speaker_id = 7;
bool has_voice_activity = 8;
string state = 9;
}
// STTInterrupt is published when the STT module detects a user interrupt.
// Subject: ai.voice.transcription.{session_id}
message STTInterrupt {
string session_id = 1;
string type = 2; // "interrupt"
int64 timestamp = 3;
string speaker_id = 4;
}
// ─────────────────────────────────────────────────────────────────────────────
// Pipeline Bridge
// ─────────────────────────────────────────────────────────────────────────────
// PipelineTrigger is the request to start a pipeline.
// Subject: ai.pipeline.trigger
message PipelineTrigger {
string request_id = 1;
string pipeline = 2;
// Protobuf Struct could be used here, but a simple string map covers
// all current use-cases and avoids a google/protobuf import.
map<string, string> parameters = 3;
}
// PipelineStatus is the response / status update for a pipeline run.
// Subject: ai.pipeline.status.{request_id}
message PipelineStatus {
string request_id = 1;
string status = 2;
string run_id = 3;
string engine = 4;
string pipeline = 5;
string submitted_at = 6;
string error = 7;
repeated string available_pipelines = 8;
}