From 6e498cc0d5b38df550378e377b7e416183c5c10d Mon Sep 17 00:00:00 2001 From: "Billy D." Date: Sat, 21 Feb 2026 15:30:26 -0500 Subject: [PATCH] feat: migrate from msgpack to protobuf (handler-base v1.0.0) - Replace msgpack encoding with protobuf wire format - Update field names to proto convention - Use pointer slices for repeated message fields ([]*DocumentSource) - Rewrite tests for proto round-trips --- go.mod | 6 ++---- go.sum | 8 ++------ main.go | 19 ++++++++++--------- main_test.go | 26 +++++++++++++------------- 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index 8d2f5d8..f6f6f60 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module git.daviestechlabs.io/daviestechlabs/voice-assistant go 1.25.1 require ( - git.daviestechlabs.io/daviestechlabs/handler-base v0.1.5 + git.daviestechlabs.io/daviestechlabs/handler-base v1.0.0 github.com/nats-io/nats.go v1.48.0 - github.com/vmihailenco/msgpack/v5 v5.4.1 + google.golang.org/protobuf v1.36.11 ) require ( @@ -19,7 +19,6 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0 // indirect @@ -37,5 +36,4 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect google.golang.org/grpc v1.78.0 // indirect - google.golang.org/protobuf v1.36.11 // indirect ) diff --git a/go.sum b/go.sum index efceef0..5d7dfc1 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -git.daviestechlabs.io/daviestechlabs/handler-base v0.1.5 h1:DqYZpeluTXh5QKqdVFgN8YIMh4Ycqzw5E9+5FTNDFCA= -git.daviestechlabs.io/daviestechlabs/handler-base v0.1.5/go.mod h1:M3HgvUDWnRn7cX3BE8l+HvoCUYtmRr5OoumB+hnRHoE= +git.daviestechlabs.io/daviestechlabs/handler-base v1.0.0 h1:pB3ehOKaDYQfbyRBKQXrB9curqSFteLrDveoElRKnBY= +git.daviestechlabs.io/daviestechlabs/handler-base v1.0.0/go.mod h1:zocOHFt8yY3cW4+Xi37sNr5Tw7KcjGFSZqgWYxPWyqA= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -33,10 +33,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= diff --git a/main.go b/main.go index 8afa772..4422010 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "git.daviestechlabs.io/daviestechlabs/handler-base/handler" "git.daviestechlabs.io/daviestechlabs/handler-base/messages" "git.daviestechlabs.io/daviestechlabs/handler-base/natsutil" + "google.golang.org/protobuf/proto" ) func main() { @@ -43,13 +44,13 @@ func main() { h := handler.New("voice.request", cfg) - h.OnTypedMessage(func(ctx context.Context, msg *nats.Msg) (any, error) { - req, err := natsutil.Decode[messages.VoiceRequest](msg.Data) - if err != nil { + h.OnTypedMessage(func(ctx context.Context, msg *nats.Msg) (proto.Message, error) { + var req messages.VoiceRequest + if err := natsutil.Decode(msg.Data, &req); err != nil { return &messages.VoiceResponse{Error: "Invalid request encoding"}, nil } - requestID := req.RequestID + requestID := req.RequestId if requestID == "" { requestID = "unknown" } @@ -64,8 +65,8 @@ func main() { slog.Info("processing voice request", "request_id", requestID) - errResp := func(msg string) (any, error) { - return &messages.VoiceResponse{RequestID: requestID, Error: msg}, nil + errResp := func(msg string) (proto.Message, error) { + return &messages.VoiceResponse{RequestId: requestID, Error: msg}, nil } // 1. Audio arrives as raw bytes — no base64 decode needed @@ -146,7 +147,7 @@ func main() { // Build typed response result := &messages.VoiceResponse{ - RequestID: requestID, + RequestId: requestID, Response: responseText, Audio: responseAudio, } @@ -160,13 +161,13 @@ func main() { if len(documents) < limit { limit = len(documents) } - result.Sources = make([]messages.DocumentSource, limit) + result.Sources = make([]*messages.DocumentSource, limit) for i := 0; i < limit; i++ { text := documents[i].Document if len(text) > 200 { text = text[:200] } - result.Sources[i] = messages.DocumentSource{Text: text, Score: documents[i].Score} + result.Sources[i] = &messages.DocumentSource{Text: text, Score: documents[i].Score} } } diff --git a/main_test.go b/main_test.go index 2474475..b5f539a 100644 --- a/main_test.go +++ b/main_test.go @@ -5,26 +5,26 @@ import ( "git.daviestechlabs.io/daviestechlabs/handler-base/messages" "git.daviestechlabs.io/daviestechlabs/handler-base/natsutil" - "github.com/vmihailenco/msgpack/v5" + "google.golang.org/protobuf/proto" ) func TestVoiceRequestDecode(t *testing.T) { - req := messages.VoiceRequest{ - RequestID: "req-123", + req := &messages.VoiceRequest{ + RequestId: "req-123", Audio: []byte{0x01, 0x02, 0x03}, Language: "en", Collection: "docs", } - data, err := msgpack.Marshal(&req) + data, err := proto.Marshal(req) if err != nil { t.Fatal(err) } - decoded, err := natsutil.Decode[messages.VoiceRequest](data) - if err != nil { + var decoded messages.VoiceRequest + if err := natsutil.Decode(data, &decoded); err != nil { t.Fatal(err) } - if decoded.RequestID != "req-123" { - t.Errorf("RequestID = %q", decoded.RequestID) + if decoded.RequestId != "req-123" { + t.Errorf("RequestId = %q", decoded.RequestId) } if len(decoded.Audio) != 3 { t.Errorf("Audio len = %d", len(decoded.Audio)) @@ -32,19 +32,19 @@ func TestVoiceRequestDecode(t *testing.T) { } func TestVoiceResponseRoundtrip(t *testing.T) { - resp := messages.VoiceResponse{ - RequestID: "req-456", + resp := &messages.VoiceResponse{ + RequestId: "req-456", Response: "It is sunny today.", Audio: make([]byte, 8000), Transcription: "What is the weather?", - Sources: []messages.DocumentSource{{Text: "weather doc", Score: 0.9}}, + Sources: []*messages.DocumentSource{{Text: "weather doc", Score: 0.9}}, } - data, err := msgpack.Marshal(&resp) + data, err := proto.Marshal(resp) if err != nil { t.Fatal(err) } var got messages.VoiceResponse - if err := msgpack.Unmarshal(data, &got); err != nil { + if err := proto.Unmarshal(data, &got); err != nil { t.Fatal(err) } if got.Response != "It is sunny today." {