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
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
258 lines
9.7 KiB
Protocol Buffer
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;
|
|
}
|