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

View File

@ -3,18 +3,19 @@ package skylark
import (
"chat/globals"
"chat/utils"
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
structpb "github.com/golang/protobuf/ptypes/struct"
"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 {
return nil
}
call := (*calls)[0]
return &api.FunctionCall{
return &model.FunctionCall{
Name: call.Function.Name,
Arguments: call.Function.Arguments,
}

View File

@ -3,52 +3,26 @@ package skylark
import (
factory "chat/adapter/common"
"chat/globals"
"github.com/volcengine/volc-sdk-golang/service/maas"
"strings"
)
const (
defaultHost = "maas-api.ml-platform-cn-beijing.volces.com"
defaultRegion = "cn-beijing"
"github.com/volcengine/volcengine-go-sdk/service/arkruntime"
)
type ChatInstance struct {
Instance *maas.MaaS
Instance *arkruntime.Client
}
func getHost(endpoint string) string {
seg := strings.Split(endpoint, "://")
if len(seg) > 1 && seg[1] != "" {
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)
func NewChatInstance(endpoint, apiKey string) *ChatInstance {
//https://ark.cn-beijing.volces.com/api/v3
instance := arkruntime.NewClientWithApiKey(apiKey, arkruntime.WithBaseUrl(endpoint))
return &ChatInstance{
Instance: instance,
}
}
func NewChatInstanceFromConfig(conf globals.ChannelConfig) factory.Factory {
params := conf.SplitRandomSecret(2)
params := conf.SplitRandomSecret(1)
return NewChatInstance(
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"],
},
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>",
models: [
"skylark-lite-public",
@ -236,8 +236,8 @@ export const ChannelInfos: Record<string, ChannelInfo> = {
"skylark-chat",
],
description:
"> Skylark 格式密钥请填写获取到的 ak|sk \n" +
"> 接入点填写生成的接入点,如 *https://maas-api.ml-platform-cn-beijing.volces.com* \n" +
"> Skylark 格式密钥请填写获取到的 ak|sk 或 apikey \n" +
"> 接入点填写生成的接入点,如 *https://ark.cn-beijing.volces.com/api/v3* \n" +
"> Skylark API 的地域字段无需手动填写,系统会自动根据接入点获取 \n",
},
bing: {

4
go.mod
View File

@ -22,6 +22,7 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/viper v1.16.0
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
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/universal-translator v0.18.1 // 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/jmespath/go-jmespath v0.4.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/json-iterator/go v1.1.12 // 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/ini.v1 v1.67.0 // 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
)

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/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.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
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/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/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E=
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/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
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/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/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/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/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/go.mod h1:kAK+x1U0Wmy/htOSEeV31JyFBAVndp/orqVJZTq9FxM=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=