package main
import (
"bufio"
"context"
"crypto/tls"
"embed"
"encoding/json"
"errors"
"fmt"
"html/template"
"io"
"io/fs"
"log"
"net/http"
"net/url"
"os"
"regexp"
"strings"
"github.com/BurntSushi/toml"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/go-resty/resty/v2"
"github.com/google/uuid"
"github.com/pkoukk/tiktoken-go"
openai "github.com/sashabaranov/go-openai"
)
//https://chat.openai.com/api/auth/session
//authorization: Bearer
//cookie: _puid
//go:embed templates
var FS embed.FS
var (
configName = "config.toml"
cqhttpApi string // cqhttp api
groupId string // 发送消息的qq群
openaiApi string // openai api
openAiApiKey string // openai api secret key
httpProxy string // openai代理
model string // 使用模型
maxTokens int // 限制token数量
systemPrompt string
qsystemPrompt string
//openai web
openaiWebApi = "http://a.tanwen.net:8080"
openaiWebAccessToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiI5ODcxNDY5NzFAcXEuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWV9LCJodHRwczovL2FwaS5vcGVuYWkuY29tL2F1dGgiOnsidXNlcl9pZCI6InVzZXItRUVCbFhHdlZzbm1vT2xza3lOM2E5UVNSIn0sImlzcyI6Imh0dHBzOi8vYXV0aDAub3BlbmFpLmNvbS8iLCJzdWIiOiJhdXRoMHw2M2FhOWYwNjM4YTk3OTk0N2RiNWFjZWUiLCJhdWQiOlsiaHR0cHM6Ly9hcGkub3BlbmFpLmNvbS92MSIsImh0dHBzOi8vb3BlbmFpLm9wZW5haS5hdXRoMGFwcC5jb20vdXNlcmluZm8iXSwiaWF0IjoxNjgxMjgwMTUwLCJleHAiOjE2ODI0ODk3NTAsImF6cCI6IlRkSkljYmUxNldvVEh0Tjk1bnl5d2g1RTR5T282SXRHIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBtb2RlbC5yZWFkIG1vZGVsLnJlcXVlc3Qgb3JnYW5pemF0aW9uLnJlYWQgb2ZmbGluZV9hY2Nlc3MifQ.eZr-RxhT9dtCek69ZjeGHpPJuuPBSWrIizPyDfQ2VhcXfNG4s6ggdM1hSGqmI2NdXxHGRXaZ88wiRcB6OeA1HSkJXAcD9q1Unk--H1WZK_8wfqnKwgaEkq8b4hhX3p9lWcOkhGhX99k9RH4zaDCZvHNa29WrUf3QGZoJE8CSyiyYaBYX-dD2FxZsiMb2izIAYOZPKuqojlfwG8yDEEJWDH_z4nkVes8_o49KCbENBqNsy3JBznYY8LIO9HJuk5pOB5lCvoWnM_JQKIuYNWEzeUJuYvoC6BySV64Ki8KbdvAvLwXjzheOPfUq5ZaXpM3uJNQS3N5i2_olyrNxu6FYyA"
)
type Config struct {
CqhttpApi string `toml:"cqhttp_api"`
GroupId string `toml:"group_id"`
OpenaiApi string `toml:"openai_api"`
OpenAiApiKey string `toml:"openai_api_key"`
HttpProxy string `toml:"http_proxy"`
Model string `toml:"model"`
MaxTokens int `toml:"max_tokens"`
SystemPrompt string `toml:"system_prompt"`
QsystemPrompt string `toml:"qsystem_prompt"`
}
type Sender struct {
UserId int64 `json:"user_id"` // 发送者 QQ 号
Nickname string // 昵称
Sex string // 性别, male 或 female 或 unknown
Age int32 // 年龄
Card string // 群名片/备注
Area string // 地区
Level string // 成员等级
Role string // 角色, owner 或 admin 或 member
Title string // 专属头衔
}
type Message struct {
MessageType string `json:"message_type"` // private, group 消息类型
SubType string `json:"sub_type"` // group, public 表示消息的子类型
MessageId int32 `json:"message_id"` //消息 ID
UserId int64 `json:"user_id"` //发送者 QQ 号
Message string // 一个消息链
RawMessage string `json:"raw_message"` // CQ 码格式的消息
Font int // 0 字体
Sender Sender // 发送者信息
}
type WebConvMessage struct {
Id string `json:"id"`
Auhor struct {
Role string `json:"role"`
} `json:"author"`
Content struct {
ContentType string `json:"content_type"`
Parts []string `json:"parts"`
} `json:"content"`
EndTurn bool `json:"end_turn"`
}
type WebMessage struct {
Action string `json:"action"`
Messages []WebConvMessage `json:"messages"`
ConversationId string `json:"conversation_id"`
ParentMessageId string `json:"parent_message_id"`
Model string `json:"model"`
}
type WebResMessage struct {
Message WebConvMessage `json:"message"`
ConversationId string `json:"conversation_id"`
}
type OpenAI struct {
client *openai.Client
}
var (
Msg []openai.ChatCompletionMessage
qqData Message
conversationId = ""
parentMessageId = ""
)
func ChatGpt() OpenAI {
config := openai.DefaultConfig(openAiApiKey)
if openaiApi != "" {
config.BaseURL = openaiApi
}
if httpProxy != "" {
proxyUrl, _ := url.Parse(httpProxy)
config.HTTPClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyURL(proxyUrl),
},
}
}
checkTokens(&Msg, model)
return OpenAI{client: openai.NewClientWithConfig(config)}
}
func (ai OpenAI) Conv(message string) {
Msg = append(Msg, openai.ChatCompletionMessage{
Role: openai.ChatMessageRoleUser,
Content: message,
})
if Msg[0].Role != openai.ChatMessageRoleSystem {
Msg = append([]openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
Content: qsystemPrompt,
},
}, Msg...)
}
resp, err := ai.client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: model,
Messages: Msg,
Temperature: 0.7,
TopP: 1.0,
PresencePenalty: 1.0,
FrequencyPenalty: 0,
},
)
if err != nil {
log.Println(err)
return
}
Msg = append(Msg, openai.ChatCompletionMessage{
Role: openai.ChatMessageRoleAssistant,
Content: resp.Choices[0].Message.Content,
})
SendQQMsg(resp.Choices[0].Message.Content)
}
func (ai OpenAI) ConvStream(ctx context.Context, ch chan<- string, messages []openai.ChatCompletionMessage, model string) error {
checkTokens(&messages, model)
messages = append([]openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
Content: systemPrompt,
},
}, messages...)
req := openai.ChatCompletionRequest{
Model: model,
Messages: messages,
Temperature: 0.7,
TopP: 1.0,
PresencePenalty: 1.0,
FrequencyPenalty: 0,
Stream: true,
}
stream, err := ai.client.CreateChatCompletionStream(ctx, req)
if err != nil {
log.Println(err)
return err
}
defer stream.Close()
for {
response, err := stream.Recv()
if errors.Is(err, io.EOF) {
return nil
}
if err != nil && !errors.Is(err, context.Canceled) {
log.Println(err)
return err
}
select {
case <-ctx.Done():
return nil
default:
ch <- response.Choices[0].Delta.Content
}
}
}
func (ai OpenAI) ConvStreamWeb(ch chan string, message string, model string) {
var data WebMessage
var rdata *WebResMessage
id := uuid.NewString()
apiUrl := openaiWebApi
v, ok := os.LookupEnv("openaiWebApi")
if ok {
apiUrl = v
}
conv := WebConvMessage{
Id: id,
Auhor: struct {
Role string `json:"role"`
}{
Role: "user",
},
Content: struct {
ContentType string `json:"content_type"`
Parts []string `json:"parts"`
}{
ContentType: "text",
Parts: []string{message},
},
}
data.Action = "next"
data.Messages = []WebConvMessage{conv}
data.ConversationId = conversationId
data.ParentMessageId = parentMessageId
data.Model = model
d, _ := json.Marshal(data)
req := resty.New().SetBaseURL(apiUrl)
req.SetHeader("Authorization", openaiWebAccessToken)
resp, _ := req.R().
SetDoNotParseResponse(true).
SetHeader("Content-Type", "application/json").
SetHeader("Accept", "text/event-stream").
SetBody(d).Post("/conversation")
defer func(body io.ReadCloser) {
body.Close()
close(ch)
}(resp.RawBody())
reader := bufio.NewReader(resp.RawBody())
for {
line, err := reader.ReadString('\n')
if line == "\n" {
continue
}
if strings.HasSuffix(line, "[DONE]\n") || err != nil {
break
}
json.Unmarshal([]byte(line[5:]), &rdata)
if rdata != nil {
parts := rdata.Message.Content.Parts
if len(parts) != 0 {
ch <- parts[0]
}
if rdata.Message.EndTurn == true {
break
}
conversat
《人工智能》--人工智能Moss.zip
版权申诉
70 浏览量
2024-03-15
14:50:20
上传
评论
收藏 1.01MB ZIP 举报
季风泯灭的季节
- 粉丝: 696
- 资源: 2920
最新资源
- Java项目-基于Springboot+Vue的私人健身与教练预约设计与实现源码+数据库脚本+部署视频+代码讲解视频+全套软件
- Java项目-基于Springboot+Vue的乒乓球预约管理的设计与实现(源码+数据库脚本+部署视频+代码讲解视频+全套软件
- 哆咪付在线换钱系统.zip
- pycharm的优缺点及适用场景.zip
- Java项目-基于Springboot+Vue的留守儿童爱心网站的设计与实现(源码+数据库脚本+部署视频+代码讲解视频+全套软件
- 流行的前端框架都有哪些?详细讲解React前端框架
- JSP宠物医院信息管理系统源码.rar
- Java项目-基于Springboot+Vue的家政服务管理平台的设计与实现(源码+数据库脚本+部署视频+代码讲解视频+全套软件
- 大数据可视化大屏页面-医院大数据展示+源代码+演示地址
- 人工智能-美国加利福尼亚州房价预测实战
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈