mirror of
https://github.com/coaidev/coai.git
synced 2025-05-19 13:00:14 +09:00
add sparkdesk, slack-claude model
This commit is contained in:
parent
b08c36bc21
commit
ec45794952
@ -56,8 +56,13 @@
|
||||
- GPT-4-Reverse (_gpt-4_)
|
||||
- DALL-E
|
||||
- Claude
|
||||
- Slack-Claude (unstable)
|
||||
- Claude-2
|
||||
- Claude-2-100k
|
||||
- SparkDesk 讯飞星火
|
||||
- v1.5
|
||||
- v2.0
|
||||
|
||||
- More models are under development...
|
||||
|
||||
## 📚 预览 | Screenshots
|
||||
|
@ -2,6 +2,8 @@ package adapter
|
||||
|
||||
import (
|
||||
"chat/adapter/chatgpt"
|
||||
"chat/adapter/slack"
|
||||
"chat/adapter/sparkdesk"
|
||||
"chat/globals"
|
||||
"chat/utils"
|
||||
"github.com/spf13/viper"
|
||||
@ -14,11 +16,13 @@ type ChatProps struct {
|
||||
Message []globals.Message
|
||||
}
|
||||
|
||||
type Hook func(data string) error
|
||||
|
||||
func NewChatRequest(props *ChatProps, hook Hook) error {
|
||||
func NewChatRequest(props *ChatProps, hook globals.Hook) error {
|
||||
if globals.IsClaudeModel(props.Model) {
|
||||
return nil // work in progress
|
||||
instance := slack.NewChatInstanceFromConfig()
|
||||
return instance.CreateStreamChatRequest(&slack.ChatProps{
|
||||
Message: props.Message,
|
||||
}, hook)
|
||||
|
||||
} else if globals.IsChatGPTModel(props.Model) {
|
||||
instance := chatgpt.NewChatInstanceFromModel(&chatgpt.InstanceProps{
|
||||
Model: props.Model,
|
||||
@ -33,6 +37,13 @@ func NewChatRequest(props *ChatProps, hook Hook) error {
|
||||
Message: props.Message,
|
||||
Token: utils.Multi(globals.IsGPT4Model(props.Model) || props.Reversible || props.Infinity, -1, 2000),
|
||||
}, hook)
|
||||
|
||||
} else if globals.IsSparkDeskModel(props.Model) {
|
||||
return sparkdesk.NewChatInstance().CreateStreamChatRequest(&sparkdesk.ChatProps{
|
||||
Message: props.Message,
|
||||
Token: 2048,
|
||||
}, hook)
|
||||
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ func (c *ChatInstance) CreateChatRequest(props *ChatProps) (string, error) {
|
||||
}
|
||||
|
||||
// CreateStreamChatRequest is the stream response body for chatgpt
|
||||
func (c *ChatInstance) CreateStreamChatRequest(props *ChatProps, callback func(string) error) error {
|
||||
func (c *ChatInstance) CreateStreamChatRequest(props *ChatProps, callback globals.Hook) error {
|
||||
return utils.EventSource(
|
||||
"POST",
|
||||
c.GetChatEndpoint(),
|
||||
|
24
adapter/slack/chat.go
Normal file
24
adapter/slack/chat.go
Normal file
@ -0,0 +1,24 @@
|
||||
package slack
|
||||
|
||||
import (
|
||||
"chat/globals"
|
||||
"context"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type ChatProps struct {
|
||||
Message []globals.Message
|
||||
}
|
||||
|
||||
func (c *ChatInstance) CreateStreamChatRequest(props *ChatProps, hook globals.Hook) error {
|
||||
if err := c.Instance.NewChannel(viper.GetString("slack.channel")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.Instance.Reply(context.Background(), c.FormatMessage(props.Message), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.ProcessPartialResponse(resp, hook)
|
||||
}
|
77
adapter/slack/struct.go
Normal file
77
adapter/slack/struct.go
Normal file
@ -0,0 +1,77 @@
|
||||
package slack
|
||||
|
||||
import (
|
||||
"chat/globals"
|
||||
"fmt"
|
||||
"github.com/bincooo/claude-api"
|
||||
"github.com/bincooo/claude-api/types"
|
||||
"github.com/bincooo/claude-api/vars"
|
||||
"github.com/spf13/viper"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ChatInstance struct {
|
||||
BotId string
|
||||
Token string
|
||||
Instance types.Chat
|
||||
}
|
||||
|
||||
func (c *ChatInstance) GetBotId() string {
|
||||
return c.BotId
|
||||
}
|
||||
|
||||
func (c *ChatInstance) GetToken() string {
|
||||
return c.Token
|
||||
}
|
||||
|
||||
func (c *ChatInstance) GetInstance() types.Chat {
|
||||
return c.Instance
|
||||
}
|
||||
|
||||
func NewChatInstance(botId, token string) *ChatInstance {
|
||||
options := claude.NewDefaultOptions(token, botId, vars.Model4Slack)
|
||||
if instance, err := claude.New(options); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
return &ChatInstance{
|
||||
BotId: botId,
|
||||
Token: token,
|
||||
Instance: instance,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewChatInstanceFromConfig() *ChatInstance {
|
||||
return NewChatInstance(
|
||||
viper.GetString("slack.bot_id"),
|
||||
viper.GetString("slack.token"),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ChatInstance) FormatMessage(message []globals.Message) string {
|
||||
result := make([]string, len(message))
|
||||
for i, item := range message {
|
||||
result[i] = fmt.Sprintf("%s: %s", item.Role, item.Content)
|
||||
}
|
||||
|
||||
return strings.Join(result, "\n\n")
|
||||
}
|
||||
|
||||
func (c *ChatInstance) ProcessPartialResponse(res chan types.PartialResponse, hook globals.Hook) error {
|
||||
for {
|
||||
select {
|
||||
case data, ok := <-res:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
if data.Error != nil {
|
||||
return data.Error
|
||||
} else if data.Text != "" {
|
||||
if err := hook(data.Text); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
54
adapter/sparkdesk/chat.go
Normal file
54
adapter/sparkdesk/chat.go
Normal file
@ -0,0 +1,54 @@
|
||||
package sparkdesk
|
||||
|
||||
import (
|
||||
"chat/globals"
|
||||
"chat/utils"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ChatProps struct {
|
||||
Message []globals.Message
|
||||
Token int
|
||||
}
|
||||
|
||||
func (c *ChatInstance) CreateStreamChatRequest(props *ChatProps, hook globals.Hook) error {
|
||||
var conn *utils.WebSocket
|
||||
if conn = utils.NewWebsocketClient(c.GenerateUrl()); conn == nil {
|
||||
return fmt.Errorf("sparkdesk error: websocket connection failed")
|
||||
}
|
||||
defer conn.DeferClose()
|
||||
|
||||
if err := conn.SendJSON(&ChatRequest{
|
||||
Header: RequestHeader{
|
||||
AppId: c.AppId,
|
||||
},
|
||||
Payload: RequestPayload{
|
||||
Message: MessagePayload{
|
||||
Text: props.Message,
|
||||
},
|
||||
},
|
||||
Parameter: RequestParameter{
|
||||
Chat: ChatParameter{
|
||||
Domain: c.Model,
|
||||
MaxToken: props.Token,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
form := utils.ReadForm[ChatResponse](conn)
|
||||
if form == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if form.Header.Code != 0 {
|
||||
return fmt.Errorf("sparkdesk error: %s (sid: %s)", form.Header.Message, form.Header.Sid)
|
||||
}
|
||||
|
||||
if err := hook(form.Payload.Choices.Text[0].Content); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
72
adapter/sparkdesk/struct.go
Normal file
72
adapter/sparkdesk/struct.go
Normal file
@ -0,0 +1,72 @@
|
||||
package sparkdesk
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ChatInstance struct {
|
||||
AppId string
|
||||
ApiSecret string
|
||||
ApiKey string
|
||||
Model string
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
func NewChatInstance() *ChatInstance {
|
||||
return &ChatInstance{
|
||||
AppId: viper.GetString("sparkdesk.app_id"),
|
||||
ApiSecret: viper.GetString("sparkdesk.api_secret"),
|
||||
ApiKey: viper.GetString("sparkdesk.api_key"),
|
||||
Model: viper.GetString("sparkdesk.model"),
|
||||
Endpoint: viper.GetString("sparkdesk.endpoint"),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChatInstance) CreateUrl(host, date, auth string) string {
|
||||
v := make(url.Values)
|
||||
v.Add("host", host)
|
||||
v.Add("date", date)
|
||||
v.Add("authorization", auth)
|
||||
return fmt.Sprintf("%s?%s", c.Endpoint, v.Encode())
|
||||
}
|
||||
|
||||
func (c *ChatInstance) Sign(data, key string) string {
|
||||
mac := hmac.New(sha256.New, []byte(key))
|
||||
mac.Write([]byte(data))
|
||||
return base64.StdEncoding.EncodeToString(mac.Sum(nil))
|
||||
}
|
||||
|
||||
// GenerateUrl will generate the signed url for sparkdesk api
|
||||
func (c *ChatInstance) GenerateUrl() string {
|
||||
uri, err := url.Parse(c.Endpoint)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
date := time.Now().UTC().Format(time.RFC1123)
|
||||
data := strings.Join([]string{
|
||||
fmt.Sprintf("host: %s", uri.Host),
|
||||
fmt.Sprintf("date: %s", date),
|
||||
fmt.Sprintf("GET %s HTTP/1.1", uri.Path),
|
||||
}, "\n")
|
||||
|
||||
signature := c.Sign(data, c.ApiSecret)
|
||||
authorization := base64.StdEncoding.EncodeToString([]byte(
|
||||
fmt.Sprintf(
|
||||
"hmac username=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"",
|
||||
c.ApiKey,
|
||||
"hmac-sha256",
|
||||
"host date request-line",
|
||||
signature,
|
||||
),
|
||||
))
|
||||
|
||||
return c.CreateUrl(uri.Host, date, authorization)
|
||||
}
|
60
adapter/sparkdesk/types.go
Normal file
60
adapter/sparkdesk/types.go
Normal file
@ -0,0 +1,60 @@
|
||||
package sparkdesk
|
||||
|
||||
import "chat/globals"
|
||||
|
||||
// ChatRequest is the request body for sparkdesk
|
||||
type ChatRequest struct {
|
||||
Header RequestHeader `json:"header"`
|
||||
Payload RequestPayload `json:"payload"`
|
||||
Parameter RequestParameter `json:"parameter"`
|
||||
}
|
||||
|
||||
type RequestHeader struct {
|
||||
AppId string `json:"app_id"`
|
||||
}
|
||||
|
||||
type RequestPayload struct {
|
||||
Message MessagePayload `json:"message"`
|
||||
}
|
||||
|
||||
type MessagePayload struct {
|
||||
Text []globals.Message `json:"text"`
|
||||
}
|
||||
|
||||
type RequestParameter struct {
|
||||
Chat ChatParameter `json:"chat"`
|
||||
}
|
||||
|
||||
type ChatParameter struct {
|
||||
Domain string `json:"domain"`
|
||||
MaxToken int `json:"max_tokens"`
|
||||
}
|
||||
|
||||
// ChatResponse is the websocket partial response body for sparkdesk
|
||||
type ChatResponse struct {
|
||||
Header struct {
|
||||
Code int `json:"code" required:"true"`
|
||||
Message string `json:"message"`
|
||||
Sid string `json:"sid"`
|
||||
Status int `json:"status"`
|
||||
} `json:"header"`
|
||||
Payload struct {
|
||||
Choices struct {
|
||||
Status int `json:"status"`
|
||||
Seq int `json:"seq"`
|
||||
Text []struct {
|
||||
Role string `json:"role"`
|
||||
Content string `json:"content"`
|
||||
Index int `json:"index"`
|
||||
} `json:"text"`
|
||||
} `json:"choices"`
|
||||
Usage struct {
|
||||
Text struct {
|
||||
QuestionTokens int `json:"question_tokens"`
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
CompletionTokens int `json:"completion_tokens"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const version: string = "3.0.0";
|
||||
export const version: string = "3.1.0";
|
||||
export const deploy: boolean = true;
|
||||
export let rest_api: string = "http://localhost:8094";
|
||||
export let ws_api: string = "ws://localhost:8094";
|
||||
@ -16,9 +16,11 @@ export const supportModels: string[] = [
|
||||
"GPT-3.5-16k",
|
||||
"GPT-4",
|
||||
"GPT-4-32k",
|
||||
"Claude-2",
|
||||
"Claude-2-100k",
|
||||
"SparkDesk 讯飞星火"
|
||||
// "Claude-2",
|
||||
// "Claude-2-100k",
|
||||
];
|
||||
|
||||
export const supportModelConvertor: Record<string, string> = {
|
||||
"GPT-3.5": "gpt-3.5-turbo",
|
||||
"GPT-3.5-16k": "gpt-3.5-turbo-16k",
|
||||
@ -26,6 +28,7 @@ export const supportModelConvertor: Record<string, string> = {
|
||||
"GPT-4-32k": "gpt-4-32k",
|
||||
"Claude-2": "claude-2",
|
||||
"Claude-2-100k": "claude-2-100k",
|
||||
"SparkDesk 讯飞星火": "spark-desk",
|
||||
};
|
||||
|
||||
export function login() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package globals
|
||||
|
||||
type Hook func(data string) error
|
||||
type Message struct {
|
||||
Role string `json:"role"`
|
||||
Content string `json:"content"`
|
||||
|
@ -28,6 +28,7 @@ const (
|
||||
Dalle = "dalle"
|
||||
Claude2 = "claude-2"
|
||||
Claude2100k = "claude-2-100k"
|
||||
SparkDesk = "spark-desk"
|
||||
)
|
||||
|
||||
var GPT3TurboArray = []string{
|
||||
@ -99,6 +100,14 @@ func IsClaudeModel(model string) bool {
|
||||
return in(model, ClaudeModelArray)
|
||||
}
|
||||
|
||||
func IsDalleModel(model string) bool {
|
||||
return model == Dalle
|
||||
}
|
||||
|
||||
func IsSparkDeskModel(model string) bool {
|
||||
return model == SparkDesk
|
||||
}
|
||||
|
||||
func IsLongContextModel(model string) bool {
|
||||
return in(model, LongContextModelArray)
|
||||
}
|
||||
|
10
go.mod
10
go.mod
@ -16,6 +16,10 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/bincooo/claude-api v1.0.2 // indirect
|
||||
github.com/bincooo/requests v0.0.0-20230720064210-7eae5d6c9d1e // indirect
|
||||
github.com/bitly/go-simplejson v0.5.0 // indirect
|
||||
github.com/bytedance/sonic v1.10.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
@ -24,13 +28,16 @@ require (
|
||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gaukas/godicttls v0.0.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
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/goccy/go-json v0.10.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.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
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
@ -39,6 +46,8 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/refraction-networking/utls v1.3.2 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.10.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
@ -46,6 +55,7 @@ require (
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/wangluozhe/fhttp v0.0.0-20230512135433-5c2ebfb4868a // indirect
|
||||
golang.org/x/arch v0.5.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
|
22
go.sum
22
go.sum
@ -38,6 +38,14 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/bincooo/claude-api v1.0.2 h1:qhN+s5vpMRU7e7IN+K+uyCmUDV/jtnihgfST8IC0G1o=
|
||||
github.com/bincooo/claude-api v1.0.2/go.mod h1:qoD2FHwGq2+Ohl5xi+jFFYjAGxP0V1ImeIg6R05uqPQ=
|
||||
github.com/bincooo/requests v0.0.0-20230720064210-7eae5d6c9d1e h1:38ztKJW0K6qQGitqAlcJs8O2nal60qYoS9oNZnpkZWE=
|
||||
github.com/bincooo/requests v0.0.0-20230720064210-7eae5d6c9d1e/go.mod h1:0WuzYU+4cQL/hVbjoncY5TACMTbD9I+pLCdnPjfItp0=
|
||||
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||
github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc=
|
||||
@ -78,6 +86,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk=
|
||||
github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
@ -166,11 +176,15 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
@ -206,10 +220,15 @@ github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYde
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8=
|
||||
github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
|
||||
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
@ -240,6 +259,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
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/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -383,6 +404,7 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -44,6 +44,16 @@ func NewWebsocket(c *gin.Context) *WebSocket {
|
||||
}
|
||||
}
|
||||
|
||||
func NewWebsocketClient(url string) *WebSocket {
|
||||
if conn, _, err := websocket.DefaultDialer.Dial(url, nil); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
return &WebSocket{
|
||||
Conn: conn,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WebSocket) Read() (int, []byte, error) {
|
||||
return w.Conn.ReadMessage()
|
||||
}
|
||||
@ -114,7 +124,7 @@ func (w *WebSocket) GetCache() *redis.Client {
|
||||
return GetCacheFromContext(w.Ctx)
|
||||
}
|
||||
|
||||
func ReadForm[T comparable](w *WebSocket) *T {
|
||||
func ReadForm[T interface{}](w *WebSocket) *T {
|
||||
// golang cannot use generic type in class-like struct
|
||||
// except ping
|
||||
_, message, err := w.Read()
|
||||
|
Loading…
Reference in New Issue
Block a user