feat: 火山V3接口

This commit is contained in:
WingGao 2025-02-12 16:01:52 +08:00 committed by Deng Junhai
parent f2e575d98d
commit 951e46c1b3
7 changed files with 5222 additions and 4289 deletions

View File

@ -4,26 +4,28 @@ import (
adaptercommon "chat/adapter/common" adaptercommon "chat/adapter/common"
"chat/globals" "chat/globals"
"chat/utils" "chat/utils"
"context"
"fmt" "fmt"
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
"github.com/volcengine/volc-sdk-golang/service/maas" "github.com/volcengine/volcengine-go-sdk/volcengine"
"github.com/volcengine/volc-sdk-golang/service/maas/models/api" "io"
) )
const defaultMaxTokens int64 = 1500 const defaultMaxTokens int = 4096
func getMessages(messages []globals.Message) []*api.Message { func getMessages(messages []globals.Message) []*model.ChatCompletionMessage {
result := make([]*api.Message, 0) result := make([]*model.ChatCompletionMessage, 0)
for _, message := range messages { for _, message := range messages {
if message.Role == globals.Tool { if message.Role == globals.Tool {
message.Role = maas.ChatRoleOfFunction message.Role = model.ChatMessageRoleTool
} }
msg := &api.Message{ msg := &model.ChatCompletionMessage{
Role: message.Role, Role: message.Role,
Content: message.Content, Content: &model.ChatCompletionMessageContent{StringValue: volcengine.String(message.Content)},
FunctionCall: getFunctionCall(message.ToolCalls), FunctionCall: getFunctionCall(message.ToolCalls),
ReasoningContent: message.ReasoningContent,
} }
hasPrevious := len(result) > 0 hasPrevious := len(result) > 0
@ -31,7 +33,7 @@ func getMessages(messages []globals.Message) []*api.Message {
// a message should not followed by the same role message, merge them // a message should not followed by the same role message, merge them
if hasPrevious && result[len(result)-1].Role == message.Role { if hasPrevious && result[len(result)-1].Role == message.Role {
prev := result[len(result)-1] prev := result[len(result)-1]
prev.Content += msg.Content prev.Content.StringValue = volcengine.String(*prev.Content.StringValue + *msg.Content.StringValue)
if message.ToolCalls != nil { if message.ToolCalls != nil {
prev.FunctionCall = msg.FunctionCall prev.FunctionCall = msg.FunctionCall
} }
@ -40,8 +42,8 @@ func getMessages(messages []globals.Message) []*api.Message {
} }
// `assistant` message should follow a user or function message, if not has previous message, change the role to `user` // `assistant` message should follow a user or function message, if not has previous message, change the role to `user`
if !hasPrevious && message.Role == maas.ChatRoleOfAssistant { if !hasPrevious && message.Role == model.ChatMessageRoleAssistant {
msg.Role = maas.ChatRoleOfUser msg.Role = model.ChatMessageRoleUser
} }
result = append(result, msg) result = append(result, msg)
@ -50,35 +52,31 @@ func getMessages(messages []globals.Message) []*api.Message {
return result return result
} }
func (c *ChatInstance) GetMaxTokens(token *int) int64 { func (c *ChatInstance) GetMaxTokens(token *int) int {
if token == nil || *token < 0 { if token == nil || *token < 0 {
return defaultMaxTokens return defaultMaxTokens
} }
return int64(*token) return *token
} }
func (c *ChatInstance) CreateRequest(props *adaptercommon.ChatProps) *api.ChatReq { func (c *ChatInstance) CreateRequest(props *adaptercommon.ChatProps) *model.ChatCompletionRequest {
return &api.ChatReq{ return &model.ChatCompletionRequest{
Model: &api.Model{ Model: props.OriginalModel,
Name: props.Model, Messages: getMessages(props.Message),
}, Temperature: utils.GetPtrVal(props.Temperature, 0.),
Messages: getMessages(props.Message), TopP: utils.GetPtrVal(props.TopP, 0.),
Parameters: &api.Parameters{ // TopK无了
TopP: utils.GetPtrVal(props.TopP, 0.), PresencePenalty: utils.GetPtrVal(props.PresencePenalty, 0.),
TopK: int64(utils.GetPtrVal(props.TopK, 0)), FrequencyPenalty: utils.GetPtrVal(props.FrequencyPenalty, 0.),
Temperature: utils.GetPtrVal(props.Temperature, 0.), RepetitionPenalty: utils.GetPtrVal(props.RepetitionPenalty, 0.),
PresencePenalty: utils.GetPtrVal(props.PresencePenalty, 0.), MaxTokens: c.GetMaxTokens(props.MaxTokens),
FrequencyPenalty: utils.GetPtrVal(props.FrequencyPenalty, 0.), FunctionCall: getFunctions(props.Tools),
RepetitionPenalty: utils.GetPtrVal(props.RepetitionPenalty, 0.),
MaxTokens: c.GetMaxTokens(props.MaxTokens),
},
Functions: getFunctions(props.Tools),
} }
} }
func getToolCalls(choice *api.ChatResp) *globals.ToolCalls { func getToolCalls(id string, choiceDelta model.ChatCompletionStreamChoiceDelta) *globals.ToolCalls {
calls := choice.Choice.Message.FunctionCall calls := choiceDelta.FunctionCall
if calls == nil { if calls == nil {
return nil return nil
} }
@ -86,7 +84,7 @@ func getToolCalls(choice *api.ChatResp) *globals.ToolCalls {
return &globals.ToolCalls{ return &globals.ToolCalls{
globals.ToolCall{ globals.ToolCall{
Type: "function", Type: "function",
Id: fmt.Sprintf("%s-%s", calls.Name, choice.ReqId), Id: fmt.Sprintf("%s-%s", calls.Name, id),
Function: globals.ToolCallFunction{ Function: globals.ToolCallFunction{
Name: calls.Name, Name: calls.Name,
Arguments: calls.Arguments, Arguments: calls.Arguments,
@ -95,34 +93,37 @@ func getToolCalls(choice *api.ChatResp) *globals.ToolCalls {
} }
} }
func getChoice(choice *api.ChatResp) *globals.Chunk { func getChoice(choice model.ChatCompletionStreamResponse) *globals.Chunk {
if choice == nil || choice.Choice == nil || choice.Choice.Message == nil { if len(choice.Choices) == 0 {
return &globals.Chunk{Content: ""} return &globals.Chunk{Content: ""}
} }
message := choice.Choice.Message message := choice.Choices[0].Delta
return &globals.Chunk{ return &globals.Chunk{
Content: message.Content, Content: message.Content,
ToolCall: getToolCalls(choice), ToolCall: getToolCalls(choice.ID, message),
} }
} }
func (c *ChatInstance) CreateStreamChatRequest(props *adaptercommon.ChatProps, callback globals.Hook) error { func (c *ChatInstance) CreateStreamChatRequest(props *adaptercommon.ChatProps, callback globals.Hook) error {
req := c.CreateRequest(props) req := c.CreateRequest(props)
channel, err := c.Instance.StreamChat(req) stream, err := c.Instance.CreateChatCompletionStream(context.Background(), req)
if err != nil { if err != nil {
return err return err
} }
defer stream.Close()
for partial := range channel { for {
if partial.Error != nil { recv, err2 := stream.Recv()
return partial.Error if err2 == io.EOF {
return nil
} }
if err2 != nil {
if err := callback(getChoice(partial)); err != nil { return err2
}
if err = callback(getChoice(recv)); err != nil {
return err return err
} }
} }
return nil return nil
} }

View File

@ -3,18 +3,19 @@ package skylark
import ( import (
"chat/globals" "chat/globals"
"chat/utils" "chat/utils"
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
structpb "github.com/golang/protobuf/ptypes/struct" structpb "github.com/golang/protobuf/ptypes/struct"
"github.com/volcengine/volc-sdk-golang/service/maas/models/api" "github.com/volcengine/volc-sdk-golang/service/maas/models/api"
) )
func getFunctionCall(calls *globals.ToolCalls) *api.FunctionCall { func getFunctionCall(calls *globals.ToolCalls) *model.FunctionCall {
if calls == nil || len(*calls) == 0 { if calls == nil || len(*calls) == 0 {
return nil return nil
} }
call := (*calls)[0] call := (*calls)[0]
return &api.FunctionCall{ return &model.FunctionCall{
Name: call.Function.Name, Name: call.Function.Name,
Arguments: call.Function.Arguments, Arguments: call.Function.Arguments,
} }

View File

@ -3,52 +3,26 @@ package skylark
import ( import (
factory "chat/adapter/common" factory "chat/adapter/common"
"chat/globals" "chat/globals"
"github.com/volcengine/volc-sdk-golang/service/maas" "github.com/volcengine/volcengine-go-sdk/service/arkruntime"
"strings"
)
const (
defaultHost = "maas-api.ml-platform-cn-beijing.volces.com"
defaultRegion = "cn-beijing"
) )
type ChatInstance struct { type ChatInstance struct {
Instance *maas.MaaS Instance *arkruntime.Client
} }
func getHost(endpoint string) string { func NewChatInstance(endpoint, apiKey string) *ChatInstance {
seg := strings.Split(endpoint, "://") //https://ark.cn-beijing.volces.com/api/v3
if len(seg) > 1 && seg[1] != "" { instance := arkruntime.NewClientWithApiKey(apiKey, arkruntime.WithBaseUrl(endpoint))
return seg[1]
}
return defaultHost
}
func getRegion(endpoint string) string {
host := getHost(endpoint)
seg := strings.TrimSuffix(strings.TrimPrefix(host, "maas-api.ml-platform-"), ".volces.com")
if seg != "" {
return seg
}
return defaultRegion
}
func NewChatInstance(endpoint, accessKey, secretKey string) *ChatInstance {
instance := maas.NewInstance(getHost(endpoint), getRegion(endpoint))
instance.SetAccessKey(accessKey)
instance.SetSecretKey(secretKey)
return &ChatInstance{ return &ChatInstance{
Instance: instance, Instance: instance,
} }
} }
func NewChatInstanceFromConfig(conf globals.ChannelConfig) factory.Factory { func NewChatInstanceFromConfig(conf globals.ChannelConfig) factory.Factory {
params := conf.SplitRandomSecret(2) params := conf.SplitRandomSecret(1)
return NewChatInstance( return NewChatInstance(
conf.GetEndpoint(), conf.GetEndpoint(),
params[0], params[1], params[0],
) )
} }

9357
app/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -227,7 +227,7 @@ export const ChannelInfos: Record<string, ChannelInfo> = {
models: ["baichuan-53b"], models: ["baichuan-53b"],
}, },
skylark: { skylark: {
endpoint: "https://maas-api.ml-platform-cn-beijing.volces.com", endpoint: "https://ark.cn-beijing.volces.com/api/v3",
format: "<access-key>|<secret-key>", format: "<access-key>|<secret-key>",
models: [ models: [
"skylark-lite-public", "skylark-lite-public",
@ -236,8 +236,8 @@ export const ChannelInfos: Record<string, ChannelInfo> = {
"skylark-chat", "skylark-chat",
], ],
description: description:
"> Skylark 格式密钥请填写获取到的 ak|sk \n" + "> Skylark 格式密钥请填写获取到的 ak|sk 或 apikey \n" +
"> 接入点填写生成的接入点,如 *https://maas-api.ml-platform-cn-beijing.volces.com* \n" + "> 接入点填写生成的接入点,如 *https://ark.cn-beijing.volces.com/api/v3* \n" +
"> Skylark API 的地域字段无需手动填写,系统会自动根据接入点获取 \n", "> Skylark API 的地域字段无需手动填写,系统会自动根据接入点获取 \n",
}, },
bing: { bing: {

4
go.mod
View File

@ -22,6 +22,7 @@ require (
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/spf13/viper v1.16.0 github.com/spf13/viper v1.16.0
github.com/volcengine/volc-sdk-golang v1.0.127 github.com/volcengine/volc-sdk-golang v1.0.127
github.com/volcengine/volcengine-go-sdk v1.0.180
golang.org/x/net v0.15.0 golang.org/x/net v0.15.0
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
) )
@ -45,8 +46,8 @@ require (
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.15.4 // indirect github.com/go-playground/validator/v10 v10.15.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect github.com/joho/godotenv v1.5.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.15.15 // indirect github.com/klauspost/compress v1.15.15 // indirect
@ -75,5 +76,6 @@ require (
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

6
go.sum
View File

@ -210,7 +210,6 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
@ -344,7 +343,9 @@ github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+
github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ=
github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E=
github.com/jhump/protoreflect v1.12.0/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= github.com/jhump/protoreflect v1.12.0/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
@ -559,8 +560,11 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/cli/v2 v2.23.0/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/cli/v2 v2.23.0/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU=
github.com/volcengine/volc-sdk-golang v1.0.127 h1:gQtXzSyzQ9Fj5mQz5HHvjzS2BtOXQV+ONisMZSmQ4Bg= github.com/volcengine/volc-sdk-golang v1.0.127 h1:gQtXzSyzQ9Fj5mQz5HHvjzS2BtOXQV+ONisMZSmQ4Bg=
github.com/volcengine/volc-sdk-golang v1.0.127/go.mod h1:4g6M0qA4IvkSjEkNHe8+bpdYhdwI/A0c8q1I3lgzoNE= github.com/volcengine/volc-sdk-golang v1.0.127/go.mod h1:4g6M0qA4IvkSjEkNHe8+bpdYhdwI/A0c8q1I3lgzoNE=
github.com/volcengine/volcengine-go-sdk v1.0.180 h1:lzcNlaxeGIUdXgDuVH7KJwZYZjIZzaCAYPDh91htU6U=
github.com/volcengine/volcengine-go-sdk v1.0.180/go.mod h1:gfEDc1s7SYaGoY+WH2dRrS3qiuDJMkwqyfXWCa7+7oA=
github.com/wangluozhe/fhttp v0.0.0-20230512135433-5c2ebfb4868a h1:nFqhBDkWfNrI5h8nAOv4orMHi0w3qMrd7GoBFXXZGmc= github.com/wangluozhe/fhttp v0.0.0-20230512135433-5c2ebfb4868a h1:nFqhBDkWfNrI5h8nAOv4orMHi0w3qMrd7GoBFXXZGmc=
github.com/wangluozhe/fhttp v0.0.0-20230512135433-5c2ebfb4868a/go.mod h1:kAK+x1U0Wmy/htOSEeV31JyFBAVndp/orqVJZTq9FxM= github.com/wangluozhe/fhttp v0.0.0-20230512135433-5c2ebfb4868a/go.mod h1:kAK+x1U0Wmy/htOSEeV31JyFBAVndp/orqVJZTq9FxM=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=