Skip to content

Commit 8e98806

Browse files
bincooobincooo
bincooo
authored and
bincooo
committed
feat: add bing model
1 parent 0bd4225 commit 8e98806

File tree

13 files changed

+419
-40
lines changed

13 files changed

+419
-40
lines changed

core/gin/response/message.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,22 @@ var (
2828
CLAUDE_ROLE_FMT = func(role string) string { return fmt.Sprintf("\n\r\n%s: ", role) }
2929
GPT_ROLE_FMT = func(role string) string { return fmt.Sprintf("<|start|>%s\n", role) }
3030
ROLE_FMT = func(role string) string { return fmt.Sprintf("<|%s|>\n", role) }
31+
BING_ROLE_FMT = func(role string) string { return bingFormater(role) }
3132
END = "<|end|>\n\n"
3233
delimiter = "\n\n"
3334
)
3435

36+
func bingFormater(role string) string {
37+
switch role {
38+
case "user":
39+
return "Hu: "
40+
case "assistant":
41+
return "Ai: "
42+
default:
43+
return "Sys: "
44+
}
45+
}
46+
3547
var (
3648
regExp = regexp.MustCompile(`^/(.+)/([a-z]*)$`, regexp.ECMAScript)
3749
regExpClears = []*regexp.Regexp{
@@ -168,6 +180,11 @@ func ConvertRole(ctx *gin.Context, role string) (newRole, end string) {
168180
return
169181
}
170182

183+
if IsBing(completion.Model) {
184+
newRole = BING_ROLE_FMT(role)
185+
return
186+
}
187+
171188
end = END
172189
if IsGPT(completion.Model) {
173190
switch role {
@@ -183,6 +200,10 @@ func ConvertRole(ctx *gin.Context, role string) (newRole, end string) {
183200
return
184201
}
185202

203+
func IsBing(mod string) bool {
204+
return mod == "bing"
205+
}
206+
186207
func splitToMessages(content string, merge bool) (messages []model.Keyv[interface{}]) {
187208
chunkMap := map[string][]byte{
188209
"assistant": []byte("\n\nassistant: "),

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.23.3
55
require (
66
github.com/antonfisher/nested-logrus-formatter v1.3.1
77
github.com/bincooo/coze-api v1.0.2-0.20241204052445-8100a9ce45d0
8+
github.com/bincooo/edge-api v1.0.4-0.20241209110641-d6c9bba09984
89
github.com/bincooo/emit.io v1.0.1-0.20241206102606-d234e60afcc9
910
github.com/bincooo/you.com v0.0.0-20241111060258-85f9deb66109
1011
github.com/bogdanfinn/tls-client v1.7.7

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
5252
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
5353
github.com/bincooo/coze-api v1.0.2-0.20241204052445-8100a9ce45d0 h1:LHJy+OS1JyHNznFu3Rz1LtUsbOI0qxMVH2mtsvATllA=
5454
github.com/bincooo/coze-api v1.0.2-0.20241204052445-8100a9ce45d0/go.mod h1:qhaSqKdvR4T594sBMzp+TKZ+PcaeelAiBMvIE254b6g=
55+
github.com/bincooo/edge-api v1.0.4-0.20241209110641-d6c9bba09984 h1:NERX3sB1nrUUPgAvGCiIUFtC0T7OBRcnwSaIs24Jrys=
56+
github.com/bincooo/edge-api v1.0.4-0.20241209110641-d6c9bba09984/go.mod h1:JMD3hj34imIyW8GLD2cmhynEbG7jXuUQG2/WWtjgzTw=
5557
github.com/bincooo/emit.io v1.0.1-0.20241206102606-d234e60afcc9 h1:xAmw70FCu96WcJpL+m2bZHel+fBGyPFzUTn8tBex7oM=
5658
github.com/bincooo/emit.io v1.0.1-0.20241206102606-d234e60afcc9/go.mod h1:OJbKJoZ6x6vSpCC+JNtfcaXo3ilpvQscWrcGEmtmrZI=
5759
github.com/bincooo/go-annotation v0.0.0-20241129022159-ea84d341fcda h1:bhkDbl8cz++1rXqroCNLYxs2Eu5ac/D3yDkxlUfHL1Y=

relay/alloc/coze/coze.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ func init() {
4242
if len(values) == 0 {
4343
return
4444
}
45+
46+
if !env.GetBool("browser-less.enabled") && env.GetString("browser-less.reversal") == "" {
47+
panic("don't used browser-less, please setting `browser-less.enabled` or `browser-less.reversal`")
48+
}
49+
4550
cookiesContainer = common.NewPollContainer("coze", make([]*account, 0), 60*time.Second) // 报错进入60秒冷却
4651
cookiesContainer.Condition = condition(env.GetString("server.proxied"))
4752
run(env, values...)
@@ -187,7 +192,6 @@ func draftBot(ctx *gin.Context, systemMessage string, chat coze.Chat, completion
187192
PresencePenalty: 0,
188193
ResponseFormat: 0,
189194
}, systemMessage); err != nil {
190-
// 全局配置修改失败,解锁
191195
logger.Error(fmt.Errorf("全局配置修改失败[%s]:%v", botId, err))
192196
return &emit.Error{Code: -1, Err: err}
193197
}

relay/alloc/you/you.go

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -206,43 +206,49 @@ func resetMarked(cookies string) {
206206
}
207207

208208
func hookCloudflare(env *env.Environment) error {
209-
if clearance == "" {
210-
logger.Info("trying cloudflare ...")
209+
if clearance != "" {
210+
return nil
211+
}
211212

212-
mu.Lock()
213-
defer mu.Unlock()
214-
if clearance != "" {
215-
return nil
216-
}
213+
baseUrl := env.GetString("browser-less.reversal")
214+
if !env.GetBool("browser-less.enabled") && baseUrl == "" {
215+
return errors.New("trying cloudflare failed, please setting `browser-less.enabled` or `browser-less.reversal`")
216+
}
217217

218-
baseUrl := env.GetString("browser-less.reversal")
219-
if baseUrl == "" {
220-
baseUrl = "http://127.0.0.1:" + env.GetString("browser-less.port")
221-
}
218+
logger.Info("trying cloudflare ...")
222219

223-
r, err := emit.ClientBuilder(common.HTTPClient).
224-
GET(baseUrl+"/clearance").
225-
DoC(emit.Status(http.StatusOK), emit.IsJSON)
226-
if err != nil {
227-
logger.Error(err)
228-
if emit.IsJSON(r) == nil {
229-
logger.Error(emit.TextResponse(r))
230-
}
231-
return err
232-
}
220+
mu.Lock()
221+
defer mu.Unlock()
222+
if clearance != "" {
223+
return nil
224+
}
233225

234-
defer r.Body.Close()
235-
obj, err := emit.ToMap(r)
236-
if err != nil {
237-
logger.Error(err)
238-
return err
226+
if baseUrl == "" {
227+
baseUrl = "http://127.0.0.1:" + env.GetString("browser-less.port")
228+
}
229+
230+
r, err := emit.ClientBuilder(common.HTTPClient).
231+
GET(baseUrl+"/clearance").
232+
DoC(emit.Status(http.StatusOK), emit.IsJSON)
233+
if err != nil {
234+
logger.Error(err)
235+
if emit.IsJSON(r) == nil {
236+
logger.Error(emit.TextResponse(r))
239237
}
238+
return err
239+
}
240240

241-
data := obj["data"].(map[string]interface{})
242-
clearance = data["cookie"].(string)
243-
userAgent = data["userAgent"].(string)
244-
lang = data["lang"].(string)
241+
defer r.Body.Close()
242+
obj, err := emit.ToMap(r)
243+
if err != nil {
244+
logger.Error(err)
245+
return err
245246
}
247+
248+
data := obj["data"].(map[string]interface{})
249+
clearance = data["cookie"].(string)
250+
userAgent = data["userAgent"].(string)
251+
lang = data["lang"].(string)
246252
return nil
247253
}
248254

relay/llm/bing/adapter.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package bing
2+
3+
import (
4+
"chatgpt-adapter/core/common"
5+
"chatgpt-adapter/core/common/toolcall"
6+
"chatgpt-adapter/core/common/vars"
7+
"chatgpt-adapter/core/gin/inter"
8+
"chatgpt-adapter/core/gin/model"
9+
"chatgpt-adapter/core/gin/response"
10+
"context"
11+
"github.com/bincooo/edge-api"
12+
"github.com/gin-gonic/gin"
13+
"github.com/iocgo/sdk/env"
14+
"github.com/iocgo/sdk/stream"
15+
"strings"
16+
"time"
17+
)
18+
19+
var (
20+
Model = "bing"
21+
)
22+
23+
type api struct {
24+
inter.BaseAdapter
25+
26+
env *env.Environment
27+
holder *response.ContentHolder
28+
}
29+
30+
func (api *api) Match(ctx *gin.Context, model string) (ok bool, err error) {
31+
ok = Model == model
32+
if ok {
33+
var token = ctx.GetString("token")
34+
password := api.env.GetString("server.password")
35+
if password != "" && password != token {
36+
err = response.UnauthorizedError
37+
return
38+
}
39+
}
40+
return
41+
}
42+
43+
func (*api) Models() (slice []model.Model) {
44+
slice = append(slice, model.Model{
45+
Id: Model,
46+
Object: "model",
47+
Created: 1686935002,
48+
By: Model + "-adapter",
49+
})
50+
return
51+
}
52+
53+
func (api *api) HandleMessages(ctx *gin.Context, completion model.Completion) (messages []model.Keyv[interface{}], err error) {
54+
var (
55+
toolMessages = toolcall.ExtractToolMessages(&completion)
56+
)
57+
58+
if messages, err = api.holder.Handle(ctx, completion); err != nil {
59+
return
60+
}
61+
messages = append(messages, toolMessages...)
62+
return
63+
}
64+
65+
func (api *api) ToolChoice(ctx *gin.Context) (ok bool, err error) {
66+
var (
67+
completion = common.GetGinCompletion(ctx)
68+
echo = ctx.GetBool(vars.GinEcho)
69+
)
70+
71+
if echo {
72+
echoMessages(ctx, completion)
73+
return
74+
}
75+
76+
if toolChoice(ctx, completion) {
77+
ok = true
78+
}
79+
return
80+
}
81+
82+
func (api *api) Completion(ctx *gin.Context) (err error) {
83+
var (
84+
completion = common.GetGinCompletion(ctx)
85+
echo = ctx.GetBool(vars.GinEcho)
86+
)
87+
88+
if echo {
89+
echoMessages(ctx, completion)
90+
return
91+
}
92+
93+
request := convertRequest(ctx, completion)
94+
95+
timeout, cancel := context.WithTimeout(ctx.Request.Context(), 10*time.Second)
96+
defer cancel()
97+
conversationId, err := edge.CreateConversation(common.HTTPClient, timeout)
98+
if err != nil {
99+
return
100+
}
101+
102+
message, err := edge.Chat(common.HTTPClient, ctx.Request.Context(), conversationId, request)
103+
if err != nil {
104+
return
105+
}
106+
107+
content := waitResponse(ctx, message, completion.Stream)
108+
if content == "" && response.NotResponse(ctx) {
109+
response.Error(ctx, -1, "EMPTY RESPONSE")
110+
}
111+
return
112+
}
113+
114+
func convertRequest(ctx *gin.Context, completion model.Completion) (content string) {
115+
content = strings.Join(stream.Map(stream.OfSlice(completion.Messages), func(message model.Keyv[interface{}]) string {
116+
convertRole, trun := response.ConvertRole(ctx, message.GetString("role"))
117+
return convertRole + message.GetString("content") + trun
118+
}).ToSlice(), "\n\n")
119+
if content != "" {
120+
convertRole, _ := response.ConvertRole(ctx, "assistant")
121+
content += "\n\n" + convertRole
122+
}
123+
return
124+
}

relay/llm/bing/ctor.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package bing
2+
3+
import (
4+
"chatgpt-adapter/core/gin/inter"
5+
"chatgpt-adapter/core/gin/response"
6+
"github.com/iocgo/sdk/env"
7+
8+
_ "github.com/iocgo/sdk"
9+
)
10+
11+
// @Inject(name = "bing-adapter")
12+
func New(env *env.Environment, holder *response.ContentHolder) inter.Adapter {
13+
return &api{env: env, holder: holder}
14+
}

0 commit comments

Comments
 (0)