diff --git a/grpcServer/anthropic.go b/grpcServer/anthropic.go new file mode 100644 index 0000000..849aa3a --- /dev/null +++ b/grpcServer/anthropic.go @@ -0,0 +1,85 @@ +package grpcServer + +import ( + "go.limit.dev/unollm/model" + anthropic "go.limit.dev/unollm/provider/Anthropic" +) + +func NewAnthropicClient(info *model.LLMRequestInfo) *anthropic.Client { + return anthropic.NewClient(info.GetToken()) +} + +func AnthropicChatCompletion(cli *anthropic.Client, rs *model.LLMRequestSchema) (*model.LLMResponseSchema, error) { + req := anthropic.ChatCompletionRequest{ + Model: rs.LlmRequestInfo.Model, + Messages: make([]anthropic.Message, 0), + MaxTokens: 4096, + Temperature: rs.LlmRequestInfo.Temperature, + TopP: rs.LlmRequestInfo.TopP, + TopK: rs.LlmRequestInfo.TopK, + } + for _, m := range rs.Messages { + req.Messages = append(req.Messages, anthropic.Message{ + Role: m.Role, + Content: m.Content, + }) + } + respp, err := anthropic.ChatCompletion(cli, req) + if err != nil { + return nil, err + } + res := &model.LLMResponseSchema{ + Message: &model.LLMChatCompletionMessage{ + Role: respp.Role, + Content: respp.Content[0].Text, + }, + LlmTokenCount: &model.LLMTokenCount{ + PromptToken: int64(respp.Usage.InputTokens), + CompletionToken: int64(respp.Usage.OutputTokens), + TotalToken: int64(respp.Usage.InputTokens + respp.Usage.OutputTokens), + }, + } + + return res, nil +} + +func AnthropicChatCompletionStreaming(cli *anthropic.Client, rs *model.LLMRequestSchema, sv model.UnoLLMv1_StreamRequestLLMServer) error { + req := anthropic.ChatCompletionRequest{ + Model: rs.LlmRequestInfo.Model, + Messages: make([]anthropic.Message, 0), + MaxTokens: 4096, + } + for _, m := range rs.Messages { + req.Messages = append(req.Messages, anthropic.Message{ + Role: m.Role, + Content: m.Content, + }) + } + respp, err := cli.ChatCompletionStreamingRequest(&req) + if err != nil { + return err + } + go func() { + for { + r := <-respp + if r.Type == "STOP" { + sv.Send(&model.PartialLLMResponse{ + Response: &model.PartialLLMResponse_Done{}, + LlmTokenCount: &model.LLMTokenCount{ + PromptToken: int64(r.Delta.Usage.InputTokens), + CompletionToken: int64(r.Delta.Usage.OutputTokens), + TotalToken: int64(r.Delta.Usage.InputTokens + r.Delta.Usage.OutputTokens), + }, + }) + return + } else { + sv.Send(&model.PartialLLMResponse{ + Response: &model.PartialLLMResponse_Content{ + Content: r.Delta.Text, + }, + }) + } + } + }() + return nil +} diff --git a/grpcServer/baichuan.go b/grpcServer/baichuan.go index 5a1502e..e4093c4 100644 --- a/grpcServer/baichuan.go +++ b/grpcServer/baichuan.go @@ -1,6 +1,8 @@ package grpcServer import ( + "log" + "go.limit.dev/unollm/model" "go.limit.dev/unollm/provider/Baichuan" "go.limit.dev/unollm/relay" @@ -8,7 +10,6 @@ import ( "go.limit.dev/unollm/relay/respTransformer" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "log" ) func BaichuanChatCompletion(cli *Baichuan.Client, rs *model.LLMRequestSchema) (*model.LLMResponseSchema, error) { diff --git a/grpcServer/relay.go b/grpcServer/relay.go index 51bd56f..737cec8 100644 --- a/grpcServer/relay.go +++ b/grpcServer/relay.go @@ -28,6 +28,7 @@ const AZURE_OPENAI_LLM_API = "azure_openai" const BAICHUAN_LLM_API = "baichuan" const GEMINI_LLM_API = "gemini" const MOONSHOT_LLM_API = "moonshot" +const ANTHROPIC_LLM_API = "anthropic" func (uno *UnoForwardServer) BlockingRequestLLM(ctx context.Context, rs *model.LLMRequestSchema) (*model.LLMResponseSchema, error) { info := rs.GetLlmRequestInfo() @@ -35,7 +36,9 @@ func (uno *UnoForwardServer) BlockingRequestLLM(ctx context.Context, rs *model.L case OPENAI_LLM_API: cli := NewOpenAIClient(info) return OpenAIChatCompletion(cli, rs) - + case ANTHROPIC_LLM_API: + cli := NewAnthropicClient(info) + return AnthropicChatCompletion(cli, rs) case MOONSHOT_LLM_API: cli := NewOpenAIClient(info) if functionCallingRequestMake(rs) { @@ -82,6 +85,9 @@ func (uno *UnoForwardServer) StreamRequestLLM(rs *model.LLMRequestSchema, sv mod case OPENAI_LLM_API: cli := NewOpenAIClient(info) return OpenAIChatCompletionStreaming(cli, rs, sv) + case ANTHROPIC_LLM_API: + cli := NewAnthropicClient(info) + return AnthropicChatCompletionStreaming(cli, rs, sv) case MOONSHOT_LLM_API: cli := NewOpenAIClient(info) if functionCallingRequestMake(rs) { diff --git a/model/unollm.pb.go b/model/unollm.pb.go index ce2fe47..0f5ae3c 100644 --- a/model/unollm.pb.go +++ b/model/unollm.pb.go @@ -88,9 +88,10 @@ type LLMChatCompletionMessage struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` - Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` - ToolCallId *string `protobuf:"bytes,3,opt,name=tool_call_id,json=toolCallId,proto3,oneof" json:"tool_call_id,omitempty"` + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` + ToolCallId *string `protobuf:"bytes,3,opt,name=tool_call_id,json=toolCallId,proto3,oneof" json:"tool_call_id,omitempty"` + Images []string `protobuf:"bytes,4,rep,name=images,proto3" json:"images,omitempty"` } func (x *LLMChatCompletionMessage) Reset() { @@ -146,6 +147,13 @@ func (x *LLMChatCompletionMessage) GetToolCallId() string { return "" } +func (x *LLMChatCompletionMessage) GetImages() []string { + if x != nil { + return x.Images + } + return nil +} + type FunctionCallingParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -932,147 +940,148 @@ var file_model_unollm_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x80, 0x01, 0x0a, + 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x98, 0x01, 0x0a, 0x18, 0x4c, 0x4c, 0x4d, 0x43, 0x68, 0x61, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0c, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, - 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0f, - 0x0a, 0x0d, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x69, 0x64, 0x22, - 0x7a, 0x0a, 0x18, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6c, 0x6c, 0x69, - 0x6e, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x08, - 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, - 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x46, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x73, 0x22, 0x9d, - 0x03, 0x0a, 0x0e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x6c, 0x6c, 0x6d, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6c, 0x6d, 0x41, 0x70, 0x69, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x65, 0x6d, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, - 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, - 0x6f, 0x70, 0x5f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x74, 0x6f, 0x70, 0x50, - 0x12, 0x13, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x5f, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, - 0x04, 0x74, 0x6f, 0x70, 0x4b, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x40, 0x0a, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x24, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x66, 0x6f, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x66, 0x6f, 0x12, - 0x2e, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x46, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x30, 0x0a, 0x14, 0x75, 0x73, 0x65, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x75, - 0x73, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6c, 0x6c, 0x69, 0x6e, - 0x67, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x92, - 0x01, 0x0a, 0x10, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x12, 0x3c, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, - 0x4c, 0x4d, 0x43, 0x68, 0x61, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x12, 0x40, 0x0a, 0x10, 0x6c, 0x6c, 0x6d, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x75, 0x6e, - 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x6c, 0x6c, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x22, 0x06, 0x0a, 0x04, 0x44, 0x6f, 0x6e, 0x65, 0x22, 0x4c, 0x0a, 0x08, 0x54, - 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, - 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xe9, 0x01, 0x0a, 0x12, 0x50, 0x61, - 0x72, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x04, - 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x75, 0x6e, 0x6f, - 0x4c, 0x4c, 0x4d, 0x2e, 0x44, 0x6f, 0x6e, 0x65, 0x48, 0x00, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, - 0x12, 0x2f, 0x0a, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x54, 0x6f, - 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x09, 0x74, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, - 0x73, 0x12, 0x42, 0x0a, 0x0f, 0x6c, 0x6c, 0x6d, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x6f, - 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x48, 0x01, 0x52, 0x0d, 0x6c, 0x6c, 0x6d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x6c, 0x6c, 0x6d, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xbf, 0x01, 0x0a, 0x11, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x3a, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x75, - 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x43, 0x68, 0x61, 0x74, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0f, 0x6c, 0x6c, 0x6d, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x16, + 0x0a, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x69, 0x64, 0x22, 0x7a, 0x0a, 0x18, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, + 0x05, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, + 0x75, 0x6d, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x08, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x75, 0x6e, 0x6f, + 0x4c, 0x4c, 0x4d, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6c, 0x6c, + 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x73, 0x22, 0x9d, 0x03, 0x0a, 0x0e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x6c, 0x6c, 0x6d, + 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6c, 0x6c, 0x6d, 0x41, 0x70, 0x69, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x04, 0x74, 0x6f, 0x70, 0x50, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x5f, + 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x74, 0x6f, 0x70, 0x4b, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x40, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, + 0x2e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x75, 0x6e, 0x6f, + 0x4c, 0x4c, 0x4d, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x75, 0x73, 0x65, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x75, 0x73, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, + 0x61, 0x69, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x92, 0x01, 0x0a, 0x10, 0x4c, 0x4c, 0x4d, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x3c, 0x0a, 0x08, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x43, 0x68, 0x61, 0x74, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x10, 0x6c, 0x6c, 0x6d, + 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x6c, 0x6c, 0x6d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x06, 0x0a, 0x04, 0x44, + 0x6f, 0x6e, 0x65, 0x22, 0x4c, 0x0a, 0x08, 0x54, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x22, 0xe9, 0x01, 0x0a, 0x12, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x4c, 0x4d, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x44, 0x6f, 0x6e, 0x65, + 0x48, 0x00, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x75, + 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x09, + 0x74, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x12, 0x42, 0x0a, 0x0f, 0x6c, 0x6c, 0x6d, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x48, 0x01, 0x52, 0x0d, 0x6c, 0x6c, 0x6d, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x6c, 0x6c, + 0x6d, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xbf, 0x01, + 0x0a, 0x11, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x12, 0x3a, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, + 0x4d, 0x43, 0x68, 0x61, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x3d, 0x0a, 0x0f, 0x6c, 0x6c, 0x6d, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, + 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x0d, 0x6c, 0x6c, 0x6d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2f, + 0x0a, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, + 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x09, 0x74, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x22, + 0xcc, 0x01, 0x0a, 0x11, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x16, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x45, + 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x14, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x6d, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, + 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x02, 0x52, 0x07, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x0d, 0x6c, 0x6c, 0x6d, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x63, - 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x75, 0x6e, 0x6f, - 0x4c, 0x4c, 0x4d, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x09, 0x74, 0x6f, - 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x11, 0x45, 0x6d, 0x62, 0x65, - 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, - 0x16, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x65, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x22, 0x76, + 0x0a, 0x14, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x6c, 0x6c, 0x6d, 0x5f, 0x61, 0x70, + 0x69, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6c, + 0x6d, 0x41, 0x70, 0x69, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x7a, 0x0a, 0x10, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x16, 0x65, 0x6d, + 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x6f, + 0x4c, 0x4c, 0x4d, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x14, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, + 0x78, 0x74, 0x32, 0xa5, 0x01, 0x0a, 0x08, 0x55, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x76, 0x31, 0x12, + 0x4b, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4c, 0x4c, 0x4d, 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, + 0x4c, 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, + 0x19, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x10, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x4c, 0x4d, + 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x1a, 0x2e, 0x75, 0x6e, 0x6f, + 0x4c, 0x4c, 0x4d, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x4c, 0x4d, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0x5e, 0x0a, 0x0e, 0x55, 0x6e, + 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x76, 0x31, 0x12, 0x4c, 0x0a, 0x13, + 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x4c, 0x4c, 0x4d, 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x45, 0x6d, 0x62, + 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x14, 0x65, 0x6d, 0x62, - 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x02, - 0x52, 0x07, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x75, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, - 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, - 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x22, 0x76, 0x0a, 0x14, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, - 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, - 0x0a, 0x0c, 0x6c, 0x6c, 0x6d, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6c, 0x6d, 0x41, 0x70, 0x69, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x7a, - 0x0a, 0x10, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x52, 0x0a, 0x16, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x45, 0x6d, 0x62, 0x65, - 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x14, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x32, 0xa5, 0x01, 0x0a, 0x08, 0x55, - 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x76, 0x31, 0x12, 0x4b, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x4c, 0x4d, 0x12, 0x18, 0x2e, - 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x19, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, - 0x2e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x4c, 0x4d, 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, - 0x4d, 0x2e, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x1a, 0x1a, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x50, 0x61, 0x72, 0x74, - 0x69, 0x61, 0x6c, 0x4c, 0x4c, 0x4d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x30, 0x01, 0x32, 0x5e, 0x0a, 0x0e, 0x55, 0x6e, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, - 0x6e, 0x67, 0x76, 0x31, 0x12, 0x4c, 0x0a, 0x13, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x4c, 0x4d, 0x12, 0x18, 0x2e, 0x75, 0x6e, - 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x75, 0x6e, 0x6f, 0x4c, 0x4c, 0x4d, 0x2e, 0x45, - 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/model/unollm.proto b/model/unollm.proto index cea9a28..7376cdd 100644 --- a/model/unollm.proto +++ b/model/unollm.proto @@ -13,6 +13,7 @@ message LLMChatCompletionMessage { string role = 1; string content = 2; optional string tool_call_id = 3; + repeated string images = 4; } diff --git a/provider/Anthropic/api.go b/provider/Anthropic/api.go new file mode 100644 index 0000000..1c3618a --- /dev/null +++ b/provider/Anthropic/api.go @@ -0,0 +1,87 @@ +package anthropic + +import ( + "encoding/xml" + "net/http" +) + +type Client struct { + key string + hc *http.Client +} + +func NewClient(key string) *Client { + return &Client{ + key: key, + hc: &http.Client{}, + } +} + +type Message struct { + Role string `json:"role"` + Content string `json:"content"` +} + +type ChatCompletionRequest struct { + Model string `json:"model"` + Messages []Message `json:"messages"` + MaxTokens int `json:"max_tokens"` // 4096 + Stream bool `json:"stream,omitempty"` + Temperature float64 `json:"temperature,omitempty"` + TopP float64 `json:"top_p,omitempty"` + TopK float64 `json:"top_k,omitempty"` +} + +type Content struct { + Text string `json:"text"` + Type string `json:"type"` +} + +type Usage struct { + InputTokens int `json:"input_tokens"` + OutputTokens int `json:"output_tokens"` +} +type ChatCompletionResponse struct { + Content []Content `json:"content"` + Id string `json:"id"` + Model string `json:"model"` + Role string `json:"role"` + StopReason string `json:"stop_reason"` + StopSequence string `json:"stop_sequence,omitempty"` + Type string `json:"type"` + Usage Usage `json:"usage"` +} + +const OPUS = "claude-3-opus-20240229" +const SONNET = "claude-3-sonnet-20240229" + +type FunctionCalling struct { + XMLName xml.Name `xml:"config"` // 指定最外层的标签为config +} + +// type StreamMessageStartMessage struct { +// Id string `json:"id"` +// Type string `json:"type"` +// Role string `json:"role"` +// Model string `json:"model"` +// Usage Usage `json:"usage"` +// } + +// type StreamMessageStart struct { +// Type string `json:"type"` +// Message StreamMessageStartMessage `json:"message"` +// } + +type StreamResponseDelta struct { + Type string `json:"type"` + Text string `json:"text"` + StopReason string `json:"stop_reason"` + StopSequence string `json:"stop_sequence"` + Usage Usage `json:"usage"` +} + +type StreamResponse struct { + Type string `json:"type"` + Index int `json:"index"` + Delta StreamResponseDelta `json:"delta"` +} diff --git a/provider/Anthropic/chat_completion.go b/provider/Anthropic/chat_completion.go new file mode 100644 index 0000000..1fa23e9 --- /dev/null +++ b/provider/Anthropic/chat_completion.go @@ -0,0 +1,42 @@ +package anthropic + +import ( + "bytes" + "encoding/json" + "io" + "net/http" +) + +func ChatCompletion(cli *Client, req ChatCompletionRequest) (*ChatCompletionResponse, error) { + reqBytes, err := json.Marshal(req) + if err != nil { + return nil, err + } + + httpreq, err := http.NewRequest( + "POST", + "https://api.anthropic.com/v1/messages", + bytes.NewBuffer(reqBytes), + ) + if err != nil { + return nil, err + } + httpreq.Header.Set("x-api-key", cli.key) + httpreq.Header.Set("anthropic-version", "2023-06-01") + httpreq.Header.Set("content-type", "application/json") + resp, err := cli.hc.Do(httpreq) + if err != nil { + return nil, err + } + defer resp.Body.Close() + bts, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var respp ChatCompletionResponse + err = json.Unmarshal(bts, &respp) + if err != nil { + return nil, err + } + return &respp, nil +} diff --git a/provider/Anthropic/stream_chat_completion.go b/provider/Anthropic/stream_chat_completion.go new file mode 100644 index 0000000..5b28453 --- /dev/null +++ b/provider/Anthropic/stream_chat_completion.go @@ -0,0 +1,79 @@ +package anthropic + +import ( + "bytes" + "encoding/json" + "log" + "net/http" + "strings" + + "go.limit.dev/unollm/utils" +) + +func (c *Client) ChatCompletionStreamingRequest(body *ChatCompletionRequest) (chan StreamResponse, error) { + body.Stream = true + reqBody, err := json.Marshal(body) + if err != nil { + return nil, err + + } + + req, err := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", bytes.NewReader(reqBody)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("x-api-key", c.key) + req.Header.Set("anthropic-version", "2023-06-01") + req.Header.Set("X-Stainless-Stream-Helper", "messages") + + resp, err := c.hc.Do(req) + if err != nil { + return nil, err + + } + + reader := utils.NewEventStreamReader(resp.Body, 4096) + + res := make(chan StreamResponse) + + go func() error { + defer resp.Body.Close() + var jj map[string]any + var jjj StreamResponse + for reader.Scanner.Scan() { + text := reader.Scanner.Text() + // read from first \n to the end of the text + event := text[:strings.Index(text, "\n")] + text = text[strings.Index(text, "\n")+1+6:] + log.Println(event) + log.Println(text) + if strings.Contains(event, "error") { + log.Println(text) + break + } + if strings.Contains(event, "message_stop") { + jjj.Delta.Usage.InputTokens = int(jj["message"].(map[string]any)["usage"].(map[string]any)["input_tokens"].(float64)) + res <- StreamResponse{Type: "STOP", Delta: StreamResponseDelta{ + Usage: jjj.Delta.Usage, + }} + return nil + } + if jj != nil { + err = json.NewDecoder(strings.NewReader(text)).Decode(&jjj) + if err != nil { + log.Println(err) + return nil + } + res <- jjj + } else { + err := json.NewDecoder(strings.NewReader(text)).Decode(&jj) + if err != nil { + break + } + } + } + return reader.Scanner.Err() + }() + return res, nil +} diff --git a/provider/ChatGLM/api.go b/provider/ChatGLM/api.go index 91d490e..dde6db9 100644 --- a/provider/ChatGLM/api.go +++ b/provider/ChatGLM/api.go @@ -10,9 +10,22 @@ const ( ModelGLM4V = "glm-4v" ) +type ChatCompletionTextContent struct { + Type string `json:"type"` + Text string `json:"text"` +} + +type Image struct { + Url string `json:"url"` +} +type ChatCompletionImageContent struct { + Type string `json:"type"` + ImageUrl Image `json:"image_url"` +} + type ChatCompletionMessage struct { Role string `json:"role"` - Content string `json:"content"` + Content any `json:"content"` ToolCalls []GLMToolCall `json:"tool_calls,omitempty"` } diff --git a/relay/reqTransformer/ChatGLM.go b/relay/reqTransformer/ChatGLM.go index 04bdd3e..4a89eab 100644 --- a/relay/reqTransformer/ChatGLM.go +++ b/relay/reqTransformer/ChatGLM.go @@ -49,9 +49,20 @@ func ChatGLMGrpcChatCompletionReq(rs *model.LLMRequestSchema) ChatGLM.ChatComple } for _, m := range messages { + contents := make([]any, 0) + contents = append(contents, ChatGLM.ChatCompletionTextContent{ + Type: "text", + Text: m.GetContent(), + }) + for _, i := range m.GetImages() { + contents = append(contents, ChatGLM.ChatCompletionImageContent{ + Type: "image_url", + ImageUrl: ChatGLM.Image{Url: i}, + }) + } req.Messages = append(req.Messages, ChatGLM.ChatCompletionMessage{ Role: m.GetRole(), - Content: m.GetContent(), + Content: contents, }) } return req @@ -88,8 +99,13 @@ func ChatGLMFromOpenAIChatCompletionReq(req openai.ChatCompletionRequest) ChatGL for _, m := range req.Messages { zpReq.Messages = append(zpReq.Messages, ChatGLM.ChatCompletionMessage{ - Role: m.Role, - Content: m.Content, + Role: m.Role, + Content: []any{ + ChatGLM.ChatCompletionTextContent{ + Type: "text", + Text: m.Content, + }, + }, }) } return zpReq diff --git a/relay/reqTransformer/ChatGPT.go b/relay/reqTransformer/ChatGPT.go index 814e73b..ea55342 100644 --- a/relay/reqTransformer/ChatGPT.go +++ b/relay/reqTransformer/ChatGPT.go @@ -99,9 +99,22 @@ func ChatGPTGrpcChatCompletionReq(rs *model.LLMRequestSchema) openai.ChatComplet messages := rs.GetMessages() var openaiMessages []openai.ChatCompletionMessage for _, m := range messages { + content := make([]openai.ChatMessagePart, 0) + content = append(content, openai.ChatMessagePart{ + Type: "text", + Text: m.GetContent(), + }) + for _, i := range m.GetImages() { + content = append(content, openai.ChatMessagePart{ + Type: "image_url", + ImageURL: &openai.ChatMessageImageURL{ + URL: i, + }, + }) + } openaiMessages = append(openaiMessages, openai.ChatCompletionMessage{ - Role: m.GetRole(), - Content: m.GetContent(), + Role: m.GetRole(), + MultiContent: content, }) } if len(rs.LlmRequestInfo.Functions) == 0 { diff --git a/relay/respTransformer/ChatGLM_Grpc.go b/relay/respTransformer/ChatGLM_Grpc.go index a597e55..91acfa1 100644 --- a/relay/respTransformer/ChatGLM_Grpc.go +++ b/relay/respTransformer/ChatGLM_Grpc.go @@ -10,7 +10,7 @@ func ChatGLMToGrpcCompletion(res ChatGLM.ChatCompletionResponse) (*model.LLMResp content := res.Choices[0].Message.Content retMessage := model.LLMChatCompletionMessage{ Role: res.Choices[0].Message.Role, - Content: content, + Content: content.(string), } count := model.LLMTokenCount{ TotalToken: int64(res.Usage.TotalTokens), @@ -53,7 +53,7 @@ func ChatGLMToGrpcStream(_r *ChatGLM.ChatCompletionStreamingResponse, sv model.U resp := model.PartialLLMResponse{ ToolCalls: toolCalls, Response: &model.PartialLLMResponse_Content{ - Content: chunk.Choices[0].Delta.Content, + Content: chunk.Choices[0].Delta.Content.(string), }, } sv.Send(&resp) diff --git a/tests_grpc/anthropic_test.go b/tests_grpc/anthropic_test.go new file mode 100644 index 0000000..6f4d252 --- /dev/null +++ b/tests_grpc/anthropic_test.go @@ -0,0 +1,83 @@ +package tests_grpc + +import ( + "context" + "log" + "os" + "testing" + + "github.com/joho/godotenv" + "go.limit.dev/unollm/grpcServer" + "go.limit.dev/unollm/model" + "go.limit.dev/unollm/utils" +) + +func TestAnthropic(t *testing.T) { + godotenv.Load("../.env") + + messages := make([]*model.LLMChatCompletionMessage, 0) + messages = append(messages, &model.LLMChatCompletionMessage{ + Role: "user", + Content: "假如今天下大雨,我是否需要带伞?", + }) + AnthropicApiKey := os.Getenv("TEST_ANTHROPIC_API") + req_info := model.LLMRequestInfo{ + LlmApiType: grpcServer.ANTHROPIC_LLM_API, + Model: "claude-3-opus-20240229", + Temperature: 0.9, + TopP: 0.9, + TopK: 1, + Url: "", + Token: AnthropicApiKey, + } + req := model.LLMRequestSchema{ + Messages: messages, + LlmRequestInfo: &req_info, + } + mockServer := grpcServer.UnoForwardServer{} + res, err := mockServer.BlockingRequestLLM(context.Background(), &req) + if err != nil { + t.Error(err) + } + log.Println("res: ", res) +} + +func TestAnthropicStreaming(t *testing.T) { + godotenv.Load("../.env") + + messages := make([]*model.LLMChatCompletionMessage, 0) + messages = append(messages, &model.LLMChatCompletionMessage{ + Role: "user", + Content: "假如今天下大雨,我是否需要带伞?", + }) + AnthropicApiKey := os.Getenv("TEST_ANTHROPIC_API") + req_info := model.LLMRequestInfo{ + LlmApiType: grpcServer.ANTHROPIC_LLM_API, + Model: "claude-3-opus-20240229", + Temperature: 0.9, + TopP: 0.9, + TopK: 1, + Url: "", + Token: AnthropicApiKey, + } + req := model.LLMRequestSchema{ + Messages: messages, + LlmRequestInfo: &req_info, + } + mockServer := grpcServer.UnoForwardServer{} + mockServerPipe := utils.MockServerStream{ + Stream: make(chan *model.PartialLLMResponse, 1000), + } + err := mockServer.StreamRequestLLM(&req, &mockServerPipe) + if err != nil { + t.Error(err) + } + for { + res := <-mockServerPipe.Stream + log.Println(res) + if res.LlmTokenCount != nil { + log.Println(res.LlmTokenCount) + return + } + } +} diff --git a/tests_grpc/chatglm_test.go b/tests_grpc/chatglm_test.go index 3ffc980..c8b7d04 100644 --- a/tests_grpc/chatglm_test.go +++ b/tests_grpc/chatglm_test.go @@ -112,6 +112,7 @@ func TestChatGLMFunctionCalling(t *testing.T) { }, { Name: "unit", + Type: "string", Enums: []string{"celsius", "fahrenheit"}, }, }, @@ -143,3 +144,44 @@ func TestChatGLMFunctionCalling(t *testing.T) { } log.Printf("res: %#v", res.ToolCalls[0]) } + +func TestChatGLMImageStreaming(t *testing.T) { + godotenv.Load("../.env") + url := "https://www.baidu.com/img/flexible/logo/pc/result@2.png" + messages := make([]*model.LLMChatCompletionMessage, 0) + messages = append(messages, &model.LLMChatCompletionMessage{ + Role: "user", + Content: "请描述这张图片", + Images: []string{url}, + }) + zhipuaiApiKey := os.Getenv("TEST_ZHIPUAI_API") + req_info := model.LLMRequestInfo{ + LlmApiType: grpcServer.CHATGLM_LLM_API, + Model: ChatGLM.ModelGLM4V, + Temperature: 0.9, + TopP: 0.9, + TopK: 1, + Url: "", + Token: zhipuaiApiKey, + } + req := model.LLMRequestSchema{ + Messages: messages, + LlmRequestInfo: &req_info, + } + mockServer := grpcServer.UnoForwardServer{} + mockServerPipe := utils.MockServerStream{ + Stream: make(chan *model.PartialLLMResponse, 1000), + } + err := mockServer.StreamRequestLLM(&req, &mockServerPipe) + if err != nil { + t.Error(err) + } + for { + res := <-mockServerPipe.Stream + log.Println(res) + if res.LlmTokenCount != nil { + log.Println(res.LlmTokenCount) + return + } + } +} diff --git a/tests_grpc/openai_test.go b/tests_grpc/openai_test.go index c80762e..5b834b2 100644 --- a/tests_grpc/openai_test.go +++ b/tests_grpc/openai_test.go @@ -151,3 +151,45 @@ func TestOpenAIEmbedding(t *testing.T) { } log.Printf("res: %#v", res) } + +func TestOpenAIImageStreaming(t *testing.T) { + godotenv.Load("../.env") + OPENAIApiKey := os.Getenv("TEST_OPENAI_API") + url := "https://www.baidu.com/img/flexible/logo/pc/result@2.png" + messages := make([]*model.LLMChatCompletionMessage, 0) + messages = append(messages, &model.LLMChatCompletionMessage{ + Role: "user", + Content: "请描述这张图片", + Images: []string{url}, + }) + + req_info := model.LLMRequestInfo{ + LlmApiType: grpcServer.OPENAI_LLM_API, + Model: openai.GPT4VisionPreview, + Temperature: 0.9, + TopP: 0.9, + TopK: 1, + Url: "https://api.openai-sb.com/v1", + Token: OPENAIApiKey, + } + req := model.LLMRequestSchema{ + Messages: messages, + LlmRequestInfo: &req_info, + } + mockServer := grpcServer.UnoForwardServer{} + mockServerPipe := utils.MockServerStream{ + Stream: make(chan *model.PartialLLMResponse, 1000), + } + err := mockServer.StreamRequestLLM(&req, &mockServerPipe) + if err != nil { + t.Fatal(err) + } + for { + res := <-mockServerPipe.Stream + log.Println(res) + if res.LlmTokenCount != nil { + log.Println(res.LlmTokenCount) + return + } + } +}