From c738dbe775f9c32f24beb0dc8ba1cd1e083a7c99 Mon Sep 17 00:00:00 2001 From: mikeee Date: Tue, 5 Nov 2024 18:28:24 +0000 Subject: [PATCH 1/4] feat: conversation api implementation Signed-off-by: mikeee --- client/client.go | 3 + client/conversation.go | 132 ++++++++++++++++++ .../config/conversation-echo.yaml | 7 + examples/conversation/main.go | 36 +++++ 4 files changed, 178 insertions(+) create mode 100644 client/conversation.go create mode 100644 examples/conversation/config/conversation-echo.yaml create mode 100644 examples/conversation/main.go diff --git a/client/client.go b/client/client.go index 950a4626..998089db 100644 --- a/client/client.go +++ b/client/client.go @@ -259,6 +259,9 @@ type Client interface { // DeleteJobAlpha1 deletes a scheduled job. DeleteJobAlpha1(ctx context.Context, name string) error + // ConverseAlpha1 interacts with a conversational AI model. + ConverseAlpha1(ctx context.Context, componentName string, inputs []ConversationInput, options ...conversationRequestOption) (*ConversationResponse, error) + // GrpcClient returns the base grpc client if grpc is used and nil otherwise GrpcClient() pb.DaprClient diff --git a/client/conversation.go b/client/conversation.go new file mode 100644 index 00000000..0118b079 --- /dev/null +++ b/client/conversation.go @@ -0,0 +1,132 @@ +/* +Copyright 2024 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "fmt" + runtimev1pb "github.com/dapr/dapr/pkg/proto/runtime/v1" + "google.golang.org/protobuf/types/known/anypb" +) + +type conversationRequestOptions struct { + Parameters map[string]*anypb.Any + Metadata map[string]string + ContextID *string + ScrubPII *bool // Scrub PII from the output + Temperature *float64 +} + +type conversationRequestOption func(request *conversationRequestOptions) + +type ConversationInput struct { + Message string + Role *string + ScrubPII *bool // Scrub PII from the input +} + +type ConversationInputOption func(*ConversationInput) + +func NewConversationInput(message string, opts ...ConversationInputOption) ConversationInput { + return ConversationInput{} +} + +type ConversationResponse struct { + ContextID string + Outputs []ConversationResult +} + +type ConversationResult struct { + Result string + Parameters map[string]*anypb.Any +} + +func WithParameters(parameters map[string]*anypb.Any) conversationRequestOption { + return func(o *conversationRequestOptions) { + o.Parameters = parameters + } +} + +func WithMetadata(metadata map[string]string) conversationRequestOption { + return func(o *conversationRequestOptions) { + o.Metadata = metadata + } +} + +func WithContextID(id string) conversationRequestOption { + return func(o *conversationRequestOptions) { + o.ContextID = &id + } +} + +func WithScrubPII(scrub bool) conversationRequestOption { + return func(o *conversationRequestOptions) { + o.ScrubPII = &scrub + } +} + +func WithTemperature(temp float64) conversationRequestOption { + return func(o *conversationRequestOptions) { + o.Temperature = &temp + } +} + +func (c *GRPCClient) ConverseAlpha1(ctx context.Context, componentName string, inputs []ConversationInput, options ...conversationRequestOption) (*ConversationResponse, error) { + + var cinputs []*runtimev1pb.ConversationInput + for _, i := range inputs { + cinputs = append(cinputs, &runtimev1pb.ConversationInput{ + Message: i.Message, + Role: i.Role, + ScrubPII: i.ScrubPII, + }) + } + + var o conversationRequestOptions + for _, opt := range options { + if opt != nil { + opt(&o) + } + } + + request := runtimev1pb.ConversationRequest{ + Name: componentName, + ContextID: o.ContextID, + Inputs: cinputs, + Parameters: o.Parameters, + Metadata: o.Metadata, + ScrubPII: o.ScrubPII, + Temperature: o.Temperature, + } + + fmt.Println("invoking") + + resp, err := c.protoClient.ConverseAlpha1(ctx, &request) + if err != nil { + return nil, err + } + + var outputs []ConversationResult + for _, i := range resp.GetOutputs() { + outputs = append(outputs, ConversationResult{ + Result: i.GetResult(), + Parameters: i.GetParameters(), + }) + } + + return &ConversationResponse{ + ContextID: resp.GetContextID(), + Outputs: outputs, + }, nil +} diff --git a/examples/conversation/config/conversation-echo.yaml b/examples/conversation/config/conversation-echo.yaml new file mode 100644 index 00000000..9a8b3072 --- /dev/null +++ b/examples/conversation/config/conversation-echo.yaml @@ -0,0 +1,7 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: echo +spec: + type: conversation.echo + version: v1 \ No newline at end of file diff --git a/examples/conversation/main.go b/examples/conversation/main.go new file mode 100644 index 00000000..70f1fd15 --- /dev/null +++ b/examples/conversation/main.go @@ -0,0 +1,36 @@ +/* +Copyright 2024 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +import ( + "context" + "fmt" + dapr "github.com/dapr/go-sdk/client" + "log" +) + +func main() { + client, err := dapr.NewClientWithPort("47649") + if err != nil { + panic(err) + } + + resp, err := client.ConverseAlpha1(context.Background(), "echo", []dapr.ConversationInput{{Message: "hello"}}) + if err != nil { + log.Fatalf("err: %v", err) + } + + fmt.Println(resp.Outputs) +} From 4b13ed0ef082b9621b583e7ca4fb6ae5a6307619 Mon Sep 17 00:00:00 2001 From: mikeee Date: Tue, 5 Nov 2024 18:28:42 +0000 Subject: [PATCH 2/4] chore: deps for conversation api Signed-off-by: mikeee --- examples/go.mod | 20 ++++++++++---------- examples/go.sum | 40 ++++++++++++++++++++-------------------- go.mod | 20 ++++++++++---------- go.sum | 40 ++++++++++++++++++++-------------------- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/examples/go.mod b/examples/go.mod index d504837f..9721bec8 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -1,6 +1,6 @@ module github.com/dapr/go-sdk/examples -go 1.22.6 +go 1.23.1 replace github.com/dapr/go-sdk => ../ @@ -9,7 +9,7 @@ require ( github.com/dapr/go-sdk v0.0.0-00010101000000-000000000000 github.com/go-redis/redis/v8 v8.11.5 github.com/google/uuid v1.6.0 - google.golang.org/grpc v1.65.0 + google.golang.org/grpc v1.67.0 google.golang.org/grpc/examples v0.0.0-20240516203910-e22436abb809 google.golang.org/protobuf v1.34.2 ) @@ -18,7 +18,7 @@ require ( github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/dapr/dapr v1.14.1 // indirect + github.com/dapr/dapr v1.14.3-0.20241104205526-334ae9eea43d // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/go-chi/chi/v5 v5.1.0 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -28,12 +28,12 @@ require ( github.com/marusama/semaphore/v2 v2.5.0 // indirect github.com/microsoft/durabletask-go v0.5.1-0.20241014200046-fac9dd959f4d // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect + go.opentelemetry.io/otel v1.30.0 // indirect + go.opentelemetry.io/otel/metric v1.30.0 // indirect + go.opentelemetry.io/otel/trace v1.30.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/go.sum b/examples/go.sum index b3b2f562..99880962 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -7,8 +7,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/dapr/dapr v1.14.1 h1:n+FGF82caTsBjmnmKdBfrO94GRuLeuYs6qrAN5oG4ZM= -github.com/dapr/dapr v1.14.1/go.mod h1:oDNgaPHQIDZ3G4n4g89TElXWgkluYwcar41DI/oF4gw= +github.com/dapr/dapr v1.14.3-0.20241104205526-334ae9eea43d h1:0mkhz/uwGP+FE7EkMpnFZATnCshQY/9z3yHLnp+j9Ts= +github.com/dapr/dapr v1.14.3-0.20241104205526-334ae9eea43d/go.mod h1:/G9Z/yj9eQQlZSh14X4WQyF/KyzlQfxZqk2ut3LfqhM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -59,24 +59,24 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= +go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= +go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= +go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= +go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= +go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= +google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/examples v0.0.0-20240516203910-e22436abb809 h1:f96Rv5C5Y2CWlbKK6KhKDdyFgGOjPHPEMsdyaxE9k0c= google.golang.org/grpc/examples v0.0.0-20240516203910-e22436abb809/go.mod h1:uaPEAc5V00jjG3DPhGFLXGT290RUV3+aNQigs1W50/8= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/go.mod b/go.mod index 139a636c..3d0527ae 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,15 @@ module github.com/dapr/go-sdk -go 1.22.6 +go 1.23.1 require ( - github.com/dapr/dapr v1.14.1 + github.com/dapr/dapr v1.14.3-0.20241104205526-334ae9eea43d github.com/go-chi/chi/v5 v5.1.0 github.com/golang/mock v1.6.0 github.com/google/uuid v1.6.0 github.com/microsoft/durabletask-go v0.5.1-0.20241014200046-fac9dd959f4d github.com/stretchr/testify v1.9.0 - google.golang.org/grpc v1.65.0 + google.golang.org/grpc v1.67.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 ) @@ -23,12 +23,12 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/marusama/semaphore/v2 v2.5.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect + go.opentelemetry.io/otel v1.30.0 // indirect + go.opentelemetry.io/otel/metric v1.30.0 // indirect + go.opentelemetry.io/otel/trace v1.30.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index 0db5a317..d03b886d 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/dapr/dapr v1.14.1 h1:n+FGF82caTsBjmnmKdBfrO94GRuLeuYs6qrAN5oG4ZM= -github.com/dapr/dapr v1.14.1/go.mod h1:oDNgaPHQIDZ3G4n4g89TElXWgkluYwcar41DI/oF4gw= +github.com/dapr/dapr v1.14.3-0.20241104205526-334ae9eea43d h1:0mkhz/uwGP+FE7EkMpnFZATnCshQY/9z3yHLnp+j9Ts= +github.com/dapr/dapr v1.14.3-0.20241104205526-334ae9eea43d/go.mod h1:/G9Z/yj9eQQlZSh14X4WQyF/KyzlQfxZqk2ut3LfqhM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= @@ -35,22 +35,22 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= +go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= +go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= +go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= +go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= +go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -58,23 +58,23 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= +google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From d4dda30320ab1b323d3389733089d561b05d06c8 Mon Sep 17 00:00:00 2001 From: mikeee Date: Tue, 5 Nov 2024 22:31:49 +0000 Subject: [PATCH 3/4] fix: cleanup convo example Signed-off-by: mikeee --- .github/workflows/test-on-push.yaml | 9 +----- .github/workflows/validate_examples.yaml | 3 +- client/conversation.go | 9 ------ examples/conversation/README.md | 36 ++++++++++++++++++++++++ examples/conversation/main.go | 16 +++++++++-- 5 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 examples/conversation/README.md diff --git a/.github/workflows/test-on-push.yaml b/.github/workflows/test-on-push.yaml index cdc35578..3e450d1e 100644 --- a/.github/workflows/test-on-push.yaml +++ b/.github/workflows/test-on-push.yaml @@ -10,14 +10,7 @@ jobs: build: name: Test on ${{ matrix.gover }} runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - gover: - - "1.21" - - "1.22" env: - GOVER: ${{ matrix.gover }} GOLANGCILINT_VER: v1.55.2 steps: @@ -29,7 +22,7 @@ jobs: - name: Setup uses: actions/setup-go@v5 with: - go-version: ${{ env.GOVER }} + go-version-file: 'go.mod' - name: Tidy run: make tidy diff --git a/.github/workflows/validate_examples.yaml b/.github/workflows/validate_examples.yaml index cc627998..39962efe 100644 --- a/.github/workflows/validate_examples.yaml +++ b/.github/workflows/validate_examples.yaml @@ -33,7 +33,7 @@ jobs: GOPROXY: https://proxy.golang.org DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/master/install/install.sh DAPR_CLI_REF: ${{ github.event.inputs.daprcli_commit }} - DAPR_REF: ${{ github.event.inputs.daprdapr_commit }} + DAPR_REF: 334ae9eea43d487a7b29a0e4aef904e3eba57a10 CHECKOUT_REPO: ${{ github.repository }} CHECKOUT_REF: ${{ github.ref }} outputs: @@ -164,6 +164,7 @@ jobs: [ "actor", "configuration", + "conversation", "crypto", "dist-scheduler", "grpc-service", diff --git a/client/conversation.go b/client/conversation.go index 0118b079..5c83c1cf 100644 --- a/client/conversation.go +++ b/client/conversation.go @@ -15,7 +15,6 @@ package client import ( "context" - "fmt" runtimev1pb "github.com/dapr/dapr/pkg/proto/runtime/v1" "google.golang.org/protobuf/types/known/anypb" ) @@ -36,12 +35,6 @@ type ConversationInput struct { ScrubPII *bool // Scrub PII from the input } -type ConversationInputOption func(*ConversationInput) - -func NewConversationInput(message string, opts ...ConversationInputOption) ConversationInput { - return ConversationInput{} -} - type ConversationResponse struct { ContextID string Outputs []ConversationResult @@ -110,8 +103,6 @@ func (c *GRPCClient) ConverseAlpha1(ctx context.Context, componentName string, i Temperature: o.Temperature, } - fmt.Println("invoking") - resp, err := c.protoClient.ConverseAlpha1(ctx, &request) if err != nil { return nil, err diff --git a/examples/conversation/README.md b/examples/conversation/README.md new file mode 100644 index 00000000..b27ed7b7 --- /dev/null +++ b/examples/conversation/README.md @@ -0,0 +1,36 @@ +# Dapr Conversation Example with go-sdk + +## Step + +### Prepare + +- Dapr installed + +### Run Conversation Example + + + +```bash +dapr run --app-id conversation \ + --dapr-grpc-port 50001 \ + --log-level debug \ + --resources-path ./config \ + -- go run ./main.go +``` + + + +## Result + +``` + - '== APP == conversation output: hello world' +``` diff --git a/examples/conversation/main.go b/examples/conversation/main.go index 70f1fd15..f6f3ab10 100644 --- a/examples/conversation/main.go +++ b/examples/conversation/main.go @@ -22,15 +22,25 @@ import ( ) func main() { - client, err := dapr.NewClientWithPort("47649") + client, err := dapr.NewClient() if err != nil { panic(err) } - resp, err := client.ConverseAlpha1(context.Background(), "echo", []dapr.ConversationInput{{Message: "hello"}}) + input := dapr.ConversationInput{ + Message: "hello world", + // Role: nil, // Optional + // ScrubPII: nil, // Optional + } + + fmt.Printf("conversation input: %s\n", input.Message) + + var conversationComponent = "echo" + + resp, err := client.ConverseAlpha1(context.Background(), conversationComponent, []dapr.ConversationInput{input}) if err != nil { log.Fatalf("err: %v", err) } - fmt.Println(resp.Outputs) + fmt.Printf("conversation output: %s\n", resp.Outputs[0].Result) } From d14495b551f052143afb8904d0ee1385723293f1 Mon Sep 17 00:00:00 2001 From: mikeee Date: Tue, 5 Nov 2024 23:06:21 +0000 Subject: [PATCH 4/4] refactor: add a conversationrequest builder and docs Signed-off-by: mikeee --- client/client.go | 2 +- client/conversation.go | 62 ++++++++++++++++++++++++----------- examples/conversation/main.go | 4 ++- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/client/client.go b/client/client.go index 998089db..f93350c4 100644 --- a/client/client.go +++ b/client/client.go @@ -260,7 +260,7 @@ type Client interface { DeleteJobAlpha1(ctx context.Context, name string) error // ConverseAlpha1 interacts with a conversational AI model. - ConverseAlpha1(ctx context.Context, componentName string, inputs []ConversationInput, options ...conversationRequestOption) (*ConversationResponse, error) + ConverseAlpha1(ctx context.Context, request conversationRequest, options ...conversationRequestOption) (*ConversationResponse, error) // GrpcClient returns the base grpc client if grpc is used and nil otherwise GrpcClient() pb.DaprClient diff --git a/client/conversation.go b/client/conversation.go index 5c83c1cf..028ac75b 100644 --- a/client/conversation.go +++ b/client/conversation.go @@ -19,7 +19,10 @@ import ( "google.golang.org/protobuf/types/known/anypb" ) -type conversationRequestOptions struct { +// conversationRequest object - currently unexported as used in a functions option pattern +type conversationRequest struct { + name string + inputs []ConversationInput Parameters map[string]*anypb.Any Metadata map[string]string ContextID *string @@ -27,58 +30,78 @@ type conversationRequestOptions struct { Temperature *float64 } -type conversationRequestOption func(request *conversationRequestOptions) +// NewConversationRequest defines a request with a component name and one or more inputs as a slice +func NewConversationRequest(llmName string, inputs []ConversationInput) conversationRequest { + return conversationRequest{ + name: llmName, + inputs: inputs, + } +} + +type conversationRequestOption func(request *conversationRequest) +// ConversationInput defines a single input. type ConversationInput struct { - Message string - Role *string - ScrubPII *bool // Scrub PII from the input + // The string to send to the llm. + Message string + // The role of the message. + Role *string + // Whether to Scrub PII from the input + ScrubPII *bool } +// ConversationResponse is the basic response from a conversationRequest. type ConversationResponse struct { ContextID string Outputs []ConversationResult } +// ConversationResult is the individual type ConversationResult struct { Result string Parameters map[string]*anypb.Any } +// WithParameters should be used to provide parameters for custom fields. func WithParameters(parameters map[string]*anypb.Any) conversationRequestOption { - return func(o *conversationRequestOptions) { + return func(o *conversationRequest) { o.Parameters = parameters } } +// WithMetadata used to define metadata to be passed to components. func WithMetadata(metadata map[string]string) conversationRequestOption { - return func(o *conversationRequestOptions) { + return func(o *conversationRequest) { o.Metadata = metadata } } +// WithContextID to provide a new context or continue an existing one. func WithContextID(id string) conversationRequestOption { - return func(o *conversationRequestOptions) { + return func(o *conversationRequest) { o.ContextID = &id } } +// WithScrubPII to define whether the outputs should have PII removed. func WithScrubPII(scrub bool) conversationRequestOption { - return func(o *conversationRequestOptions) { + return func(o *conversationRequest) { o.ScrubPII = &scrub } } +// WithTemperature to specify which way the LLM leans. func WithTemperature(temp float64) conversationRequestOption { - return func(o *conversationRequestOptions) { + return func(o *conversationRequest) { o.Temperature = &temp } } -func (c *GRPCClient) ConverseAlpha1(ctx context.Context, componentName string, inputs []ConversationInput, options ...conversationRequestOption) (*ConversationResponse, error) { +// ConverseAlpha1 can invoke an LLM given a request created by the NewConversationRequest function. +func (c *GRPCClient) ConverseAlpha1(ctx context.Context, req conversationRequest, options ...conversationRequestOption) (*ConversationResponse, error) { var cinputs []*runtimev1pb.ConversationInput - for _, i := range inputs { + for _, i := range req.inputs { cinputs = append(cinputs, &runtimev1pb.ConversationInput{ Message: i.Message, Role: i.Role, @@ -86,21 +109,20 @@ func (c *GRPCClient) ConverseAlpha1(ctx context.Context, componentName string, i }) } - var o conversationRequestOptions for _, opt := range options { if opt != nil { - opt(&o) + opt(&req) } } request := runtimev1pb.ConversationRequest{ - Name: componentName, - ContextID: o.ContextID, + Name: req.name, + ContextID: req.ContextID, Inputs: cinputs, - Parameters: o.Parameters, - Metadata: o.Metadata, - ScrubPII: o.ScrubPII, - Temperature: o.Temperature, + Parameters: req.Parameters, + Metadata: req.Metadata, + ScrubPII: req.ScrubPII, + Temperature: req.Temperature, } resp, err := c.protoClient.ConverseAlpha1(ctx, &request) diff --git a/examples/conversation/main.go b/examples/conversation/main.go index f6f3ab10..00b347e0 100644 --- a/examples/conversation/main.go +++ b/examples/conversation/main.go @@ -37,7 +37,9 @@ func main() { var conversationComponent = "echo" - resp, err := client.ConverseAlpha1(context.Background(), conversationComponent, []dapr.ConversationInput{input}) + request := dapr.NewConversationRequest(conversationComponent, []dapr.ConversationInput{input}) + + resp, err := client.ConverseAlpha1(context.Background(), request) if err != nil { log.Fatalf("err: %v", err) }