From c8d606a16d481891743ccda5a811d2f9a5f5bdda Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Mon, 13 May 2024 21:50:51 +0800
Subject: [PATCH 01/12] Beta115 (#113)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
---
applogic/gensokyo.go | 55 ++++++++++++++++++++++++++++++++------------
applogic/hunyuan.go | 3 ++-
2 files changed, 42 insertions(+), 16 deletions(-)
diff --git a/applogic/gensokyo.go b/applogic/gensokyo.go
index 246c80c..71369e8 100644
--- a/applogic/gensokyo.go
+++ b/applogic/gensokyo.go
@@ -11,6 +11,7 @@ import (
"net/url"
"strconv"
"strings"
+ "sync"
"github.com/hoshinonyaruko/gensokyo-llm/acnode"
"github.com/hoshinonyaruko/gensokyo-llm/config"
@@ -20,7 +21,8 @@ import (
)
var newmsgToStringMap = make(map[string]string)
-var stringToIndexMap = make(map[string]int)
+var stringToIndexMap sync.Map
+var processMessageMu sync.Mutex
// RecordStringById 根据id记录一个string
func RecordStringByNewmsg(id, value string) {
@@ -38,20 +40,30 @@ func GetStringByNewmsg(newmsg string) string {
// IncrementIndex 为给定的字符串递增索引
func IncrementIndex(s string) int {
- // 检查map中是否已经有这个字符串的索引
- if _, exists := stringToIndexMap[s]; !exists {
- // 如果不存在,初始化为0
- stringToIndexMap[s] = 0
+ // 尝试从map中获取值,如果不存在则初始化为0
+ val, loaded := stringToIndexMap.LoadOrStore(s, 0)
+ if !loaded {
+ // 如果这是一个新的键,我们现在将其值设置为1
+ stringToIndexMap.Store(s, 1)
+ return 1
}
- // 递增索引
- stringToIndexMap[s]++
- // 返回新的索引值
- return stringToIndexMap[s]
+
+ // 如果已存在,递增索引
+ newVal := val.(int) + 1
+ stringToIndexMap.Store(s, newVal)
+ return newVal
}
-// ResetIndex 将给定字符串的索引归零
+// ResetIndex 重置或删除给定字符串的索引
func ResetIndex(s string) {
- stringToIndexMap[s] = 0
+ // 直接从map中删除指定的键
+ stringToIndexMap.Delete(s)
+}
+
+// ResetAllIndexes 清空整个索引map
+func ResetAllIndexes() {
+ // 重新初始化stringToIndexMap,因为sync.Map没有提供清空所有条目的直接方法
+ stringToIndexMap = sync.Map{}
}
// checkMessageForHints 检查消息中是否包含给定的提示词
@@ -607,7 +619,11 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
lastMessageID = id // 更新lastMessageID
// 检查是否有未发送的消息部分
key := utils.GetKey(message.GroupID, message.UserID)
- accumulatedMessage, exists := groupUserMessages[key]
+ accumulatedMessageInterface, exists := groupUserMessages.Load(key)
+ var accumulatedMessage string
+ if exists {
+ accumulatedMessage = accumulatedMessageInterface.(string)
+ }
// 提取response字段
if response, ok = responseData["response"].(string); ok {
@@ -721,8 +737,8 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
}
}
- // 清空映射中对应的累积消息
- groupUserMessages[key] = ""
+ // 清空key的值
+ groupUserMessages.Store(key, "")
}
} else {
//发送信息
@@ -909,7 +925,16 @@ func processMessage(response string, msg structs.OnebotGroupMessage, newmesssage
// 达到标点符号,发送累积的整个消息
if messageBuilder.Len() > 0 {
accumulatedMessage := messageBuilder.String()
- groupUserMessages[key] += accumulatedMessage
+ // 锁定
+ processMessageMu.Lock()
+ // 从sync.map读取当前的value
+ valueInterface, _ := groupUserMessages.Load(key)
+ value, _ := valueInterface.(string)
+ // 添加当前messageBuilder中的新内容
+ value += accumulatedMessage
+ // 储存新的内容到sync.map
+ groupUserMessages.Store(key, value)
+ processMessageMu.Unlock() // 完成更新后时解锁
// 判断消息类型,如果是私人消息或私有群消息,发送私人消息;否则,根据配置决定是否发送群消息
if msg.RealMessageType == "group_private" || msg.MessageType == "private" {
diff --git a/applogic/hunyuan.go b/applogic/hunyuan.go
index 59dc088..8168e87 100644
--- a/applogic/hunyuan.go
+++ b/applogic/hunyuan.go
@@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"strings"
+ "sync"
"github.com/hoshinonyaruko/gensokyo-llm/config"
"github.com/hoshinonyaruko/gensokyo-llm/fmtf"
@@ -15,7 +16,7 @@ import (
)
var messageBuilder strings.Builder
-var groupUserMessages = make(map[string]string)
+var groupUserMessages sync.Map
func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
From d23d5239704c1f0a1ab1c4a795b09463d037a843 Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Tue, 14 May 2024 18:22:59 +0800
Subject: [PATCH 02/12] Beta116 (#114)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
---
applogic/chatglm.go | 6 +-
applogic/tongyiqianwen.go | 50 ++---
config/config.go | 442 ++++++++++++++++++++++++++++++++------
3 files changed, 405 insertions(+), 93 deletions(-)
diff --git a/applogic/chatglm.go b/applogic/chatglm.go
index 6373a6e..3405390 100644
--- a/applogic/chatglm.go
+++ b/applogic/chatglm.go
@@ -225,16 +225,16 @@ func (app *App) ChatHandlerGlm(w http.ResponseWriter, r *http.Request) {
}
// 获取配置信息
- apiKey := config.GetGlmApiKey()
+ apiKey := config.GetGlmApiKey(promptstr)
// 创建请求体的映射结构
requestBody := map[string]interface{}{
- "model": config.GetGlmModel(),
+ "model": config.GetGlmModel(promptstr),
"messages": messages,
"do_sample": config.GetGlmDoSample(),
"stream": config.GetuseSse(promptstr),
"temperature": config.GetGlmTemperature(),
"top_p": config.GetGlmTopP(),
- "max_tokens": config.GetGlmMaxTokens(),
+ "max_tokens": config.GetGlmMaxTokens(promptstr),
"stop": config.GetGlmStop(),
//"tools": config.GetGlmTools(), 不太清楚参数格式
"tool_choice": config.GetGlmToolChoice(),
diff --git a/applogic/tongyiqianwen.go b/applogic/tongyiqianwen.go
index e067e90..e35e4d7 100644
--- a/applogic/tongyiqianwen.go
+++ b/applogic/tongyiqianwen.go
@@ -198,7 +198,7 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
fmtf.Printf("Tyqw上下文history:%v\n", history)
// 构建请求到Tyqw API
- apiURL := config.GetTyqwApiPath()
+ apiURL := config.GetTyqwApiPath(promptstr)
// 构造消息历史和当前消息
messages := []map[string]interface{}{}
@@ -216,29 +216,29 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
})
var isIncrementalOutput bool
- if config.GetTyqwSseType() == 1 {
+ if config.GetTyqwSseType(promptstr) == 1 {
isIncrementalOutput = true
}
// 获取配置信息
useSSE := config.GetuseSse(promptstr)
- apiKey := config.GetTyqwKey()
+ apiKey := config.GetTyqwKey(promptstr)
var requestBody map[string]interface{}
if useSSE {
// 构建请求体,根据提供的文档重新调整
requestBody = map[string]interface{}{
"parameters": map[string]interface{}{
- "max_tokens": config.GetTyqwMaxTokens(), // 最大生成的token数
- "temperature": config.GetTyqwTemperature(), // 控制随机性和多样性的温度
- "top_p": config.GetTyqwTopP(), // 核采样方法的概率阈值
- "top_k": config.GetTyqwTopK(), // 采样候选集的大小
- "repetition_penalty": config.GetTyqwRepetitionPenalty(), // 控制重复度的惩罚因子
- "stop": config.GetTyqwStopTokens(), // 停止标记
- "seed": config.GetTyqwSeed(), // 随机数种子
- "result_format": "message", // 返回结果的格式
- "enable_search": config.GetTyqwEnableSearch(), // 是否启用互联网搜索
- "incremental_output": isIncrementalOutput, // 是否使用增量SSE模式,使用增量模式会更快,rwkv和openai不支持增量模式
+ "max_tokens": config.GetTyqwMaxTokens(promptstr), // 最大生成的token数
+ "temperature": config.GetTyqwTemperature(promptstr), // 控制随机性和多样性的温度
+ "top_p": config.GetTyqwTopP(promptstr), // 核采样方法的概率阈值
+ "top_k": config.GetTyqwTopK(promptstr), // 采样候选集的大小
+ "repetition_penalty": config.GetTyqwRepetitionPenalty(), // 控制重复度的惩罚因子
+ "stop": config.GetTyqwStopTokens(), // 停止标记
+ "seed": config.GetTyqwSeed(), // 随机数种子
+ "result_format": "message", // 返回结果的格式
+ "enable_search": config.GetTyqwEnableSearch(), // 是否启用互联网搜索
+ "incremental_output": isIncrementalOutput, // 是否使用增量SSE模式,使用增量模式会更快,rwkv和openai不支持增量模式
},
- "model": config.GetTyqwModel(), // 指定对话模型
+ "model": config.GetTyqwModel(promptstr), // 指定对话模型
"input": map[string]interface{}{
"messages": messages, // 用户与模型的对话历史
},
@@ -251,17 +251,17 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
// 构建请求体,根据提供的文档重新调整
requestBody = map[string]interface{}{
"parameters": map[string]interface{}{
- "max_tokens": config.GetTyqwMaxTokens(), // 最大生成的token数
- "temperature": config.GetTyqwTemperature(), // 控制随机性和多样性的温度
- "top_p": config.GetTyqwTopP(), // 核采样方法的概率阈值
- "top_k": config.GetTyqwTopK(), // 采样候选集的大小
- "repetition_penalty": config.GetTyqwRepetitionPenalty(), // 控制重复度的惩罚因子
- "stop": config.GetTyqwStopTokens(), // 停止标记
- "seed": config.GetTyqwSeed(), // 随机数种子
- "result_format": "message", // 返回结果的格式
- "enable_search": config.GetTyqwEnableSearch(), // 是否启用互联网搜索
+ "max_tokens": config.GetTyqwMaxTokens(promptstr), // 最大生成的token数
+ "temperature": config.GetTyqwTemperature(promptstr), // 控制随机性和多样性的温度
+ "top_p": config.GetTyqwTopP(promptstr), // 核采样方法的概率阈值
+ "top_k": config.GetTyqwTopK(promptstr), // 采样候选集的大小
+ "repetition_penalty": config.GetTyqwRepetitionPenalty(), // 控制重复度的惩罚因子
+ "stop": config.GetTyqwStopTokens(), // 停止标记
+ "seed": config.GetTyqwSeed(), // 随机数种子
+ "result_format": "message", // 返回结果的格式
+ "enable_search": config.GetTyqwEnableSearch(), // 是否启用互联网搜索
},
- "model": config.GetTyqwModel(), // 指定对话模型
+ "model": config.GetTyqwModel(promptstr), // 指定对话模型
"input": map[string]interface{}{
"messages": messages, // 用户与模型的对话历史
},
@@ -402,7 +402,7 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
reader := bufio.NewReader(resp.Body)
var totalUsage structs.GPTUsageInfo
- if config.GetTyqwSseType() == 1 {
+ if config.GetTyqwSseType(promptstr) == 1 {
for {
line, err := reader.ReadString('\n')
if err != nil {
diff --git a/config/config.go b/config/config.go
index d3d2704..745d86a 100644
--- a/config/config.go
+++ b/config/config.go
@@ -2032,14 +2032,38 @@ func GetNo4Promptkeyboard() bool {
return false
}
-// 获取TYQW API路径
-func GetTyqwApiPath() string {
+// GetTyqwApiPath 获取TYQW API路径,可接受basename作为参数
+func GetTyqwApiPath(options ...string) string {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.TyqwApiPath
+ return getTyqwApiPathInternal(options...)
+}
+
+// getTyqwApiPathInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTyqwApiPathInternal(options ...string) string {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TyqwApiPath
+ }
+ return "" // 默认值或错误处理
}
- return "" // 默认值或错误处理
+
+ // 使用传入的 basename
+ basename := options[0]
+ apiPathInterface, err := prompt.GetSettingFromFilename(basename, "TyqwApiPath")
+ if err != nil {
+ log.Println("Error retrieving TyqwApiPath:", err)
+ return getTyqwApiPathInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ apiPath, ok := apiPathInterface.(string)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for TyqwApiPath, fetching default")
+ return getTyqwApiPathInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return apiPath
}
// 获取TYQW最大Token数量,可接受basename作为参数
@@ -2076,44 +2100,140 @@ func getTyqwMaxTokensInternal(options ...string) int {
return maxTokens
}
-// 获取TYQW温度设置
-func GetTyqwTemperature() float64 {
+// GetTyqwTemperature 获取TYQW温度设置,可接受basename作为参数
+func GetTyqwTemperature(options ...string) float64 {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.TyqwTemperature
+ return getTyqwTemperatureInternal(options...)
+}
+
+// getTyqwTemperatureInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTyqwTemperatureInternal(options ...string) float64 {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TyqwTemperature
+ }
+ return 0.0 // 默认值或错误处理
}
- return 0.0 // 默认值或错误处理
+
+ // 使用传入的 basename
+ basename := options[0]
+ temperatureInterface, err := prompt.GetSettingFromFilename(basename, "TyqwTemperature")
+ if err != nil {
+ log.Println("Error retrieving TyqwTemperature:", err)
+ return getTyqwTemperatureInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ temperature, ok := temperatureInterface.(float64)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for TyqwTemperature, fetching default")
+ return getTyqwTemperatureInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return temperature
}
-// 获取TYQW Top P
-func GetTyqwTopP() float64 {
+// GetTyqwTopP 获取TYQW Top P值,可接受basename作为参数
+func GetTyqwTopP(options ...string) float64 {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.TyqwTopP
+ return getTyqwTopPInternal(options...)
+}
+
+// getTyqwTopPInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTyqwTopPInternal(options ...string) float64 {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TyqwTopP
+ }
+ return 0.0 // 默认值或错误处理
}
- return 0.0 // 默认值或错误处理
+
+ // 使用传入的 basename
+ basename := options[0]
+ topPInterface, err := prompt.GetSettingFromFilename(basename, "TyqwTopP")
+ if err != nil {
+ log.Println("Error retrieving TyqwTopP:", err)
+ return getTyqwTopPInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ topP, ok := topPInterface.(float64)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for TyqwTopP, fetching default")
+ return getTyqwTopPInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return topP
}
-// 获取TYQW Top K
-func GetTyqwTopK() int {
+// GetTyqwTopK 获取TYQW Top K设置,可接受basename作为参数
+func GetTyqwTopK(options ...string) int {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.TyqwTopK
+ return getTyqwTopKInternal(options...)
+}
+
+// getTyqwTopKInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTyqwTopKInternal(options ...string) int {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TyqwTopK
+ }
+ return 0 // 默认值或错误处理
}
- return 0 // 默认值或错误处理
+
+ // 使用传入的 basename
+ basename := options[0]
+ topKInterface, err := prompt.GetSettingFromFilename(basename, "TyqwTopK")
+ if err != nil {
+ log.Println("Error retrieving TyqwTopK:", err)
+ return getTyqwTopKInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ topK, ok := topKInterface.(int)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for TyqwTopK, fetching default")
+ return getTyqwTopKInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return topK
}
-// 获取TYQW SSE类型
-func GetTyqwSseType() int {
+// GetTyqwSseType 获取TYQW SSE类型,可接受basename作为参数
+func GetTyqwSseType(options ...string) int {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.TyqwSseType
+ return getTyqwSseTypeInternal(options...)
+}
+
+// getTyqwSseTypeInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTyqwSseTypeInternal(options ...string) int {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TyqwSseType
+ }
+ return 0 // 默认值或错误处理
}
- return 0 // 默认值或错误处理
+
+ // 使用传入的 basename
+ basename := options[0]
+ sseTypeInterface, err := prompt.GetSettingFromFilename(basename, "TyqwSseType")
+ if err != nil {
+ log.Println("Error retrieving TyqwSseType:", err)
+ return getTyqwSseTypeInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ sseType, ok := sseTypeInterface.(int)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for TyqwSseType, fetching default")
+ return getTyqwSseTypeInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return sseType
}
// 获取TYQW用户名
@@ -2196,24 +2316,72 @@ func GetTyqwEnableSearch() bool {
return false // 默认值或错误处理
}
-// 获取TYQW模型名称
-func GetTyqwModel() string {
+// GetTyqwModel 获取TYQW模型名称,可接受basename作为参数
+func GetTyqwModel(options ...string) string {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.TyqwModel
+ return getTyqwModelInternal(options...)
+}
+
+// getTyqwModelInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTyqwModelInternal(options ...string) string {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TyqwModel
+ }
+ return "default-model" // 默认值或错误处理
}
- return "default-model" // 默认值或错误处理
+
+ // 使用传入的 basename
+ basename := options[0]
+ modelInterface, err := prompt.GetSettingFromFilename(basename, "TyqwModel")
+ if err != nil {
+ log.Println("Error retrieving TyqwModel:", err)
+ return getTyqwModelInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ model, ok := modelInterface.(string)
+ if !ok || model == "" { // 检查类型断言是否失败或结果为空字符串
+ log.Println("Type assertion failed or empty string for TyqwModel, fetching default")
+ return getTyqwModelInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return model
}
-// 获取TYQW API Key
-func GetTyqwKey() string {
+// GetTyqwKey 获取TYQW API Key,可接受basename作为参数
+func GetTyqwKey(options ...string) string {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.TyqwApiKey
+ return getTyqwKeyInternal(options...)
+}
+
+// getTyqwKeyInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTyqwKeyInternal(options ...string) string {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TyqwApiKey
+ }
+ return "" // 默认值或错误处理,表示没有找到有效的API Key
+ }
+
+ // 使用传入的 basename
+ basename := options[0]
+ apiKeyInterface, err := prompt.GetSettingFromFilename(basename, "TyqwApiKey")
+ if err != nil {
+ log.Println("Error retrieving TyqwApiKey:", err)
+ return getTyqwKeyInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ apiKey, ok := apiKeyInterface.(string)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for TyqwApiKey, fetching default")
+ return getTyqwKeyInternal() // 递归调用内部函数,不传递任何参数
}
- return "" // 默认值或错误处理,表示没有找到有效的API Key
+
+ return apiKey
}
// 获取TYQW Workspace
@@ -2229,34 +2397,106 @@ func GetTyqworkspace() (string, error) {
return "", fmt.Errorf("configuration instance is not initialized") // 错误处理,当配置实例未初始化时
}
-// GetGlmApiPath 获取GLM API路径
-func GetGlmApiPath() string {
+// GetGlmApiPath 获取GLM API路径,可接受basename作为参数
+func GetGlmApiPath(options ...string) string {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.GlmApiPath
+ return getGlmApiPathInternal(options...)
+}
+
+// getGlmApiPathInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getGlmApiPathInternal(options ...string) string {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.GlmApiPath
+ }
+ return "" // 默认值或错误处理
}
- return "" // 默认值或错误处理
+
+ // 使用传入的 basename
+ basename := options[0]
+ apiPathInterface, err := prompt.GetSettingFromFilename(basename, "GlmApiPath")
+ if err != nil {
+ log.Println("Error retrieving GlmApiPath:", err)
+ return getGlmApiPathInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ apiPath, ok := apiPathInterface.(string)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for GlmApiPath, fetching default")
+ return getGlmApiPathInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return apiPath
}
-// GetGlmModel 获取模型编码
-func GetGlmModel() string {
+// GetGlmModel 获取模型编码,可接受basename作为参数
+func GetGlmModel(options ...string) string {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.GlmModel
+ return getGlmModelInternal(options...)
+}
+
+// getGlmModelInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getGlmModelInternal(options ...string) string {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.GlmModel
+ }
+ return "" // 默认值或错误处理
}
- return ""
+
+ // 使用传入的 basename
+ basename := options[0]
+ modelInterface, err := prompt.GetSettingFromFilename(basename, "GlmModel")
+ if err != nil {
+ log.Println("Error retrieving GlmModel:", err)
+ return getGlmModelInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ model, ok := modelInterface.(string)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for GlmModel, fetching default")
+ return getGlmModelInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return model
}
-// GetGlmApiKey 获取模型编码
-func GetGlmApiKey() string {
+// GetGlmApiKey 获取glm密钥,可接受basename作为参数
+func GetGlmApiKey(options ...string) string {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.GlmApiKey
+ return getGlmApiKeyInternal(options...)
+}
+
+// getGlmApiKeyInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getGlmApiKeyInternal(options ...string) string {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.GlmApiKey
+ }
+ return "" // 默认值或错误处理
}
- return ""
+
+ // 使用传入的 basename
+ basename := options[0]
+ apiKeyInterface, err := prompt.GetSettingFromFilename(basename, "GlmApiKey")
+ if err != nil {
+ log.Println("Error retrieving GlmApiKey:", err)
+ return getGlmApiKeyInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ apiKey, ok := apiKeyInterface.(string)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for GlmApiKey, fetching default")
+ return getGlmApiKeyInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return apiKey
}
// GetGlmMaxTokens 获取模型输出的最大tokens数,可接受basename作为参数
@@ -2293,14 +2533,38 @@ func getGlmMaxTokensInternal(options ...string) int {
return maxTokens
}
-// GetGlmTemperature 获取模型的采样温度
-func GetGlmTemperature() float64 {
+// GetGlmTemperature 获取模型的采样温度,可接受basename作为参数
+func GetGlmTemperature(options ...string) float64 {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.GlmTemperature
+ return getGlmTemperatureInternal(options...)
+}
+
+// getGlmTemperatureInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getGlmTemperatureInternal(options ...string) float64 {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.GlmTemperature
+ }
+ return 0.95 // 默认值或错误处理
+ }
+
+ // 使用传入的 basename
+ basename := options[0]
+ temperatureInterface, err := prompt.GetSettingFromFilename(basename, "GlmTemperature")
+ if err != nil {
+ log.Println("Error retrieving GlmTemperature:", err)
+ return getGlmTemperatureInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ temperature, ok := temperatureInterface.(float64)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for GlmTemperature, fetching default")
+ return getGlmTemperatureInternal() // 递归调用内部函数,不传递任何参数
}
- return 0.95 // 返回默认值
+
+ return temperature
}
// GetGlmDoSample 获取是否启用采样策略
@@ -2343,14 +2607,38 @@ func GetGlmRequestID() string {
return "" // 返回默认值,表示没有设置
}
-// GetGlmTopP 获取核取样概率
-func GetGlmTopP() float64 {
+// GetGlmTopP 获取核取样概率,可接受basename作为参数
+func GetGlmTopP(options ...string) float64 {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.GlmTopP
+ return getGlmTopPInternal(options...)
+}
+
+// getGlmTopPInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getGlmTopPInternal(options ...string) float64 {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.GlmTopP
+ }
+ return 0.7 // 默认值或错误处理
+ }
+
+ // 使用传入的 basename
+ basename := options[0]
+ topPInterface, err := prompt.GetSettingFromFilename(basename, "GlmTopP")
+ if err != nil {
+ log.Println("Error retrieving GlmTopP:", err)
+ return getGlmTopPInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ topP, ok := topPInterface.(float64)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for GlmTopP, fetching default")
+ return getGlmTopPInternal() // 递归调用内部函数,不传递任何参数
}
- return 0.7 // 返回默认值
+
+ return topP
}
// GetGlmStop 获取停止生成的词列表
@@ -2373,12 +2661,36 @@ func GetGlmTools() []string {
return []string{} // 返回空切片,表示没有工具设置
}
-// 获取GroupHintWords列表
-func GetGroupHintWords() []string {
+// GetGroupHintWords 获取GroupHintWords列表,可接受basename作为参数
+func GetGroupHintWords(options ...string) []string {
mu.Lock()
defer mu.Unlock()
- if instance != nil {
- return instance.Settings.GroupHintWords
+ return getGroupHintWordsInternal(options...)
+}
+
+// getGroupHintWordsInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getGroupHintWordsInternal(options ...string) []string {
+ // 检查是否有参数传递进来,以及是否为空字符串
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.GroupHintWords
+ }
+ return nil // 默认值或错误处理
}
- return nil
+
+ // 使用传入的 basename
+ basename := options[0]
+ hintWordsInterface, err := prompt.GetSettingFromFilename(basename, "GroupHintWords")
+ if err != nil {
+ log.Println("Error retrieving GroupHintWords:", err)
+ return getGroupHintWordsInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ hintWords, ok := hintWordsInterface.([]string)
+ if !ok { // 检查类型断言是否失败
+ log.Println("Type assertion failed for GroupHintWords, fetching default")
+ return getGroupHintWordsInternal() // 递归调用内部函数,不传递任何参数
+ }
+
+ return hintWords
}
From 4b1aa8dde3f827618f8f67d27250b0228876574d Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Tue, 14 May 2024 20:22:07 +0800
Subject: [PATCH 03/12] Beta117 (#115)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
---
applogic/gensokyo.go | 2 +-
utils/blacklist.go | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/applogic/gensokyo.go b/applogic/gensokyo.go
index 71369e8..60d5a94 100644
--- a/applogic/gensokyo.go
+++ b/applogic/gensokyo.go
@@ -264,7 +264,7 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
}
if utils.BlacklistIntercept(message, selfid) {
- fmtf.Printf("userid:[%v]这位用户在黑名单中,被拦截", message.UserID)
+ fmtf.Printf("userid:[%v]groupid:[%v]这位用户或群在黑名单中,被拦截", message.UserID, message.GroupID)
return
}
diff --git a/utils/blacklist.go b/utils/blacklist.go
index 6d3b1f2..77b1aea 100644
--- a/utils/blacklist.go
+++ b/utils/blacklist.go
@@ -94,6 +94,26 @@ func WatchBlacklist(filePath string) {
// BlacklistIntercept 检查用户ID是否在黑名单中,如果在,则发送预设消息
func BlacklistIntercept(message structs.OnebotGroupMessage, selfid string) bool {
+ // 检查群ID是否在黑名单中
+ if IsInBlacklist(strconv.FormatInt(message.GroupID, 10)) {
+ // 获取黑名单响应消息
+ responseMessage := config.GetBlacklistResponseMessages()
+
+ // 根据消息类型发送响应
+ if message.RealMessageType == "group_private" || message.MessageType == "private" {
+ if !config.GetUsePrivateSSE() {
+ SendPrivateMessage(message.UserID, responseMessage, selfid)
+ } else {
+ SendSSEPrivateMessage(message.UserID, responseMessage)
+ }
+ } else {
+ SendGroupMessage(message.GroupID, message.UserID, responseMessage, selfid)
+ }
+
+ fmt.Printf("groupid:[%v]这个群在黑名单中,被拦截\n", message.GroupID)
+ return true // 拦截
+ }
+
// 检查用户ID是否在黑名单中
if IsInBlacklist(strconv.FormatInt(message.UserID, 10)) {
// 获取黑名单响应消息
@@ -113,5 +133,6 @@ func BlacklistIntercept(message structs.OnebotGroupMessage, selfid string) bool
fmt.Printf("userid:[%v]这位用户在黑名单中,被拦截\n", message.UserID)
return true // 拦截
}
+
return false // 用户ID不在黑名单中,不拦截
}
From ec731c2f098623884ba4452bc0b7d3b81b7e76aa Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Thu, 16 May 2024 19:05:06 +0800
Subject: [PATCH 04/12] Beta118 (#116)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
* beta118
---
applogic/chatglm.go | 41 +++++++++++++++++--------------
applogic/ernie.go | 15 ++++++++----
applogic/tongyiqianwen.go | 49 ++++++++++++++++++++++---------------
config/config.go | 44 +++++++++++++++++++++++++++++++++
prompt/prompt.go | 23 +++++++++++++++++
template/config_template.go | 2 +-
6 files changed, 130 insertions(+), 44 deletions(-)
diff --git a/applogic/chatglm.go b/applogic/chatglm.go
index 3405390..14b4aac 100644
--- a/applogic/chatglm.go
+++ b/applogic/chatglm.go
@@ -133,7 +133,7 @@ func (app *App) ChatHandlerGlm(w http.ResponseWriter, r *http.Request) {
}
} else {
// 只获取系统提示词
- systemMessage, err := prompt.FindFirstSystemMessage(history)
+ systemMessage, err := prompt.GetFirstSystemMessageStruct(promptstr)
if err != nil {
fmt.Println("Error:", err)
} else {
@@ -164,28 +164,33 @@ func (app *App) ChatHandlerGlm(w http.ResponseWriter, r *http.Request) {
fmtf.Printf("Error getting system history: %v,promptstr[%v]\n", err, promptstr)
return
}
-
- // 处理增强QA逻辑
if config.GetEnhancedQA(promptstr) {
- // 确保系统历史与用户或助手历史数量一致,如果不足,则补足空的历史记录
- // 因为最后一个成员让给当前QA,所以-1
- if len(systemHistory)-2 > len(userHistory) {
- difference := len(systemHistory) - len(userHistory)
+ systemHistory, err := prompt.GetMessagesExcludingSystem(promptstr)
+ if err != nil {
+ fmt.Printf("Error getting system history: %v\n", err)
+ return
+ }
+
+ // 计算需要补足的历史记录数量
+ neededHistoryCount := len(systemHistory) - 2 // 最后两条留给当前QA处理
+ if neededHistoryCount > len(userHistory) {
+ // 补足用户或助手历史
+ difference := neededHistoryCount - len(userHistory)
for i := 0; i < difference; i++ {
- userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
- userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ if i%2 != 0 {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
+ } else {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ }
}
}
- // 如果系统历史中只有一个成员,跳过覆盖逻辑,留给后续处理
- if len(systemHistory) > 1 {
- // 将系统历史(除最后2个成员外)附加到相应的用户或助手历史上,采用倒序方式处理最近的记录
- for i := 0; i < len(systemHistory)-2; i++ {
- sysMsg := systemHistory[i]
- index := len(userHistory) - len(systemHistory) + i
- if index >= 0 && index < len(userHistory) && (userHistory[index].Role == "user" || userHistory[index].Role == "assistant") {
- userHistory[index].Text += fmt.Sprintf(" (%s)", sysMsg.Text)
- }
+ // 附加系统历史到用户或助手历史,除了最后两条
+ for i := 0; i < len(systemHistory)-2; i++ {
+ sysMsg := systemHistory[i]
+ index := len(userHistory) - neededHistoryCount + i
+ if index >= 0 && index < len(userHistory) {
+ userHistory[index].Text += fmt.Sprintf(" (%s)", sysMsg.Text)
}
}
} else {
diff --git a/applogic/ernie.go b/applogic/ernie.go
index 4dbe725..eadb9d8 100644
--- a/applogic/ernie.go
+++ b/applogic/ernie.go
@@ -133,12 +133,17 @@ func (app *App) ChatHandlerErnie(w http.ResponseWriter, r *http.Request) {
// 处理增强QA逻辑
if config.GetEnhancedQA(promptstr) {
// 确保系统历史与用户或助手历史数量一致,如果不足,则补足空的历史记录
- // 因为最后一个成员让给当前QA,所以-1
- if len(systemHistory)-2 > len(userHistory) {
- difference := len(systemHistory) - len(userHistory)
+ // 计算需要补足的历史记录数量
+ neededHistoryCount := len(systemHistory) - 2 // 最后两条留给当前QA处理
+ if neededHistoryCount > len(userHistory) {
+ // 补足用户或助手历史
+ difference := neededHistoryCount - len(userHistory)
for i := 0; i < difference; i++ {
- userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
- userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ if i%2 != 0 {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
+ } else {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ }
}
}
diff --git a/applogic/tongyiqianwen.go b/applogic/tongyiqianwen.go
index e35e4d7..8277437 100644
--- a/applogic/tongyiqianwen.go
+++ b/applogic/tongyiqianwen.go
@@ -128,7 +128,7 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
}
} else {
// 只获取系统提示词
- systemMessage, err := prompt.FindFirstSystemMessage(history)
+ systemMessage, err := prompt.GetFirstSystemMessageStruct(promptstr)
if err != nil {
fmt.Println("Error:", err)
} else {
@@ -138,7 +138,7 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
}
}
}
-
+ // TODO: msgid是空的开始第一句也要处理 插入
// 获取历史信息
if msg.ParentMessageID != "" {
userhistory, err := app.getHistory(msg.ConversationID, msg.ParentMessageID)
@@ -159,28 +159,33 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
fmtf.Printf("Error getting system history: %v,promptstr[%v]\n", err, promptstr)
return
}
-
- // 处理增强QA逻辑
if config.GetEnhancedQA(promptstr) {
- // 确保系统历史与用户或助手历史数量一致,如果不足,则补足空的历史记录
- // 因为最后一个成员让给当前QA,所以-1
- if len(systemHistory)-2 > len(userHistory) {
- difference := len(systemHistory) - len(userHistory)
+ systemHistory, err := prompt.GetMessagesExcludingSystem(promptstr)
+ if err != nil {
+ fmt.Printf("Error getting system history: %v\n", err)
+ return
+ }
+
+ // 计算需要补足的历史记录数量
+ neededHistoryCount := len(systemHistory) - 2 // 最后两条留给当前QA处理
+ if neededHistoryCount > len(userHistory) {
+ // 补足用户或助手历史
+ difference := neededHistoryCount - len(userHistory)
for i := 0; i < difference; i++ {
- userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
- userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ if i%2 != 0 {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
+ } else {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ }
}
}
- // 如果系统历史中只有一个成员,跳过覆盖逻辑,留给后续处理
- if len(systemHistory) > 1 {
- // 将系统历史(除最后2个成员外)附加到相应的用户或助手历史上,采用倒序方式处理最近的记录
- for i := 0; i < len(systemHistory)-2; i++ {
- sysMsg := systemHistory[i]
- index := len(userHistory) - len(systemHistory) + i
- if index >= 0 && index < len(userHistory) && (userHistory[index].Role == "user" || userHistory[index].Role == "assistant") {
- userHistory[index].Text += fmt.Sprintf(" (%s)", sysMsg.Text)
- }
+ // 附加系统历史到用户或助手历史,除了最后两条
+ for i := 0; i < len(systemHistory)-2; i++ {
+ sysMsg := systemHistory[i]
+ index := len(userHistory) - neededHistoryCount + i
+ if index >= 0 && index < len(userHistory) {
+ userHistory[index].Text += fmt.Sprintf(" (%s)", sysMsg.Text)
}
}
} else {
@@ -199,6 +204,7 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
// 构建请求到Tyqw API
apiURL := config.GetTyqwApiPath(promptstr)
+ fmtf.Printf("Tyqw请求地址:%v\n", apiURL)
// 构造消息历史和当前消息
messages := []map[string]interface{}{}
@@ -216,8 +222,11 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) {
})
var isIncrementalOutput bool
- if config.GetTyqwSseType(promptstr) == 1 {
+ tyqwssetype := config.GetTyqwSseType(promptstr)
+ if tyqwssetype == 1 {
isIncrementalOutput = true
+ } else if tyqwssetype == 2 {
+ isIncrementalOutput = false
}
// 获取配置信息
useSSE := config.GetuseSse(promptstr)
diff --git a/config/config.go b/config/config.go
index 745d86a..a7368bc 100644
--- a/config/config.go
+++ b/config/config.go
@@ -262,6 +262,10 @@ func getMaxTokensHunyuanInternal(options ...string) int {
return getMaxTokensHunyuanInternal() // 递归调用内部函数,不传递任何参数
}
+ if maxTokensHunyuan == 0 {
+ return getMaxTokensHunyuanInternal()
+ }
+
return maxTokensHunyuan
}
@@ -316,6 +320,10 @@ func getWenxinApiPathInternal(options ...string) string {
return getWenxinApiPathInternal() // 递归调用内部函数,不传递任何参数
}
+ if apiPath == "" {
+ return getWenxinApiPathInternal()
+ }
+
return apiPath
}
@@ -360,6 +368,10 @@ func getGptModelInternal(options ...string) string {
return getGptModelInternal() // 递归调用内部函数,不传递任何参数
}
+ if gptModel == "" {
+ return getGptModelInternal()
+ }
+
return gptModel
}
@@ -2063,6 +2075,10 @@ func getTyqwApiPathInternal(options ...string) string {
return getTyqwApiPathInternal() // 递归调用内部函数,不传递任何参数
}
+ if apiPath == "" {
+ return getTyqwApiPathInternal()
+ }
+
return apiPath
}
@@ -2097,6 +2113,10 @@ func getTyqwMaxTokensInternal(options ...string) int {
return getTyqwMaxTokensInternal() // 递归调用内部函数,不传递任何参数
}
+ if maxTokens == 0 {
+ return getTyqwMaxTokensInternal()
+ }
+
return maxTokens
}
@@ -2131,6 +2151,10 @@ func getTyqwTemperatureInternal(options ...string) float64 {
return getTyqwTemperatureInternal() // 递归调用内部函数,不传递任何参数
}
+ if temperature == 0 {
+ return getTyqwTemperatureInternal()
+ }
+
return temperature
}
@@ -2165,6 +2189,10 @@ func getTyqwTopPInternal(options ...string) float64 {
return getTyqwTopPInternal() // 递归调用内部函数,不传递任何参数
}
+ if topP == 0 {
+ return getTyqwTopPInternal()
+ }
+
return topP
}
@@ -2199,6 +2227,10 @@ func getTyqwTopKInternal(options ...string) int {
return getTyqwTopKInternal() // 递归调用内部函数,不传递任何参数
}
+ if topK == 0 {
+ return getTyqwTopKInternal()
+ }
+
return topK
}
@@ -2233,6 +2265,10 @@ func getTyqwSseTypeInternal(options ...string) int {
return getTyqwSseTypeInternal() // 递归调用内部函数,不传递任何参数
}
+ if sseType == 0 {
+ return getTyqwSseTypeInternal()
+ }
+
return sseType
}
@@ -2347,6 +2383,10 @@ func getTyqwModelInternal(options ...string) string {
return getTyqwModelInternal() // 递归调用内部函数,不传递任何参数
}
+ if model == "" {
+ return getTyqwModelInternal()
+ }
+
return model
}
@@ -2381,6 +2421,10 @@ func getTyqwKeyInternal(options ...string) string {
return getTyqwKeyInternal() // 递归调用内部函数,不传递任何参数
}
+ if apiKey == "" {
+ return getTyqwKeyInternal()
+ }
+
return apiKey
}
diff --git a/prompt/prompt.go b/prompt/prompt.go
index ba3e8f0..1892f24 100644
--- a/prompt/prompt.go
+++ b/prompt/prompt.go
@@ -192,6 +192,29 @@ func FindFirstSystemMessage(history []structs.Message) (structs.Message, error)
return structs.Message{}, fmt.Errorf("no system message found in history")
}
+// GetFirstSystemMessage returns the first message that is of "system" role.
+func GetFirstSystemMessageStruct(basename string) (structs.Message, error) {
+ lock.RLock()
+ defer lock.RUnlock()
+
+ filename := basename + ".yml"
+ promptFile, exists := promptsCache[filename]
+ if !exists {
+ return structs.Message{}, fmt.Errorf("no data for file: %s", filename)
+ }
+
+ for _, prompt := range promptFile.Prompts {
+ if prompt.Role == "system" || prompt.Role == "System" {
+ return structs.Message{
+ Text: prompt.Content,
+ Role: prompt.Role,
+ }, nil
+ }
+ }
+
+ return structs.Message{}, fmt.Errorf("no system message found in file: %s", filename)
+}
+
// 返回除了 "system" 角色之外的所有消息
// GetMessagesExcludingSystem returns a list of messages that are not of "system" role,
// randomly selecting from options separated by "||" in prompt contents.
diff --git a/template/config_template.go b/template/config_template.go
index f6913f1..4c559a8 100644
--- a/template/config_template.go
+++ b/template/config_template.go
@@ -155,7 +155,7 @@ settings:
tyqwRepetitionPenalty : 1.1 # 用于控制模型生成时的重复度。提高repetition_penalty时可以降低模型生成的重复度。1.0表示不做惩罚,默认为1.1。没有严格的取值范围。
tyqwTopK: 40 # 从概率最高的K个令牌中采样
tyqwSeed : 1234 # 生成时使用的随机数种子,用户控制模型生成内容的随机性。seed支持无符号64位整数,默认值为1234。在使用seed时,模型将尽可能生成相同或相似的结果,但目前不保证每次生成的结果完全相同。
- tyqwSseType: 1 # 同gptSseType, 例如0代表不使用, 1代表使用
+ tyqwSseType: 1 # 1=默认,sse发新内容 2=sse内容递增(不推荐)
tyqwGlobalPenalty: false # 是否在全局上应用频率惩罚
tyqwStop: # 停止生成的标记列表
- "\n\nUser"
From 4a09fba361a13944fdfb0e5a257e0f0331aac49d Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Fri, 17 May 2024 17:12:45 +0800
Subject: [PATCH 05/12] Beta119 (#117)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
* beta118
* beta119
---
applogic/hunyuan.go | 266 ++++++++++++-
applogic/rwkv.go | 39 +-
config/config.go | 100 +++++
hunyuan/client.go | 256 +++++++++++--
hunyuan/errors.go | 6 +-
hunyuan/models.go | 719 +++++++++++++++++++++++++++++++-----
structs/struct.go | 7 +-
template/config_template.go | 5 +-
utils/utils.go | 11 +
9 files changed, 1254 insertions(+), 155 deletions(-)
diff --git a/applogic/hunyuan.go b/applogic/hunyuan.go
index 8168e87..2efd13a 100644
--- a/applogic/hunyuan.go
+++ b/applogic/hunyuan.go
@@ -114,9 +114,22 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
}
}
} else {
- history, err = prompt.GetMessagesFromFilename(promptstr)
- if err != nil {
- fmtf.Printf("prompt.GetMessagesFromFilename error: %v\n", err)
+ // 默认执行 正常提示词顺序
+ if !config.GetEnhancedQA(promptstr) {
+ history, err = prompt.GetMessagesFromFilename(promptstr)
+ if err != nil {
+ fmtf.Printf("prompt.GetMessagesFromFilename error: %v\n", err)
+ }
+ } else {
+ // 只获取系统提示词
+ systemMessage, err := prompt.GetFirstSystemMessageStruct(promptstr)
+ if err != nil {
+ fmt.Println("Error:", err)
+ } else {
+ // 如果找到system消息,将其添加到历史数组中
+ history = append(history, systemMessage)
+ fmt.Println("Added system message back to history.")
+ }
}
}
@@ -137,31 +150,38 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
// 获取系统级预埋的系统自定义QA对
systemHistory, err := prompt.GetMessagesExcludingSystem(promptstr)
if err != nil {
- fmtf.Printf("Error getting system history: %v\n", err)
+ fmtf.Printf("Error getting system history: %v,promptstr[%v]\n", err, promptstr)
return
}
// 处理增强QA逻辑
if config.GetEnhancedQA(promptstr) {
- // 确保系统历史与用户或助手历史数量一致,如果不足,则补足空的历史记录
- // 因为最后一个成员让给当前QA,所以-1
- if len(systemHistory)-2 > len(userHistory) {
- difference := len(systemHistory) - len(userHistory)
+ systemHistory, err := prompt.GetMessagesExcludingSystem(promptstr)
+ if err != nil {
+ fmt.Printf("Error getting system history: %v\n", err)
+ return
+ }
+
+ // 计算需要补足的历史记录数量
+ neededHistoryCount := len(systemHistory) - 2 // 最后两条留给当前QA处理
+ if neededHistoryCount > len(userHistory) {
+ // 补足用户或助手历史
+ difference := neededHistoryCount - len(userHistory)
for i := 0; i < difference; i++ {
- userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
- userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ if i%2 != 0 {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
+ } else {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ }
}
}
- // 如果系统历史中只有一个成员,跳过覆盖逻辑,留给后续处理
- if len(systemHistory) > 1 {
- // 将系统历史(除最后2个成员外)附加到相应的用户或助手历史上,采用倒序方式处理最近的记录
- for i := 0; i < len(systemHistory)-2; i++ {
- sysMsg := systemHistory[i]
- index := len(userHistory) - len(systemHistory) + i
- if index >= 0 && index < len(userHistory) && (userHistory[index].Role == "user" || userHistory[index].Role == "assistant") {
- userHistory[index].Text += fmt.Sprintf(" (%s)", sysMsg.Text)
- }
+ // 附加系统历史到用户或助手历史,除了最后两条
+ for i := 0; i < len(systemHistory)-2; i++ {
+ sysMsg := systemHistory[i]
+ index := len(userHistory) - neededHistoryCount + i
+ if index >= 0 && index < len(userHistory) {
+ userHistory[index].Text += fmt.Sprintf(" (%s)", sysMsg.Text)
}
}
} else {
@@ -181,6 +201,16 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
if config.GetHunyuanType() == 0 {
// 构建 hunyuan 请求
request := hunyuan.NewChatProRequest()
+ // 配置块
+ request.StreamModeration = new(bool)
+ *request.StreamModeration = config.GetHunyuanStreamModeration(promptstr)
+ request.Stream = new(bool)
+ *request.Stream = config.GetHunyuanStreamModeration(promptstr)
+ request.TopP = new(float64)
+ *request.TopP = config.GetTopPHunyuan(promptstr)
+ request.Temperature = new(float64)
+ *request.Temperature = config.GetTemperatureHunyuan(promptstr)
+
// 添加历史信息
for _, hMsg := range history {
content := hMsg.Text // 创建新变量
@@ -335,9 +365,20 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
fmtf.Fprintf(w, "data: %s\n\n", string(finalResponseJSON))
flusher.Flush()
}
- } else {
+ } else if config.GetHunyuanType() == 1 {
// 构建 hunyuan 标准版请求
request := hunyuan.NewChatStdRequest()
+
+ // 配置块
+ request.StreamModeration = new(bool)
+ *request.StreamModeration = config.GetHunyuanStreamModeration(promptstr)
+ request.Stream = new(bool)
+ *request.Stream = config.GetHunyuanStreamModeration(promptstr)
+ request.TopP = new(float64)
+ *request.TopP = config.GetTopPHunyuan(promptstr)
+ request.Temperature = new(float64)
+ *request.Temperature = config.GetTemperatureHunyuan(promptstr)
+
// 添加历史信息
for _, hMsg := range history {
content := hMsg.Text // 创建新变量
@@ -493,6 +534,191 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
flusher.Flush()
}
+ } else if config.GetHunyuanType() == 2 || config.GetHunyuanType() == 3 || config.GetHunyuanType() == 4 || config.GetHunyuanType() == 5 {
+ // 构建 hunyuan 请求
+ request := hunyuan.NewChatCompletionsRequest()
+ // 添加历史信息
+ for _, hMsg := range history {
+ content := hMsg.Text // 创建新变量
+ role := hMsg.Role // 创建新变量
+ hunyuanMsg := hunyuan.Message{
+ Content: &content, // 引用新变量的地址
+ Role: &role, // 引用新变量的地址
+ }
+ request.Messages = append(request.Messages, &hunyuanMsg)
+ }
+
+ // 添加当前用户消息
+ currentUserContent := msg.Text // 创建新变量
+ currentUserRole := msg.Role // 创建新变量
+ currentUserMsg := hunyuan.Message{
+ Content: ¤tUserContent, // 引用新变量的地址
+ Role: ¤tUserRole, // 引用新变量的地址
+ }
+ request.Messages = append(request.Messages, ¤tUserMsg)
+
+ // 获取HunyuanType并设置对应的Model
+ switch config.GetHunyuanType() {
+ case 2:
+ request.Model = new(string)
+ *request.Model = "hunyuan-lite"
+ case 3:
+ request.Model = new(string)
+ *request.Model = "hunyuan-standard"
+ case 4:
+ request.Model = new(string)
+ *request.Model = "hunyuan-standard-256K"
+ case 5:
+ request.Model = new(string)
+ *request.Model = "hunyuan-pro"
+ default:
+ request.Model = new(string)
+ *request.Model = "default-value"
+ }
+ fmtf.Printf("请求的混元模型类型:%v", *request.Model)
+ request.StreamModeration = new(bool)
+ *request.StreamModeration = config.GetHunyuanStreamModeration(promptstr)
+ request.Stream = new(bool)
+ *request.Stream = config.GetHunyuanStreamModeration(promptstr)
+ request.TopP = new(float64)
+ *request.TopP = config.GetTopPHunyuan(promptstr)
+ request.Temperature = new(float64)
+ *request.Temperature = config.GetTemperatureHunyuan(promptstr)
+
+ // 打印请求以进行调试
+ utils.PrintChatCompletionsRequest(request)
+
+ // 发送请求并获取响应
+ response, err := app.Client.ChatCompletions(request)
+ if err != nil {
+ http.Error(w, fmtf.Sprintf("hunyuanapi返回错误: %v", err), http.StatusInternalServerError)
+ return
+ }
+ if !config.GetuseSse(promptstr) {
+ // 解析响应
+ var responseTextBuilder strings.Builder
+ var totalUsage structs.UsageInfo
+ for event := range response.BaseSSEResponse.Events {
+ if event.Err != nil {
+ http.Error(w, fmtf.Sprintf("接收事件时发生错误: %v", event.Err), http.StatusInternalServerError)
+ return
+ }
+
+ // 解析事件数据
+ var eventData map[string]interface{}
+ if err := json.Unmarshal(event.Data, &eventData); err != nil {
+ http.Error(w, fmtf.Sprintf("解析事件数据出错: %v", err), http.StatusInternalServerError)
+ return
+ }
+
+ // 使用extractEventDetails函数提取信息
+ responseText, usageInfo := utils.ExtractEventDetails(eventData)
+ responseTextBuilder.WriteString(responseText)
+ totalUsage.PromptTokens += usageInfo.PromptTokens
+ totalUsage.CompletionTokens += usageInfo.CompletionTokens
+ }
+ // 现在responseTextBuilder中的内容是所有AI助手回复的组合
+ responseText := responseTextBuilder.String()
+
+ assistantMessageID, err := app.addMessage(structs.Message{
+ ConversationID: msg.ConversationID,
+ ParentMessageID: userMessageID,
+ Text: responseText,
+ Role: "assistant",
+ })
+
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ // 构造响应
+ responseMap := map[string]interface{}{
+ "response": responseText,
+ "conversationId": msg.ConversationID,
+ "messageId": assistantMessageID,
+ "details": map[string]interface{}{
+ "usage": totalUsage,
+ },
+ }
+
+ json.NewEncoder(w).Encode(responseMap)
+ } else {
+ // 设置SSE相关的响应头部
+ w.Header().Set("Content-Type", "text/event-stream")
+ w.Header().Set("Cache-Control", "no-cache")
+ w.Header().Set("Connection", "keep-alive")
+
+ flusher, ok := w.(http.Flusher)
+ if !ok {
+ http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
+ return
+ }
+
+ var responseTextBuilder strings.Builder
+ var totalUsage structs.UsageInfo
+
+ for event := range response.BaseSSEResponse.Events {
+ if event.Err != nil {
+ fmtf.Fprintf(w, "data: %s\n\n", fmtf.Sprintf("接收事件时发生错误: %v", event.Err))
+ flusher.Flush()
+ continue
+ }
+
+ // 解析事件数据和提取信息
+ var eventData map[string]interface{}
+ if err := json.Unmarshal(event.Data, &eventData); err != nil {
+ fmtf.Fprintf(w, "data: %s\n\n", fmtf.Sprintf("解析事件数据出错: %v", err))
+ flusher.Flush()
+ continue
+ }
+
+ responseText, usageInfo := utils.ExtractEventDetails(eventData)
+ responseTextBuilder.WriteString(responseText)
+ totalUsage.PromptTokens += usageInfo.PromptTokens
+ totalUsage.CompletionTokens += usageInfo.CompletionTokens
+
+ // 发送当前事件的响应数据,但不包含assistantMessageID
+ //fmtf.Printf("发送当前事件的响应数据,但不包含assistantMessageID\n")
+ tempResponseMap := map[string]interface{}{
+ "response": responseText,
+ "conversationId": msg.ConversationID,
+ "details": map[string]interface{}{
+ "usage": usageInfo,
+ },
+ }
+ tempResponseJSON, _ := json.Marshal(tempResponseMap)
+ fmtf.Fprintf(w, "data: %s\n\n", string(tempResponseJSON))
+ flusher.Flush()
+ }
+
+ // 处理完所有事件后,生成并发送包含assistantMessageID的最终响应
+ responseText := responseTextBuilder.String()
+ fmtf.Printf("处理完所有事件后,生成并发送包含assistantMessageID的最终响应:%v\n", responseText)
+ assistantMessageID, err := app.addMessage(structs.Message{
+ ConversationID: msg.ConversationID,
+ ParentMessageID: userMessageID,
+ Text: responseText,
+ Role: "assistant",
+ })
+
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ finalResponseMap := map[string]interface{}{
+ "response": responseText,
+ "conversationId": msg.ConversationID,
+ "messageId": assistantMessageID,
+ "details": map[string]interface{}{
+ "usage": totalUsage,
+ },
+ }
+ finalResponseJSON, _ := json.Marshal(finalResponseMap)
+ fmtf.Fprintf(w, "data: %s\n\n", string(finalResponseJSON))
+ flusher.Flush()
+ }
}
}
diff --git a/applogic/rwkv.go b/applogic/rwkv.go
index acc3af3..543fd90 100644
--- a/applogic/rwkv.go
+++ b/applogic/rwkv.go
@@ -128,7 +128,7 @@ func (app *App) ChatHandlerRwkv(w http.ResponseWriter, r *http.Request) {
}
} else {
// 只获取系统提示词
- systemMessage, err := prompt.FindFirstSystemMessage(history)
+ systemMessage, err := prompt.GetFirstSystemMessageStruct(promptstr)
if err != nil {
fmt.Println("Error:", err)
} else {
@@ -162,25 +162,32 @@ func (app *App) ChatHandlerRwkv(w http.ResponseWriter, r *http.Request) {
// 处理增强QA逻辑
if config.GetEnhancedQA(promptstr) {
- // 确保系统历史与用户或助手历史数量一致,如果不足,则补足空的历史记录
- // 因为最后一个成员让给当前QA,所以-1
- if len(systemHistory)-2 > len(userHistory) {
- difference := len(systemHistory) - len(userHistory)
+ systemHistory, err := prompt.GetMessagesExcludingSystem(promptstr)
+ if err != nil {
+ fmt.Printf("Error getting system history: %v\n", err)
+ return
+ }
+
+ // 计算需要补足的历史记录数量
+ neededHistoryCount := len(systemHistory) - 2 // 最后两条留给当前QA处理
+ if neededHistoryCount > len(userHistory) {
+ // 补足用户或助手历史
+ difference := neededHistoryCount - len(userHistory)
for i := 0; i < difference; i++ {
- userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
- userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ if i%2 != 0 {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "user"})
+ } else {
+ userHistory = append(userHistory, structs.Message{Text: "", Role: "assistant"})
+ }
}
}
- // 如果系统历史中只有一个成员,跳过覆盖逻辑,留给后续处理
- if len(systemHistory) > 1 {
- // 将系统历史(除最后2个成员外)附加到相应的用户或助手历史上,采用倒序方式处理最近的记录
- for i := 0; i < len(systemHistory)-2; i++ {
- sysMsg := systemHistory[i]
- index := len(userHistory) - len(systemHistory) + i
- if index >= 0 && index < len(userHistory) && (userHistory[index].Role == "user" || userHistory[index].Role == "assistant") {
- userHistory[index].Text += fmt.Sprintf(" (%s)", sysMsg.Text)
- }
+ // 附加系统历史到用户或助手历史,除了最后两条
+ for i := 0; i < len(systemHistory)-2; i++ {
+ sysMsg := systemHistory[i]
+ index := len(userHistory) - neededHistoryCount + i
+ if index >= 0 && index < len(userHistory) {
+ userHistory[index].Text += fmt.Sprintf(" (%s)", sysMsg.Text)
}
}
} else {
diff --git a/config/config.go b/config/config.go
index a7368bc..c87ae21 100644
--- a/config/config.go
+++ b/config/config.go
@@ -1229,6 +1229,10 @@ func getRwkvMaxTokensInternal(options ...string) int {
return getRwkvMaxTokensInternal() // 递归调用内部函数,不传递任何参数
}
+ if maxTokens == 0 {
+ return getRwkvMaxTokensInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return maxTokens
}
@@ -2738,3 +2742,99 @@ func getGroupHintWordsInternal(options ...string) []string {
return hintWords
}
+
+// 获取HunyuanStreamModeration值
+func GetHunyuanStreamModeration(options ...string) bool {
+ mu.Lock()
+ defer mu.Unlock()
+ return getHunyuanStreamModerationInternal(options...)
+}
+
+// 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getHunyuanStreamModerationInternal(options ...string) bool {
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.HunyuanStreamModeration
+ }
+ return false
+ }
+
+ basename := options[0]
+ valueInterface, err := prompt.GetSettingFromFilename(basename, "HunyuanStreamModeration")
+ if err != nil {
+ log.Println("Error retrieving HunyuanStreamModeration:", err)
+ return getHunyuanStreamModerationInternal()
+ }
+
+ value, ok := valueInterface.(bool)
+ if !ok || !value {
+ log.Println("Fetching default HunyuanStreamModeration")
+ return getHunyuanStreamModerationInternal()
+ }
+
+ return value
+}
+
+// 获取TopPHunyuan值
+func GetTopPHunyuan(options ...string) float64 {
+ mu.Lock()
+ defer mu.Unlock()
+ return getTopPHunyuanInternal(options...)
+}
+
+// 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTopPHunyuanInternal(options ...string) float64 {
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TopPHunyuan
+ }
+ return 0.0
+ }
+
+ basename := options[0]
+ valueInterface, err := prompt.GetSettingFromFilename(basename, "TopPHunyuan")
+ if err != nil {
+ log.Println("Error retrieving TopPHunyuan:", err)
+ return getTopPHunyuanInternal()
+ }
+
+ value, ok := valueInterface.(float64)
+ if !ok || value == 0.0 {
+ log.Println("Fetching default TopPHunyuan")
+ return getTopPHunyuanInternal()
+ }
+
+ return value
+}
+
+// 获取TemperatureHunyuan值
+func GetTemperatureHunyuan(options ...string) float64 {
+ mu.Lock()
+ defer mu.Unlock()
+ return getTemperatureHunyuanInternal(options...)
+}
+
+// 内部逻辑执行函数,不处理锁,可以安全地递归调用
+func getTemperatureHunyuanInternal(options ...string) float64 {
+ if len(options) == 0 || options[0] == "" {
+ if instance != nil {
+ return instance.Settings.TemperatureHunyuan
+ }
+ return 0.0
+ }
+
+ basename := options[0]
+ valueInterface, err := prompt.GetSettingFromFilename(basename, "TemperatureHunyuan")
+ if err != nil {
+ log.Println("Error retrieving TemperatureHunyuan:", err)
+ return getTemperatureHunyuanInternal()
+ }
+
+ value, ok := valueInterface.(float64)
+ if !ok || value == 0.0 {
+ log.Println("Fetching default TemperatureHunyuan")
+ return getTemperatureHunyuanInternal()
+ }
+
+ return value
+}
diff --git a/hunyuan/client.go b/hunyuan/client.go
index 45501b1..e1c9bc0 100644
--- a/hunyuan/client.go
+++ b/hunyuan/client.go
@@ -45,6 +45,90 @@ func NewClient(credential common.CredentialIface, region string, clientProfile *
return
}
+func NewChatCompletionsRequest() (request *ChatCompletionsRequest) {
+ request = &ChatCompletionsRequest{
+ BaseRequest: &tchttp.BaseRequest{},
+ }
+
+ request.Init().WithApiInfo("hunyuan", APIVersion, "ChatCompletions")
+
+ return
+}
+
+func NewChatCompletionsResponse() (response *ChatCompletionsResponse) {
+ response = &ChatCompletionsResponse{}
+ return
+
+}
+
+// ChatCompletions
+// 腾讯混元大模型是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口支持流式或非流式调用,当使用流式调用时为 SSE 协议。
+//
+// 1. 本接口暂不支持返回图片内容。
+//
+// 2. 默认每种模型单账号限制并发数为 5 路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
+//
+// 3. 请使用 SDK 调用本接口,每种开发语言的 SDK Git 仓库 examples/hunyuan/v20230901/ 目录下有提供示例供参考。SDK 链接在文档下方 “**开发者资源 - SDK**” 部分提供。
+//
+// 可能返回的错误码:
+//
+// FAILEDOPERATION_ENGINEREQUESTTIMEOUT = "FailedOperation.EngineRequestTimeout"
+// FAILEDOPERATION_ENGINESERVERERROR = "FailedOperation.EngineServerError"
+// FAILEDOPERATION_ENGINESERVERLIMITEXCEEDED = "FailedOperation.EngineServerLimitExceeded"
+// FAILEDOPERATION_FREERESOURCEPACKEXHAUSTED = "FailedOperation.FreeResourcePackExhausted"
+// FAILEDOPERATION_RESOURCEPACKEXHAUSTED = "FailedOperation.ResourcePackExhausted"
+// FAILEDOPERATION_SERVICENOTACTIVATED = "FailedOperation.ServiceNotActivated"
+// FAILEDOPERATION_SERVICESTOP = "FailedOperation.ServiceStop"
+// FAILEDOPERATION_SERVICESTOPARREARS = "FailedOperation.ServiceStopArrears"
+// INTERNALERROR = "InternalError"
+// INVALIDPARAMETER = "InvalidParameter"
+// INVALIDPARAMETERVALUE = "InvalidParameterValue"
+// INVALIDPARAMETERVALUE_MODEL = "InvalidParameterValue.Model"
+// LIMITEXCEEDED = "LimitExceeded"
+func (c *Client) ChatCompletions(request *ChatCompletionsRequest) (response *ChatCompletionsResponse, err error) {
+ return c.ChatCompletionsWithContext(context.Background(), request)
+}
+
+// ChatCompletions
+// 腾讯混元大模型是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口支持流式或非流式调用,当使用流式调用时为 SSE 协议。
+//
+// 1. 本接口暂不支持返回图片内容。
+//
+// 2. 默认每种模型单账号限制并发数为 5 路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
+//
+// 3. 请使用 SDK 调用本接口,每种开发语言的 SDK Git 仓库 examples/hunyuan/v20230901/ 目录下有提供示例供参考。SDK 链接在文档下方 “**开发者资源 - SDK**” 部分提供。
+//
+// 可能返回的错误码:
+//
+// FAILEDOPERATION_ENGINEREQUESTTIMEOUT = "FailedOperation.EngineRequestTimeout"
+// FAILEDOPERATION_ENGINESERVERERROR = "FailedOperation.EngineServerError"
+// FAILEDOPERATION_ENGINESERVERLIMITEXCEEDED = "FailedOperation.EngineServerLimitExceeded"
+// FAILEDOPERATION_FREERESOURCEPACKEXHAUSTED = "FailedOperation.FreeResourcePackExhausted"
+// FAILEDOPERATION_RESOURCEPACKEXHAUSTED = "FailedOperation.ResourcePackExhausted"
+// FAILEDOPERATION_SERVICENOTACTIVATED = "FailedOperation.ServiceNotActivated"
+// FAILEDOPERATION_SERVICESTOP = "FailedOperation.ServiceStop"
+// FAILEDOPERATION_SERVICESTOPARREARS = "FailedOperation.ServiceStopArrears"
+// INTERNALERROR = "InternalError"
+// INVALIDPARAMETER = "InvalidParameter"
+// INVALIDPARAMETERVALUE = "InvalidParameterValue"
+// INVALIDPARAMETERVALUE_MODEL = "InvalidParameterValue.Model"
+// LIMITEXCEEDED = "LimitExceeded"
+func (c *Client) ChatCompletionsWithContext(ctx context.Context, request *ChatCompletionsRequest) (response *ChatCompletionsResponse, err error) {
+ if request == nil {
+ request = NewChatCompletionsRequest()
+ }
+
+ if c.GetCredential() == nil {
+ return nil, errors.New("ChatCompletions require credential")
+ }
+
+ request.SetContext(ctx)
+
+ response = NewChatCompletionsResponse()
+ err = c.Send(request, response)
+ return
+}
+
func NewChatProRequest() (request *ChatProRequest) {
request = &ChatProRequest{
BaseRequest: &tchttp.BaseRequest{},
@@ -62,13 +146,15 @@ func NewChatProResponse() (response *ChatProResponse) {
}
// ChatPro
-// 腾讯混元大模型高级版是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口为SSE协议。
+// 注意:本接口将于 5 月 15 日下线;下线后将不再提供文档指引,接口本身可继续调用,建议使用 [hunyuan](https://cloud.tencent.com/document/api/1729/105701) 接入。
//
-// 1.本接口暂不支持返回图片内容。
+// 腾讯混元大模型(hunyuan-pro)是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口支持流式或非流式调用,当使用流式调用时为 SSE 协议。
//
-// 2.默认单账号限制并发数为5路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
+// 1. 本接口暂不支持返回图片内容。
//
-// 3.请使用SDK调用本接口 ,SDK GitHub仓库examples/hunyuan/v20230901/目录有提供[参考示例](https://github.com/TencentCloud/tencentcloud-sdk-python/blob/master/examples/hunyuan/v20230901/chat_std.py)。
+// 2. 默认单账号限制并发数为 5 路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
+//
+// 3. 请使用 SDK 调用本接口,每种开发语言的 SDK Git 仓库 examples/hunyuan/v20230901/ 目录下有提供示例供参考。SDK 链接在文档下方 “**开发者资源 - SDK**” 部分提供。
//
// 可能返回的错误码:
//
@@ -83,19 +169,20 @@ func NewChatProResponse() (response *ChatProResponse) {
// INTERNALERROR = "InternalError"
// INVALIDPARAMETERVALUE = "InvalidParameterValue"
// LIMITEXCEEDED = "LimitExceeded"
-// UNSUPPORTEDOPERATION_NONWHITELISTACCOUNT = "UnsupportedOperation.NonWhitelistAccount"
func (c *Client) ChatPro(request *ChatProRequest) (response *ChatProResponse, err error) {
return c.ChatProWithContext(context.Background(), request)
}
// ChatPro
-// 腾讯混元大模型高级版是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口为SSE协议。
+// 注意:本接口将于 5 月 15 日下线;下线后将不再提供文档指引,接口本身可继续调用,建议使用 [hunyuan](https://cloud.tencent.com/document/api/1729/105701) 接入。
+//
+// 腾讯混元大模型(hunyuan-pro)是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口支持流式或非流式调用,当使用流式调用时为 SSE 协议。
//
-// 1.本接口暂不支持返回图片内容。
+// 1. 本接口暂不支持返回图片内容。
//
-// 2.默认单账号限制并发数为5路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
+// 2. 默认单账号限制并发数为 5 路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
//
-// 3.请使用SDK调用本接口 ,SDK GitHub仓库examples/hunyuan/v20230901/目录有提供[参考示例](https://github.com/TencentCloud/tencentcloud-sdk-python/blob/master/examples/hunyuan/v20230901/chat_std.py)。
+// 3. 请使用 SDK 调用本接口,每种开发语言的 SDK Git 仓库 examples/hunyuan/v20230901/ 目录下有提供示例供参考。SDK 链接在文档下方 “**开发者资源 - SDK**” 部分提供。
//
// 可能返回的错误码:
//
@@ -110,7 +197,6 @@ func (c *Client) ChatPro(request *ChatProRequest) (response *ChatProResponse, er
// INTERNALERROR = "InternalError"
// INVALIDPARAMETERVALUE = "InvalidParameterValue"
// LIMITEXCEEDED = "LimitExceeded"
-// UNSUPPORTEDOPERATION_NONWHITELISTACCOUNT = "UnsupportedOperation.NonWhitelistAccount"
func (c *Client) ChatProWithContext(ctx context.Context, request *ChatProRequest) (response *ChatProResponse, err error) {
if request == nil {
request = NewChatProRequest()
@@ -144,13 +230,15 @@ func NewChatStdResponse() (response *ChatStdResponse) {
}
// ChatStd
-// 腾讯混元大模型标准版是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口为SSE协议。
+// 注意:本接口将于 5 月 15 日下线;下线后将不再提供文档指引,接口本身可继续调用,建议使用 [hunyuan](https://cloud.tencent.com/document/api/1729/105701) 接入。
//
-// 1.本接口暂不支持返回图片内容。
+// 腾讯混元大模型标准版是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口支持流式或非流式调用,当使用流式调用时为 SSE 协议。
//
-// 2.默认单账号限制并发数为5路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
+// 1. 本接口暂不支持返回图片内容。
//
-// 3.请使用SDK调用本接口 ,SDK GitHub仓库examples/hunyuan/v20230901/目录有提供[参考示例](https://github.com/TencentCloud/tencentcloud-sdk-python/blob/master/examples/hunyuan/v20230901/chat_std.py)。
+// 2. 默认单账号限制并发数为 5 路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
+//
+// 3. 请使用 SDK 调用本接口,每种开发语言的 SDK Git 仓库 examples/hunyuan/v20230901/ 目录下有提供示例供参考。SDK 链接在文档下方 “**开发者资源 - SDK**” 部分提供。
//
// 可能返回的错误码:
//
@@ -166,19 +254,20 @@ func NewChatStdResponse() (response *ChatStdResponse) {
// INVALIDPARAMETER = "InvalidParameter"
// INVALIDPARAMETERVALUE = "InvalidParameterValue"
// LIMITEXCEEDED = "LimitExceeded"
-// UNSUPPORTEDOPERATION_NONWHITELISTACCOUNT = "UnsupportedOperation.NonWhitelistAccount"
func (c *Client) ChatStd(request *ChatStdRequest) (response *ChatStdResponse, err error) {
return c.ChatStdWithContext(context.Background(), request)
}
// ChatStd
-// 腾讯混元大模型标准版是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口为SSE协议。
+// 注意:本接口将于 5 月 15 日下线;下线后将不再提供文档指引,接口本身可继续调用,建议使用 [hunyuan](https://cloud.tencent.com/document/api/1729/105701) 接入。
+//
+// 腾讯混元大模型标准版是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。本接口支持流式或非流式调用,当使用流式调用时为 SSE 协议。
//
-// 1.本接口暂不支持返回图片内容。
+// 1. 本接口暂不支持返回图片内容。
//
-// 2.默认单账号限制并发数为5路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
+// 2. 默认单账号限制并发数为 5 路,如您有提高并发限制的需求请 [联系我们](https://cloud.tencent.com/act/event/Online_service) 。
//
-// 3.请使用SDK调用本接口 ,SDK GitHub仓库examples/hunyuan/v20230901/目录有提供[参考示例](https://github.com/TencentCloud/tencentcloud-sdk-python/blob/master/examples/hunyuan/v20230901/chat_std.py)。
+// 3. 请使用 SDK 调用本接口,每种开发语言的 SDK Git 仓库 examples/hunyuan/v20230901/ 目录下有提供示例供参考。SDK 链接在文档下方 “**开发者资源 - SDK**” 部分提供。
//
// 可能返回的错误码:
//
@@ -194,7 +283,6 @@ func (c *Client) ChatStd(request *ChatStdRequest) (response *ChatStdResponse, er
// INVALIDPARAMETER = "InvalidParameter"
// INVALIDPARAMETERVALUE = "InvalidParameterValue"
// LIMITEXCEEDED = "LimitExceeded"
-// UNSUPPORTEDOPERATION_NONWHITELISTACCOUNT = "UnsupportedOperation.NonWhitelistAccount"
func (c *Client) ChatStdWithContext(ctx context.Context, request *ChatStdRequest) (response *ChatStdResponse, err error) {
if request == nil {
request = NewChatStdRequest()
@@ -230,7 +318,7 @@ func NewGetEmbeddingResponse() (response *GetEmbeddingResponse) {
}
// GetEmbedding
-// 腾讯混元-Embedding接口,可以将文本转化为高质量的向量数据。
+// 腾讯混元 Embedding 接口,可以将文本转化为高质量的向量数据。
//
// 可能返回的错误码:
//
@@ -243,7 +331,7 @@ func (c *Client) GetEmbedding(request *GetEmbeddingRequest) (response *GetEmbedd
}
// GetEmbedding
-// 腾讯混元-Embedding接口,可以将文本转化为高质量的向量数据。
+// 腾讯混元 Embedding 接口,可以将文本转化为高质量的向量数据。
//
// 可能返回的错误码:
//
@@ -316,3 +404,127 @@ func (c *Client) GetTokenCountWithContext(ctx context.Context, request *GetToken
err = c.Send(request, response)
return
}
+
+func NewQueryHunyuanImageJobRequest() (request *QueryHunyuanImageJobRequest) {
+ request = &QueryHunyuanImageJobRequest{
+ BaseRequest: &tchttp.BaseRequest{},
+ }
+
+ request.Init().WithApiInfo("hunyuan", APIVersion, "QueryHunyuanImageJob")
+
+ return
+}
+
+func NewQueryHunyuanImageJobResponse() (response *QueryHunyuanImageJobResponse) {
+ response = &QueryHunyuanImageJobResponse{
+ BaseResponse: &tchttp.BaseResponse{},
+ }
+ return
+
+}
+
+// QueryHunyuanImageJob
+// 混元生图接口基于混元大模型,将根据输入的文本描述,智能生成与之相关的结果图。分为提交任务和查询任务2个接口。
+//
+// 提交任务:输入文本等,提交一个混元生图异步任务,获得任务 ID。
+//
+// 查询任务:根据任务 ID 查询任务的处理状态、处理结果,任务处理完成后可获得生成图像结果。
+//
+// 并发任务数(并发)说明:并发任务数指能同时处理的任务数量。混元生图默认提供1个并发任务数,代表最多能同时处理1个已提交的任务,上一个任务处理完毕后才能开始处理下一个任务。
+//
+// 可能返回的错误码:
+//
+// FAILEDOPERATION = "FailedOperation"
+func (c *Client) QueryHunyuanImageJob(request *QueryHunyuanImageJobRequest) (response *QueryHunyuanImageJobResponse, err error) {
+ return c.QueryHunyuanImageJobWithContext(context.Background(), request)
+}
+
+// QueryHunyuanImageJob
+// 混元生图接口基于混元大模型,将根据输入的文本描述,智能生成与之相关的结果图。分为提交任务和查询任务2个接口。
+//
+// 提交任务:输入文本等,提交一个混元生图异步任务,获得任务 ID。
+//
+// 查询任务:根据任务 ID 查询任务的处理状态、处理结果,任务处理完成后可获得生成图像结果。
+//
+// 并发任务数(并发)说明:并发任务数指能同时处理的任务数量。混元生图默认提供1个并发任务数,代表最多能同时处理1个已提交的任务,上一个任务处理完毕后才能开始处理下一个任务。
+//
+// 可能返回的错误码:
+//
+// FAILEDOPERATION = "FailedOperation"
+func (c *Client) QueryHunyuanImageJobWithContext(ctx context.Context, request *QueryHunyuanImageJobRequest) (response *QueryHunyuanImageJobResponse, err error) {
+ if request == nil {
+ request = NewQueryHunyuanImageJobRequest()
+ }
+
+ if c.GetCredential() == nil {
+ return nil, errors.New("QueryHunyuanImageJob require credential")
+ }
+
+ request.SetContext(ctx)
+
+ response = NewQueryHunyuanImageJobResponse()
+ err = c.Send(request, response)
+ return
+}
+
+func NewSubmitHunyuanImageJobRequest() (request *SubmitHunyuanImageJobRequest) {
+ request = &SubmitHunyuanImageJobRequest{
+ BaseRequest: &tchttp.BaseRequest{},
+ }
+
+ request.Init().WithApiInfo("hunyuan", APIVersion, "SubmitHunyuanImageJob")
+
+ return
+}
+
+func NewSubmitHunyuanImageJobResponse() (response *SubmitHunyuanImageJobResponse) {
+ response = &SubmitHunyuanImageJobResponse{
+ BaseResponse: &tchttp.BaseResponse{},
+ }
+ return
+
+}
+
+// SubmitHunyuanImageJob
+// 混元生图接口基于混元大模型,将根据输入的文本描述,智能生成与之相关的结果图。分为提交任务和查询任务2个接口。
+//
+// 提交任务:输入文本等,提交一个混元生图异步任务,获得任务 ID。
+//
+// 查询任务:根据任务 ID 查询任务的处理状态、处理结果,任务处理完成后可获得生成图像结果。
+//
+// 并发任务数(并发)说明:并发任务数指能同时处理的任务数量。混元生图默认提供1个并发任务数,代表最多能同时处理1个已提交的任务,上一个任务处理完毕后才能开始处理下一个任务。
+//
+// 可能返回的错误码:
+//
+// FAILEDOPERATION = "FailedOperation"
+func (c *Client) SubmitHunyuanImageJob(request *SubmitHunyuanImageJobRequest) (response *SubmitHunyuanImageJobResponse, err error) {
+ return c.SubmitHunyuanImageJobWithContext(context.Background(), request)
+}
+
+// SubmitHunyuanImageJob
+// 混元生图接口基于混元大模型,将根据输入的文本描述,智能生成与之相关的结果图。分为提交任务和查询任务2个接口。
+//
+// 提交任务:输入文本等,提交一个混元生图异步任务,获得任务 ID。
+//
+// 查询任务:根据任务 ID 查询任务的处理状态、处理结果,任务处理完成后可获得生成图像结果。
+//
+// 并发任务数(并发)说明:并发任务数指能同时处理的任务数量。混元生图默认提供1个并发任务数,代表最多能同时处理1个已提交的任务,上一个任务处理完毕后才能开始处理下一个任务。
+//
+// 可能返回的错误码:
+//
+// FAILEDOPERATION = "FailedOperation"
+func (c *Client) SubmitHunyuanImageJobWithContext(ctx context.Context, request *SubmitHunyuanImageJobRequest) (response *SubmitHunyuanImageJobResponse, err error) {
+ if request == nil {
+ request = NewSubmitHunyuanImageJobRequest()
+ }
+
+ if c.GetCredential() == nil {
+ return nil, errors.New("SubmitHunyuanImageJob require credential")
+ }
+
+ request.SetContext(ctx)
+
+ response = NewSubmitHunyuanImageJobResponse()
+ err = c.Send(request, response)
+ return
+}
diff --git a/hunyuan/errors.go b/hunyuan/errors.go
index 6bd7ab4..d284c66 100644
--- a/hunyuan/errors.go
+++ b/hunyuan/errors.go
@@ -53,9 +53,9 @@ const (
// 参数取值错误。
INVALIDPARAMETERVALUE = "InvalidParameterValue"
+ // 模型不存在。
+ INVALIDPARAMETERVALUE_MODEL = "InvalidParameterValue.Model"
+
// 超过配额限制。
LIMITEXCEEDED = "LimitExceeded"
-
- // 非白名单帐号,请前往控制台申请试用。
- UNSUPPORTEDOPERATION_NONWHITELISTACCOUNT = "UnsupportedOperation.NonWhitelistAccount"
)
diff --git a/hunyuan/models.go b/hunyuan/models.go
index 82e3e97..0f9a653 100644
--- a/hunyuan/models.go
+++ b/hunyuan/models.go
@@ -20,26 +20,225 @@ import (
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json"
)
+// Predefined struct for user
+type ChatCompletionsRequestParams struct {
+ // 模型名称,可选值包括 hunyuan-lite、hunyuan-standard、hunyuan-standard-256K、hunyuan-pro。
+ // 各模型介绍请阅读 [产品概述](https://cloud.tencent.com/document/product/1729/104753) 中的说明。
+ //
+ // 注意:
+ // 不同的模型计费不同,请根据 [购买指南](https://cloud.tencent.com/document/product/1729/97731) 按需调用。
+ Model *string `json:"Model,omitnil,omitempty" name:"Model"`
+
+ // 聊天上下文信息。
+ // 说明:
+ // 1. 长度最多为 40,按对话时间从旧到新在数组中排列。
+ // 2. Message.Role 可选值:system、user、assistant。
+ // 其中,system 角色可选,如存在则必须位于列表的最开始。user 和 assistant 需交替出现(一问一答),以 user 提问开始和结束,且 Content 不能为空。Role 的顺序示例:[system(可选) user assistant user assistant user ...]。
+ // 3. Messages 中 Content 总长度不能超过模型输入长度上限(可参考 [产品概述](https://cloud.tencent.com/document/product/1729/104753) 文档),超过则会截断最前面的内容,只保留尾部内容。
+ Messages []*Message `json:"Messages,omitnil,omitempty" name:"Messages"`
+
+ // 流式调用开关。
+ // 说明:
+ // 1. 未传值时默认为非流式调用(false)。
+ // 2. 流式调用时以 SSE 协议增量返回结果(返回值取 Choices[n].Delta 中的值,需要拼接增量数据才能获得完整结果)。
+ // 3. 非流式调用时:
+ // 调用方式与普通 HTTP 请求无异。
+ // 接口响应耗时较长,**如需更低时延建议设置为 true**。
+ // 只返回一次最终结果(返回值取 Choices[n].Message 中的值)。
+ //
+ // 注意:
+ // 通过 SDK 调用时,流式和非流式调用需用**不同的方式**获取返回值,具体参考 SDK 中的注释或示例(在各语言 SDK 代码仓库的 examples/hunyuan/v20230901/ 目录中)。
+ Stream *bool `json:"Stream,omitnil,omitempty" name:"Stream"`
+
+ // 流式输出审核开关。
+ // 说明:
+ // 1. 当使用流式输出(Stream 字段值为 true)时,该字段生效。
+ // 2. 输出审核有流式和同步两种模式,**流式模式首包响应更快**。未传值时默认为流式模式(true)。
+ // 3. 如果值为 true,将对输出内容进行分段审核,审核通过的内容流式输出返回。如果出现审核不过,响应中的 FinishReason 值为 sensitive。
+ // 4. 如果值为 false,则不使用流式输出审核,需要审核完所有输出内容后再返回结果。
+ //
+ // 注意:
+ // 当选择流式输出审核时,可能会出现部分内容已输出,但中间某一段响应中的 FinishReason 值为 sensitive,此时说明安全审核未通过。如果业务场景有实时文字上屏的需求,需要自行撤回已上屏的内容,并建议自定义替换为一条提示语,如 “这个问题我不方便回答,不如我们换个话题试试”,以保障终端体验。
+ StreamModeration *bool `json:"StreamModeration,omitnil,omitempty" name:"StreamModeration"`
+
+ // 说明:
+ // 1. 影响输出文本的多样性,取值越大,生成文本的多样性越强。
+ // 2. 默认 1.0,取值区间为 [0.0, 1.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ TopP *float64 `json:"TopP,omitnil,omitempty" name:"TopP"`
+
+ // 说明:
+ // 1. 较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
+ // 2. 默认 1.0,取值区间为 [0.0, 2.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ Temperature *float64 `json:"Temperature,omitnil,omitempty" name:"Temperature"`
+}
+
+type ChatCompletionsRequest struct {
+ *tchttp.BaseRequest
+
+ // 模型名称,可选值包括 hunyuan-lite、hunyuan-standard、hunyuan-standard-256K、hunyuan-pro。
+ // 各模型介绍请阅读 [产品概述](https://cloud.tencent.com/document/product/1729/104753) 中的说明。
+ //
+ // 注意:
+ // 不同的模型计费不同,请根据 [购买指南](https://cloud.tencent.com/document/product/1729/97731) 按需调用。
+ Model *string `json:"Model,omitnil,omitempty" name:"Model"`
+
+ // 聊天上下文信息。
+ // 说明:
+ // 1. 长度最多为 40,按对话时间从旧到新在数组中排列。
+ // 2. Message.Role 可选值:system、user、assistant。
+ // 其中,system 角色可选,如存在则必须位于列表的最开始。user 和 assistant 需交替出现(一问一答),以 user 提问开始和结束,且 Content 不能为空。Role 的顺序示例:[system(可选) user assistant user assistant user ...]。
+ // 3. Messages 中 Content 总长度不能超过模型输入长度上限(可参考 [产品概述](https://cloud.tencent.com/document/product/1729/104753) 文档),超过则会截断最前面的内容,只保留尾部内容。
+ Messages []*Message `json:"Messages,omitnil,omitempty" name:"Messages"`
+
+ // 流式调用开关。
+ // 说明:
+ // 1. 未传值时默认为非流式调用(false)。
+ // 2. 流式调用时以 SSE 协议增量返回结果(返回值取 Choices[n].Delta 中的值,需要拼接增量数据才能获得完整结果)。
+ // 3. 非流式调用时:
+ // 调用方式与普通 HTTP 请求无异。
+ // 接口响应耗时较长,**如需更低时延建议设置为 true**。
+ // 只返回一次最终结果(返回值取 Choices[n].Message 中的值)。
+ //
+ // 注意:
+ // 通过 SDK 调用时,流式和非流式调用需用**不同的方式**获取返回值,具体参考 SDK 中的注释或示例(在各语言 SDK 代码仓库的 examples/hunyuan/v20230901/ 目录中)。
+ Stream *bool `json:"Stream,omitnil,omitempty" name:"Stream"`
+
+ // 流式输出审核开关。
+ // 说明:
+ // 1. 当使用流式输出(Stream 字段值为 true)时,该字段生效。
+ // 2. 输出审核有流式和同步两种模式,**流式模式首包响应更快**。未传值时默认为流式模式(true)。
+ // 3. 如果值为 true,将对输出内容进行分段审核,审核通过的内容流式输出返回。如果出现审核不过,响应中的 FinishReason 值为 sensitive。
+ // 4. 如果值为 false,则不使用流式输出审核,需要审核完所有输出内容后再返回结果。
+ //
+ // 注意:
+ // 当选择流式输出审核时,可能会出现部分内容已输出,但中间某一段响应中的 FinishReason 值为 sensitive,此时说明安全审核未通过。如果业务场景有实时文字上屏的需求,需要自行撤回已上屏的内容,并建议自定义替换为一条提示语,如 “这个问题我不方便回答,不如我们换个话题试试”,以保障终端体验。
+ StreamModeration *bool `json:"StreamModeration,omitnil,omitempty" name:"StreamModeration"`
+
+ // 说明:
+ // 1. 影响输出文本的多样性,取值越大,生成文本的多样性越强。
+ // 2. 默认 1.0,取值区间为 [0.0, 1.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ TopP *float64 `json:"TopP,omitnil,omitempty" name:"TopP"`
+
+ // 说明:
+ // 1. 较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
+ // 2. 默认 1.0,取值区间为 [0.0, 2.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ Temperature *float64 `json:"Temperature,omitnil,omitempty" name:"Temperature"`
+}
+
+func (r *ChatCompletionsRequest) ToJsonString() string {
+ b, _ := json.Marshal(r)
+ return string(b)
+}
+
+// FromJsonString It is highly **NOT** recommended to use this function
+// because it has no param check, nor strict type check
+func (r *ChatCompletionsRequest) FromJsonString(s string) error {
+ f := make(map[string]interface{})
+ if err := json.Unmarshal([]byte(s), &f); err != nil {
+ return err
+ }
+ delete(f, "Model")
+ delete(f, "Messages")
+ delete(f, "Stream")
+ delete(f, "StreamModeration")
+ delete(f, "TopP")
+ delete(f, "Temperature")
+ if len(f) > 0 {
+ return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "ChatCompletionsRequest has unknown keys!", "")
+ }
+ return json.Unmarshal([]byte(s), &r)
+}
+
+// Predefined struct for user
+type ChatCompletionsResponseParams struct {
+ // Unix 时间戳,单位为秒。
+ Created *int64 `json:"Created,omitnil,omitempty" name:"Created"`
+
+ // Token 统计信息。
+ // 按照总 Token 数量计费。
+ Usage *Usage `json:"Usage,omitnil,omitempty" name:"Usage"`
+
+ // 免责声明。
+ Note *string `json:"Note,omitnil,omitempty" name:"Note"`
+
+ // 本轮对话的 ID。
+ Id *string `json:"Id,omitnil,omitempty" name:"Id"`
+
+ // 回复内容。
+ Choices []*Choice `json:"Choices,omitnil,omitempty" name:"Choices"`
+
+ // 错误信息。
+ // 如果流式返回中服务处理异常,返回该错误信息。
+ // 注意:此字段可能返回 null,表示取不到有效值。
+ ErrorMsg *ErrorMsg `json:"ErrorMsg,omitnil,omitempty" name:"ErrorMsg"`
+
+ // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。本接口为流式响应接口,当请求成功时,RequestId 会被放在 HTTP 响应的 Header "X-TC-RequestId" 中。
+ RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
+}
+
+type ChatCompletionsResponse struct {
+ tchttp.BaseSSEResponse `json:"-"`
+ Response *ChatCompletionsResponseParams `json:"Response"`
+}
+
+func (r *ChatCompletionsResponse) ToJsonString() string {
+ b, _ := json.Marshal(r)
+ return string(b)
+}
+
+// FromJsonString It is highly **NOT** recommended to use this function
+// because it has no param check, nor strict type check
+func (r *ChatCompletionsResponse) FromJsonString(s string) error {
+ return json.Unmarshal([]byte(s), &r)
+}
+
// Predefined struct for user
type ChatProRequestParams struct {
// 聊天上下文信息。
// 说明:
- // 1.长度最多为40, 按对话时间从旧到新在数组中排列。
- // 2.Message的Role当前可选值:system、user、assistant,其中,system角色是可选的,如果存在,必须位于列表的最开始。user和assistant需要交替出现(一问一答),最后一个为user提问, 且Content不能为空。
- // 3.Messages中Content总长度不超过16000 token,超过则会截断最前面的内容,只保留尾部内容。建议不超过4000 token。
- Messages []*Message `json:"Messages,omitnil" name:"Messages"`
+ // 1. 长度最多为 40,按对话时间从旧到新在数组中排列。
+ // 2. Message.Role 可选值:system、user、assistant。
+ // 其中,system 角色可选,如存在则必须位于列表的最开始。user 和 assistant 需交替出现(一问一答),以 user 提问开始和结束,且 Content 不能为空。Role 的顺序示例:[system(可选) user assistant user assistant user ...]。
+ // 3. Messages 中 Content 总长度不能超过 hunyuan-pro 模型输入长度上限(可参考 [产品概述](https://cloud.tencent.com/document/product/1729/104753) 文档),超过则会截断最前面的内容,只保留尾部内容。
+ Messages []*Message `json:"Messages,omitnil,omitempty" name:"Messages"`
+
+ // 说明:
+ // 1. 影响输出文本的多样性,取值越大,生成文本的多样性越强。
+ // 2. 默认 1.0,取值区间为 [0.0, 1.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ TopP *float64 `json:"TopP,omitnil,omitempty" name:"TopP"`
// 说明:
- // 1.影响输出文本的多样性,取值越大,生成文本的多样性越强。
- // 2.默认1.0,取值区间为[0.0, 1.0]。
- // 3.非必要不建议使用, 不合理的取值会影响效果。
- TopP *float64 `json:"TopP,omitnil" name:"TopP"`
+ // 1. 较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
+ // 2. 默认 1.0,取值区间为 [0.0, 2.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ Temperature *float64 `json:"Temperature,omitnil,omitempty" name:"Temperature"`
+ // 流式调用开关。
// 说明:
- // 1.较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
- // 2.默认1.0,取值区间为[0.0,2.0]。
- // 3.非必要不建议使用,不合理的取值会影响效果。
- Temperature *float64 `json:"Temperature,omitnil" name:"Temperature"`
+ // 1. 未传值时默认为流式调用。
+ // 2. 流式调用时以 SSE 协议增量返回结果。
+ // 3. 非流式调用时接口响应耗时较长,非必要不建议使用。
+ // 4. 非流式调用时只返回一次最终结果,调用方式与普通 HTTP 请求无异。
+ //
+ // 注意:
+ // 通过 SDK 调用时,流式和非流式调用需要用**不同的方式**获取返回值,具体参考 SDK 中的注释或示例(在各语言 SDK 代码仓库的 examples/hunyuan/v20230901/ 目录中)。
+ Stream *bool `json:"Stream,omitnil,omitempty" name:"Stream"`
+
+ // 流式输出审核开关。
+ // 说明:
+ // 1. 输出审核有流式和同步两种模式,**流式模式首包响应更快**。
+ // 2. 当使用流式输出(Stream 字段值为 true)时,该字段生效。
+ // 3. 如果值为 true,将对输出内容进行分段审核,审核通过的内容流式输出返回。如果出现审核不过,响应中的 FinishReason 值为 sensitive。
+ // 4. 如果未传值或值为 false,则不使用流式输出审核,需要审核完所有输出内容后再返回结果。
+ //
+ // 注意:
+ // 当选择流式输出审核时,可能会出现部分内容已输出,但中间某一段响应中的 FinishReason 值为 sensitive,此时说明安全审核未通过。如果业务场景有实时文字上屏的需求,需要自行撤回已上屏的内容,并建议自定义替换为一条提示语,如 “这个问题我不方便回答,不如我们换个话题试试”,以保障终端体验。
+ StreamModeration *bool `json:"StreamModeration,omitnil,omitempty" name:"StreamModeration"`
}
type ChatProRequest struct {
@@ -47,22 +246,45 @@ type ChatProRequest struct {
// 聊天上下文信息。
// 说明:
- // 1.长度最多为40, 按对话时间从旧到新在数组中排列。
- // 2.Message的Role当前可选值:system、user、assistant,其中,system角色是可选的,如果存在,必须位于列表的最开始。user和assistant需要交替出现(一问一答),最后一个为user提问, 且Content不能为空。
- // 3.Messages中Content总长度不超过16000 token,超过则会截断最前面的内容,只保留尾部内容。建议不超过4000 token。
- Messages []*Message `json:"Messages,omitnil" name:"Messages"`
+ // 1. 长度最多为 40,按对话时间从旧到新在数组中排列。
+ // 2. Message.Role 可选值:system、user、assistant。
+ // 其中,system 角色可选,如存在则必须位于列表的最开始。user 和 assistant 需交替出现(一问一答),以 user 提问开始和结束,且 Content 不能为空。Role 的顺序示例:[system(可选) user assistant user assistant user ...]。
+ // 3. Messages 中 Content 总长度不能超过 hunyuan-pro 模型输入长度上限(可参考 [产品概述](https://cloud.tencent.com/document/product/1729/104753) 文档),超过则会截断最前面的内容,只保留尾部内容。
+ Messages []*Message `json:"Messages,omitnil,omitempty" name:"Messages"`
+
+ // 说明:
+ // 1. 影响输出文本的多样性,取值越大,生成文本的多样性越强。
+ // 2. 默认 1.0,取值区间为 [0.0, 1.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ TopP *float64 `json:"TopP,omitnil,omitempty" name:"TopP"`
// 说明:
- // 1.影响输出文本的多样性,取值越大,生成文本的多样性越强。
- // 2.默认1.0,取值区间为[0.0, 1.0]。
- // 3.非必要不建议使用, 不合理的取值会影响效果。
- TopP *float64 `json:"TopP,omitnil" name:"TopP"`
+ // 1. 较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
+ // 2. 默认 1.0,取值区间为 [0.0, 2.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ Temperature *float64 `json:"Temperature,omitnil,omitempty" name:"Temperature"`
+ // 流式调用开关。
// 说明:
- // 1.较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
- // 2.默认1.0,取值区间为[0.0,2.0]。
- // 3.非必要不建议使用,不合理的取值会影响效果。
- Temperature *float64 `json:"Temperature,omitnil" name:"Temperature"`
+ // 1. 未传值时默认为流式调用。
+ // 2. 流式调用时以 SSE 协议增量返回结果。
+ // 3. 非流式调用时接口响应耗时较长,非必要不建议使用。
+ // 4. 非流式调用时只返回一次最终结果,调用方式与普通 HTTP 请求无异。
+ //
+ // 注意:
+ // 通过 SDK 调用时,流式和非流式调用需要用**不同的方式**获取返回值,具体参考 SDK 中的注释或示例(在各语言 SDK 代码仓库的 examples/hunyuan/v20230901/ 目录中)。
+ Stream *bool `json:"Stream,omitnil,omitempty" name:"Stream"`
+
+ // 流式输出审核开关。
+ // 说明:
+ // 1. 输出审核有流式和同步两种模式,**流式模式首包响应更快**。
+ // 2. 当使用流式输出(Stream 字段值为 true)时,该字段生效。
+ // 3. 如果值为 true,将对输出内容进行分段审核,审核通过的内容流式输出返回。如果出现审核不过,响应中的 FinishReason 值为 sensitive。
+ // 4. 如果未传值或值为 false,则不使用流式输出审核,需要审核完所有输出内容后再返回结果。
+ //
+ // 注意:
+ // 当选择流式输出审核时,可能会出现部分内容已输出,但中间某一段响应中的 FinishReason 值为 sensitive,此时说明安全审核未通过。如果业务场景有实时文字上屏的需求,需要自行撤回已上屏的内容,并建议自定义替换为一条提示语,如 “这个问题我不方便回答,不如我们换个话题试试”,以保障终端体验。
+ StreamModeration *bool `json:"StreamModeration,omitnil,omitempty" name:"StreamModeration"`
}
func (r *ChatProRequest) ToJsonString() string {
@@ -80,36 +302,100 @@ func (r *ChatProRequest) FromJsonString(s string) error {
delete(f, "Messages")
delete(f, "TopP")
delete(f, "Temperature")
+ delete(f, "Stream")
+ delete(f, "StreamModeration")
if len(f) > 0 {
return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "ChatProRequest has unknown keys!", "")
}
return json.Unmarshal([]byte(s), &r)
}
+// Predefined struct for user
+type ChatProResponseParams struct {
+ // Unix 时间戳,单位为秒。
+ Created *int64 `json:"Created,omitnil,omitempty" name:"Created"`
+
+ // Token 统计信息。
+ // 按照总 Token 数量计费。
+ Usage *Usage `json:"Usage,omitnil,omitempty" name:"Usage"`
+
+ // 免责声明。
+ Note *string `json:"Note,omitnil,omitempty" name:"Note"`
+
+ // 本轮对话的 ID。
+ Id *string `json:"Id,omitnil,omitempty" name:"Id"`
+
+ // 回复内容。
+ Choices []*Choice `json:"Choices,omitnil,omitempty" name:"Choices"`
+
+ // 错误信息。
+ // 如果流式返回中服务处理异常,返回该错误信息。
+ // 注意:此字段可能返回 null,表示取不到有效值。
+ ErrorMsg *ErrorMsg `json:"ErrorMsg,omitnil,omitempty" name:"ErrorMsg"`
+
+ // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。本接口为流式响应接口,当请求成功时,RequestId 会被放在 HTTP 响应的 Header "X-TC-RequestId" 中。
+ RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
+}
+
type ChatProResponse struct {
- tchttp.BaseSSEResponse
+ tchttp.BaseSSEResponse `json:"-"`
+ Response *ChatProResponseParams `json:"Response"`
+}
+
+func (r *ChatProResponse) ToJsonString() string {
+ b, _ := json.Marshal(r)
+ return string(b)
+}
+
+// FromJsonString It is highly **NOT** recommended to use this function
+// because it has no param check, nor strict type check
+func (r *ChatProResponse) FromJsonString(s string) error {
+ return json.Unmarshal([]byte(s), &r)
}
// Predefined struct for user
type ChatStdRequestParams struct {
// 聊天上下文信息。
// 说明:
- // 1.长度最多为40, 按对话时间从旧到新在数组中排列。
- // 2.Message的Role当前可选值:user、assistant,其中,user和assistant需要交替出现(一问一答),最后一个为user提问, 且Content不能为空。
- // 3.Messages中Content总长度不超过16000 token,超过则会截断最前面的内容,只保留尾部内容。建议不超过4000 token。
- Messages []*Message `json:"Messages,omitnil" name:"Messages"`
+ // 1. 长度最多为 40,按对话时间从旧到新在数组中排列。
+ // 2. Message 的 Role 当前可选值:user、assistant。
+ // 其中,user 和 assistant 需交替出现(一问一答),以 user 提问开始和结束,且 Content 不能为空。Role 的顺序示例:[user assistant user assistant user ...]。
+ // 3. Messages 中 Content 总长度不能超过 hunyuan-standard 模型输入长度上限(可参考 [产品概述](https://cloud.tencent.com/document/product/1729/104753) 文档),超过则会截断最前面的内容,只保留尾部内容。
+ Messages []*Message `json:"Messages,omitnil,omitempty" name:"Messages"`
+
+ // 说明:
+ // 1. 影响输出文本的多样性,取值越大,生成文本的多样性越强。
+ // 2. 默认 1.0,取值区间为 [0.0, 1.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ TopP *float64 `json:"TopP,omitnil,omitempty" name:"TopP"`
// 说明:
- // 1.影响输出文本的多样性,取值越大,生成文本的多样性越强。
- // 2.默认1.0,取值区间为[0.0, 1.0]。
- // 3.非必要不建议使用, 不合理的取值会影响效果。
- TopP *float64 `json:"TopP,omitnil" name:"TopP"`
+ // 1. 较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
+ // 2. 默认 1.0,取值区间为 [0.0, 2.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ Temperature *float64 `json:"Temperature,omitnil,omitempty" name:"Temperature"`
+ // 流式调用开关。
// 说明:
- // 1.较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
- // 2.默认1.0,取值区间为[0.0,2.0]。
- // 3.非必要不建议使用,不合理的取值会影响效果。
- Temperature *float64 `json:"Temperature,omitnil" name:"Temperature"`
+ // 1. 未传值时默认为流式调用。
+ // 2. 流式调用时以 SSE 协议增量返回结果。
+ // 3. 非流式调用时接口响应耗时较长,非必要不建议使用。
+ // 4. 非流式调用时只返回一次最终结果,调用方式与普通 HTTP 请求无异。
+ //
+ // 注意:
+ // 通过 SDK 调用时,流式和非流式调用需要用**不同的方式**获取返回值,具体参考 SDK 中的注释或示例(在各语言 SDK 代码仓库的 examples/hunyuan/v20230901/ 目录中)。
+ Stream *bool `json:"Stream,omitnil,omitempty" name:"Stream"`
+
+ // 流式输出审核开关。
+ // 说明:
+ // 1. 输出审核有流式和同步两种模式,**流式模式首包响应更快**。
+ // 2. 当使用流式输出(Stream 字段值为 true)时,该字段生效。
+ // 3. 如果值为 true,将对输出内容进行分段审核,审核通过的内容流式输出返回。如果出现审核不过,响应中的 FinishReason 值为 sensitive。
+ // 4. 如果未传值或值为 false,则不使用流式输出审核,需要审核完所有输出内容后再返回结果。
+ //
+ // 注意:
+ // 当选择流式输出审核时,可能会出现部分内容已输出,但中间某一段响应中的 FinishReason 值为 sensitive,此时说明安全审核未通过。如果业务场景有实时文字上屏的需求,需要自行撤回已上屏的内容,并建议自定义替换为一条提示语,如 “这个问题我不方便回答,不如我们换个话题试试”,以保障终端体验。
+ StreamModeration *bool `json:"StreamModeration,omitnil,omitempty" name:"StreamModeration"`
}
type ChatStdRequest struct {
@@ -117,22 +403,45 @@ type ChatStdRequest struct {
// 聊天上下文信息。
// 说明:
- // 1.长度最多为40, 按对话时间从旧到新在数组中排列。
- // 2.Message的Role当前可选值:user、assistant,其中,user和assistant需要交替出现(一问一答),最后一个为user提问, 且Content不能为空。
- // 3.Messages中Content总长度不超过16000 token,超过则会截断最前面的内容,只保留尾部内容。建议不超过4000 token。
- Messages []*Message `json:"Messages,omitnil" name:"Messages"`
+ // 1. 长度最多为 40,按对话时间从旧到新在数组中排列。
+ // 2. Message 的 Role 当前可选值:user、assistant。
+ // 其中,user 和 assistant 需交替出现(一问一答),以 user 提问开始和结束,且 Content 不能为空。Role 的顺序示例:[user assistant user assistant user ...]。
+ // 3. Messages 中 Content 总长度不能超过 hunyuan-standard 模型输入长度上限(可参考 [产品概述](https://cloud.tencent.com/document/product/1729/104753) 文档),超过则会截断最前面的内容,只保留尾部内容。
+ Messages []*Message `json:"Messages,omitnil,omitempty" name:"Messages"`
+
+ // 说明:
+ // 1. 影响输出文本的多样性,取值越大,生成文本的多样性越强。
+ // 2. 默认 1.0,取值区间为 [0.0, 1.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ TopP *float64 `json:"TopP,omitnil,omitempty" name:"TopP"`
// 说明:
- // 1.影响输出文本的多样性,取值越大,生成文本的多样性越强。
- // 2.默认1.0,取值区间为[0.0, 1.0]。
- // 3.非必要不建议使用, 不合理的取值会影响效果。
- TopP *float64 `json:"TopP,omitnil" name:"TopP"`
+ // 1. 较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
+ // 2. 默认 1.0,取值区间为 [0.0, 2.0]。
+ // 3. 非必要不建议使用,不合理的取值会影响效果。
+ Temperature *float64 `json:"Temperature,omitnil,omitempty" name:"Temperature"`
+ // 流式调用开关。
// 说明:
- // 1.较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。
- // 2.默认1.0,取值区间为[0.0,2.0]。
- // 3.非必要不建议使用,不合理的取值会影响效果。
- Temperature *float64 `json:"Temperature,omitnil" name:"Temperature"`
+ // 1. 未传值时默认为流式调用。
+ // 2. 流式调用时以 SSE 协议增量返回结果。
+ // 3. 非流式调用时接口响应耗时较长,非必要不建议使用。
+ // 4. 非流式调用时只返回一次最终结果,调用方式与普通 HTTP 请求无异。
+ //
+ // 注意:
+ // 通过 SDK 调用时,流式和非流式调用需要用**不同的方式**获取返回值,具体参考 SDK 中的注释或示例(在各语言 SDK 代码仓库的 examples/hunyuan/v20230901/ 目录中)。
+ Stream *bool `json:"Stream,omitnil,omitempty" name:"Stream"`
+
+ // 流式输出审核开关。
+ // 说明:
+ // 1. 输出审核有流式和同步两种模式,**流式模式首包响应更快**。
+ // 2. 当使用流式输出(Stream 字段值为 true)时,该字段生效。
+ // 3. 如果值为 true,将对输出内容进行分段审核,审核通过的内容流式输出返回。如果出现审核不过,响应中的 FinishReason 值为 sensitive。
+ // 4. 如果未传值或值为 false,则不使用流式输出审核,需要审核完所有输出内容后再返回结果。
+ //
+ // 注意:
+ // 当选择流式输出审核时,可能会出现部分内容已输出,但中间某一段响应中的 FinishReason 值为 sensitive,此时说明安全审核未通过。如果业务场景有实时文字上屏的需求,需要自行撤回已上屏的内容,并建议自定义替换为一条提示语,如 “这个问题我不方便回答,不如我们换个话题试试”,以保障终端体验。
+ StreamModeration *bool `json:"StreamModeration,omitnil,omitempty" name:"StreamModeration"`
}
func (r *ChatStdRequest) ToJsonString() string {
@@ -150,75 +459,122 @@ func (r *ChatStdRequest) FromJsonString(s string) error {
delete(f, "Messages")
delete(f, "TopP")
delete(f, "Temperature")
+ delete(f, "Stream")
+ delete(f, "StreamModeration")
if len(f) > 0 {
return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "ChatStdRequest has unknown keys!", "")
}
return json.Unmarshal([]byte(s), &r)
}
+// Predefined struct for user
+type ChatStdResponseParams struct {
+ // Unix 时间戳,单位为秒。
+ Created *int64 `json:"Created,omitnil,omitempty" name:"Created"`
+
+ // Token 统计信息。
+ // 按照总 Token 数量计费。
+ Usage *Usage `json:"Usage,omitnil,omitempty" name:"Usage"`
+
+ // 免责声明。
+ Note *string `json:"Note,omitnil,omitempty" name:"Note"`
+
+ // 本轮对话的 ID。
+ Id *string `json:"Id,omitnil,omitempty" name:"Id"`
+
+ // 回复内容。
+ Choices []*Choice `json:"Choices,omitnil,omitempty" name:"Choices"`
+
+ // 错误信息。
+ // 如果流式返回中服务处理异常,返回该错误信息。
+ // 注意:此字段可能返回 null,表示取不到有效值。
+ ErrorMsg *ErrorMsg `json:"ErrorMsg,omitnil,omitempty" name:"ErrorMsg"`
+
+ // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。本接口为流式响应接口,当请求成功时,RequestId 会被放在 HTTP 响应的 Header "X-TC-RequestId" 中。
+ RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
+}
+
type ChatStdResponse struct {
- tchttp.BaseSSEResponse
+ tchttp.BaseSSEResponse `json:"-"`
+ Response *ChatStdResponseParams `json:"Response"`
+}
+
+func (r *ChatStdResponse) ToJsonString() string {
+ b, _ := json.Marshal(r)
+ return string(b)
+}
+
+// FromJsonString It is highly **NOT** recommended to use this function
+// because it has no param check, nor strict type check
+func (r *ChatStdResponse) FromJsonString(s string) error {
+ return json.Unmarshal([]byte(s), &r)
}
type Choice struct {
- // 流式结束标志位,为 stop 则表示尾包。
- FinishReason *string `json:"FinishReason,omitnil" name:"FinishReason"`
+ // 结束标志位,可能为 stop 或 sensitive。
+ // stop 表示输出正常结束,sensitive 只在开启流式输出审核时会出现,表示安全审核未通过。
+ FinishReason *string `json:"FinishReason,omitnil,omitempty" name:"FinishReason"`
+
+ // 增量返回值,流式调用时使用该字段。
+ // 注意:此字段可能返回 null,表示取不到有效值。
+ Delta *Delta `json:"Delta,omitnil,omitempty" name:"Delta"`
- // 返回值。
- Delta *Delta `json:"Delta,omitnil" name:"Delta"`
+ // 返回值,非流式调用时使用该字段。
+ // 注意:此字段可能返回 null,表示取不到有效值。
+ Message *Message `json:"Message,omitnil,omitempty" name:"Message"`
}
type Delta struct {
// 角色名称。
- Role *string `json:"Role,omitnil" name:"Role"`
+ Role *string `json:"Role,omitnil,omitempty" name:"Role"`
// 内容详情。
- Content *string `json:"Content,omitnil" name:"Content"`
+ Content *string `json:"Content,omitnil,omitempty" name:"Content"`
}
type EmbeddingData struct {
// embedding 信息。
// 注意:此字段可能返回 null,表示取不到有效值。
- Embedding []*float64 `json:"Embedding,omitnil" name:"Embedding"`
+ Embedding []*float64 `json:"Embedding,omitnil,omitempty" name:"Embedding"`
// 下标。
// 注意:此字段可能返回 null,表示取不到有效值。
- Index *int64 `json:"Index,omitnil" name:"Index"`
+ Index *int64 `json:"Index,omitnil,omitempty" name:"Index"`
// embedding
// 注意:此字段可能返回 null,表示取不到有效值。
- Object *string `json:"Object,omitnil" name:"Object"`
+ Object *string `json:"Object,omitnil,omitempty" name:"Object"`
}
type EmbeddingUsage struct {
- // 输入Token数。
- PromptTokens *int64 `json:"PromptTokens,omitnil" name:"PromptTokens"`
+ // 输入 Token 数。
+ PromptTokens *int64 `json:"PromptTokens,omitnil,omitempty" name:"PromptTokens"`
- // 总Token数。
- TotalTokens *int64 `json:"TotalTokens,omitnil" name:"TotalTokens"`
+ // 总 Token 数。
+ TotalTokens *int64 `json:"TotalTokens,omitnil,omitempty" name:"TotalTokens"`
}
type ErrorMsg struct {
// 错误提示信息。
- Msg *string `json:"Msg,omitnil" name:"Msg"`
+ Msg *string `json:"Msg,omitnil,omitempty" name:"Msg"`
// 错误码。
// 4000 服务内部异常。
// 4001 请求模型超时。
- Code *int64 `json:"Code,omitnil" name:"Code"`
+ Code *int64 `json:"Code,omitnil,omitempty" name:"Code"`
}
// Predefined struct for user
type GetEmbeddingRequestParams struct {
- // 输入文本。总长度不超过1024 个token, 超过则会截断最后面的内容。
- Input *string `json:"Input,omitnil" name:"Input"`
+ // 输入文本。总长度不超过 1024 个 Token,超过则会截断最后面的内容。
+ Input *string `json:"Input,omitnil,omitempty" name:"Input"`
}
type GetEmbeddingRequest struct {
*tchttp.BaseRequest
- // 输入文本。总长度不超过1024 个token, 超过则会截断最后面的内容。
- Input *string `json:"Input,omitnil" name:"Input"`
+ // 输入文本。总长度不超过 1024 个 Token,超过则会截断最后面的内容。
+ Input *string `json:"Input,omitnil,omitempty" name:"Input"`
}
func (r *GetEmbeddingRequest) ToJsonString() string {
@@ -242,14 +598,14 @@ func (r *GetEmbeddingRequest) FromJsonString(s string) error {
// Predefined struct for user
type GetEmbeddingResponseParams struct {
- // 返回的 embedding 信息。
- Data []*EmbeddingData `json:"Data,omitnil" name:"Data"`
+ // 返回的 Embedding 信息。当前不支持批量,所以数组元素数目为 1。
+ Data []*EmbeddingData `json:"Data,omitnil,omitempty" name:"Data"`
- // token 使用计数,按照总token数量收费。
- Usage *EmbeddingUsage `json:"Usage,omitnil" name:"Usage"`
+ // Token 使用计数,按照总 Token 数量收费。
+ Usage *EmbeddingUsage `json:"Usage,omitnil,omitempty" name:"Usage"`
- // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
- RequestId *string `json:"RequestId,omitnil" name:"RequestId"`
+ // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。
+ RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
}
type GetEmbeddingResponse struct {
@@ -271,14 +627,14 @@ func (r *GetEmbeddingResponse) FromJsonString(s string) error {
// Predefined struct for user
type GetTokenCountRequestParams struct {
// 输入文本
- Prompt *string `json:"Prompt,omitnil" name:"Prompt"`
+ Prompt *string `json:"Prompt,omitnil,omitempty" name:"Prompt"`
}
type GetTokenCountRequest struct {
*tchttp.BaseRequest
// 输入文本
- Prompt *string `json:"Prompt,omitnil" name:"Prompt"`
+ Prompt *string `json:"Prompt,omitnil,omitempty" name:"Prompt"`
}
func (r *GetTokenCountRequest) ToJsonString() string {
@@ -303,16 +659,16 @@ func (r *GetTokenCountRequest) FromJsonString(s string) error {
// Predefined struct for user
type GetTokenCountResponseParams struct {
// token计数
- TokenCount *int64 `json:"TokenCount,omitnil" name:"TokenCount"`
+ TokenCount *int64 `json:"TokenCount,omitnil,omitempty" name:"TokenCount"`
// 字符计数
- CharacterCount *int64 `json:"CharacterCount,omitnil" name:"CharacterCount"`
+ CharacterCount *int64 `json:"CharacterCount,omitnil,omitempty" name:"CharacterCount"`
// 切分后的列表
- Tokens []*string `json:"Tokens,omitnil" name:"Tokens"`
+ Tokens []*string `json:"Tokens,omitnil,omitempty" name:"Tokens"`
- // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
- RequestId *string `json:"RequestId,omitnil" name:"RequestId"`
+ // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。
+ RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
}
type GetTokenCountResponse struct {
@@ -333,19 +689,200 @@ func (r *GetTokenCountResponse) FromJsonString(s string) error {
type Message struct {
// 角色
- Role *string `json:"Role,omitnil" name:"Role"`
+ Role *string `json:"Role,omitnil,omitempty" name:"Role"`
+
+ // 文本内容
+ Content *string `json:"Content,omitnil,omitempty" name:"Content"`
+}
+
+// Predefined struct for user
+type QueryHunyuanImageJobRequestParams struct {
+ // 任务 ID。
+ JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
+}
+
+type QueryHunyuanImageJobRequest struct {
+ *tchttp.BaseRequest
+
+ // 任务 ID。
+ JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
+}
+
+func (r *QueryHunyuanImageJobRequest) ToJsonString() string {
+ b, _ := json.Marshal(r)
+ return string(b)
+}
+
+// FromJsonString It is highly **NOT** recommended to use this function
+// because it has no param check, nor strict type check
+func (r *QueryHunyuanImageJobRequest) FromJsonString(s string) error {
+ f := make(map[string]interface{})
+ if err := json.Unmarshal([]byte(s), &f); err != nil {
+ return err
+ }
+ delete(f, "JobId")
+ if len(f) > 0 {
+ return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "QueryHunyuanImageJobRequest has unknown keys!", "")
+ }
+ return json.Unmarshal([]byte(s), &r)
+}
+
+// Predefined struct for user
+type QueryHunyuanImageJobResponseParams struct {
+ // 当前任务状态码:
+ // 1:等待中、2:运行中、4:处理失败、5:处理完成。
+ JobStatusCode *string `json:"JobStatusCode,omitnil,omitempty" name:"JobStatusCode"`
+
+ // 当前任务状态:排队中、处理中、处理失败或者处理完成。
+ JobStatusMsg *string `json:"JobStatusMsg,omitnil,omitempty" name:"JobStatusMsg"`
+
+ // 任务处理失败错误码。
+ JobErrorCode *string `json:"JobErrorCode,omitnil,omitempty" name:"JobErrorCode"`
+
+ // 任务处理失败错误信息。
+ JobErrorMsg *string `json:"JobErrorMsg,omitnil,omitempty" name:"JobErrorMsg"`
+
+ // 生成图 URL 列表,有效期1小时,请及时保存。
+ ResultImage []*string `json:"ResultImage,omitnil,omitempty" name:"ResultImage"`
+
+ // 结果 detail 数组,Success 代表成功。
+ ResultDetails []*string `json:"ResultDetails,omitnil,omitempty" name:"ResultDetails"`
+
+ // 对应 SubmitTextToImageProJob 接口中 Revise 参数。开启扩写时,返回扩写后的 prompt 文本。 如果关闭扩写,将直接返回原始输入的 prompt。
+ RevisedPrompt []*string `json:"RevisedPrompt,omitnil,omitempty" name:"RevisedPrompt"`
+
+ // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。
+ RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
+}
- // 消息的内容
- Content *string `json:"Content,omitnil" name:"Content"`
+type QueryHunyuanImageJobResponse struct {
+ *tchttp.BaseResponse
+ Response *QueryHunyuanImageJobResponseParams `json:"Response"`
+}
+
+func (r *QueryHunyuanImageJobResponse) ToJsonString() string {
+ b, _ := json.Marshal(r)
+ return string(b)
+}
+
+// FromJsonString It is highly **NOT** recommended to use this function
+// because it has no param check, nor strict type check
+func (r *QueryHunyuanImageJobResponse) FromJsonString(s string) error {
+ return json.Unmarshal([]byte(s), &r)
+}
+
+// Predefined struct for user
+type SubmitHunyuanImageJobRequestParams struct {
+ // 文本描述。 算法将根据输入的文本智能生成与之相关的图像。 不能为空,推荐使用中文。最多可传100个 utf-8 字符。
+ Prompt *string `json:"Prompt,omitnil,omitempty" name:"Prompt"`
+
+ // 绘画风格。
+ // 请在 [混元生图风格列表](https://cloud.tencent.com/document/product/1729/105846) 中选择期望的风格,传入风格编号。
+ // 不传默认不指定风格。
+ Style *string `json:"Style,omitnil,omitempty" name:"Style"`
+
+ // 生成图分辨率。
+ // 支持生成以下分辨率的图片:768:768(1:1)、768:1024(3:4)、1024:768(4:3)、1024:1024(1:1)、720:1280(9:16)、1280:720(16:9)、768:1280(3:5)、1280:768(5:3),不传默认使用1024:1024。
+ Resolution *string `json:"Resolution,omitnil,omitempty" name:"Resolution"`
+
+ // 为生成结果图添加显式水印标识的开关,默认为1。
+ // 1:添加。
+ // 0:不添加。
+ // 其他数值:默认按1处理。
+ // 建议您使用显著标识来提示结果图使用了 AI 绘画技术,是 AI 生成的图片。
+ LogoAdd *int64 `json:"LogoAdd,omitnil,omitempty" name:"LogoAdd"`
+
+ // prompt 扩写开关。1为开启,0为关闭,不传默认开启。
+ // 开启扩写后,将自动扩写原始输入的 prompt 并使用扩写后的 prompt 生成图片,返回生成图片结果时将一并返回扩写后的 prompt 文本。
+ // 如果关闭扩写,将直接使用原始输入的 prompt 生成图片。
+ // 建议开启,在多数场景下可提升生成图片效果、丰富生成图片细节。
+ Revise *int64 `json:"Revise,omitnil,omitempty" name:"Revise"`
+}
+
+type SubmitHunyuanImageJobRequest struct {
+ *tchttp.BaseRequest
+
+ // 文本描述。 算法将根据输入的文本智能生成与之相关的图像。 不能为空,推荐使用中文。最多可传100个 utf-8 字符。
+ Prompt *string `json:"Prompt,omitnil,omitempty" name:"Prompt"`
+
+ // 绘画风格。
+ // 请在 [混元生图风格列表](https://cloud.tencent.com/document/product/1729/105846) 中选择期望的风格,传入风格编号。
+ // 不传默认不指定风格。
+ Style *string `json:"Style,omitnil,omitempty" name:"Style"`
+
+ // 生成图分辨率。
+ // 支持生成以下分辨率的图片:768:768(1:1)、768:1024(3:4)、1024:768(4:3)、1024:1024(1:1)、720:1280(9:16)、1280:720(16:9)、768:1280(3:5)、1280:768(5:3),不传默认使用1024:1024。
+ Resolution *string `json:"Resolution,omitnil,omitempty" name:"Resolution"`
+
+ // 为生成结果图添加显式水印标识的开关,默认为1。
+ // 1:添加。
+ // 0:不添加。
+ // 其他数值:默认按1处理。
+ // 建议您使用显著标识来提示结果图使用了 AI 绘画技术,是 AI 生成的图片。
+ LogoAdd *int64 `json:"LogoAdd,omitnil,omitempty" name:"LogoAdd"`
+
+ // prompt 扩写开关。1为开启,0为关闭,不传默认开启。
+ // 开启扩写后,将自动扩写原始输入的 prompt 并使用扩写后的 prompt 生成图片,返回生成图片结果时将一并返回扩写后的 prompt 文本。
+ // 如果关闭扩写,将直接使用原始输入的 prompt 生成图片。
+ // 建议开启,在多数场景下可提升生成图片效果、丰富生成图片细节。
+ Revise *int64 `json:"Revise,omitnil,omitempty" name:"Revise"`
+}
+
+func (r *SubmitHunyuanImageJobRequest) ToJsonString() string {
+ b, _ := json.Marshal(r)
+ return string(b)
+}
+
+// FromJsonString It is highly **NOT** recommended to use this function
+// because it has no param check, nor strict type check
+func (r *SubmitHunyuanImageJobRequest) FromJsonString(s string) error {
+ f := make(map[string]interface{})
+ if err := json.Unmarshal([]byte(s), &f); err != nil {
+ return err
+ }
+ delete(f, "Prompt")
+ delete(f, "Style")
+ delete(f, "Resolution")
+ delete(f, "LogoAdd")
+ delete(f, "Revise")
+ if len(f) > 0 {
+ return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "SubmitHunyuanImageJobRequest has unknown keys!", "")
+ }
+ return json.Unmarshal([]byte(s), &r)
+}
+
+// Predefined struct for user
+type SubmitHunyuanImageJobResponseParams struct {
+ // 任务 ID。
+ JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
+
+ // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。
+ RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
+}
+
+type SubmitHunyuanImageJobResponse struct {
+ *tchttp.BaseResponse
+ Response *SubmitHunyuanImageJobResponseParams `json:"Response"`
+}
+
+func (r *SubmitHunyuanImageJobResponse) ToJsonString() string {
+ b, _ := json.Marshal(r)
+ return string(b)
+}
+
+// FromJsonString It is highly **NOT** recommended to use this function
+// because it has no param check, nor strict type check
+func (r *SubmitHunyuanImageJobResponse) FromJsonString(s string) error {
+ return json.Unmarshal([]byte(s), &r)
}
type Usage struct {
- // 输入 token 数量。
- PromptTokens *int64 `json:"PromptTokens,omitnil" name:"PromptTokens"`
+ // 输入 Token 数量。
+ PromptTokens *int64 `json:"PromptTokens,omitnil,omitempty" name:"PromptTokens"`
- // 输出 token 数量。
- CompletionTokens *int64 `json:"CompletionTokens,omitnil" name:"CompletionTokens"`
+ // 输出 Token 数量。
+ CompletionTokens *int64 `json:"CompletionTokens,omitnil,omitempty" name:"CompletionTokens"`
- // 总 token 数量。
- TotalTokens *int64 `json:"TotalTokens,omitnil" name:"TotalTokens"`
+ // 总 Token 数量。
+ TotalTokens *int64 `json:"TotalTokens,omitnil,omitempty" name:"TotalTokens"`
}
diff --git a/structs/struct.go b/structs/struct.go
index 9e01676..a04e96e 100644
--- a/structs/struct.go
+++ b/structs/struct.go
@@ -264,8 +264,11 @@ type Settings struct {
MdPromptKeyboardAtGroup bool `yaml:"mdPromptKeyboardAtGroup"` // 群内使用md能力模拟PromptKeyboard
GroupHintWords []string `yaml:"groupHintWords"`
- HunyuanType int `yaml:"hunyuanType"`
- MaxTokensHunyuan int `yaml:"maxTokensHunyuan"`
+ HunyuanType int `yaml:"hunyuanType"`
+ MaxTokensHunyuan int `yaml:"maxTokensHunyuan"`
+ HunyuanStreamModeration bool `yaml:"hunyuanStreamModeration"`
+ TopPHunyuan float64 `yaml:"topPHunyuan"`
+ TemperatureHunyuan float64 `yaml:"temperatureHunyuan"`
WenxinAccessToken string `yaml:"wenxinAccessToken"`
WenxinApiPath string `yaml:"wenxinApiPath"`
diff --git a/template/config_template.go b/template/config_template.go
index 4c559a8..215e99a 100644
--- a/template/config_template.go
+++ b/template/config_template.go
@@ -99,7 +99,10 @@ settings:
secretKey : ""
region : "" #留空
maxTokensHunyuan : 4096 #最大上下文
- hunyuanType : 0 #0=高级版 1=标准版 价格差异10倍
+ hunyuanType : 0 #0=高级版 1=标准版std 2=hunyuan-lite 3=hunyuan-standard 4=hunyuan-standard-256K 5=hunyuan-pro
+ hunyuanStreamModeration : false #是否采用流式审核
+ topPHunyuan : 1.0 #累积概率最高的令牌进行采样的界限
+ temperatureHunyuan : 1.0 #生成的随机性控制
#文心配置项
wenxinAccessToken : "" #请求百度access_token接口获取到的,有效期一个月,需要自己请求获取
diff --git a/utils/utils.go b/utils/utils.go
index 37f798e..0c57b76 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -70,6 +70,17 @@ func PrintChatStdRequest(request *hunyuan.ChatStdRequest) {
}
+func PrintChatCompletionsRequest(request *hunyuan.ChatCompletionsRequest) {
+
+ // 打印Messages
+ for i, msg := range request.Messages {
+ fmtf.Printf("Message %d:\n", i)
+ fmtf.Printf("Content: %s\n", *msg.Content)
+ fmtf.Printf("Role: %s\n", *msg.Role)
+ }
+
+}
+
// contains 检查一个字符串切片是否包含一个特定的字符串
func Contains(slice []string, item string) bool {
for _, a := range slice {
From d1053df9e9b60c88f20847e1873af8530ef5105e Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Sun, 19 May 2024 14:43:14 +0800
Subject: [PATCH 06/12] Beta120 (#118)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
* beta118
* beta119
* beta120
---
applogic/gensokyo.go | 12 ++----
config/config.go | 10 +++++
main.go | 5 +++
readme.md | 28 +++++++-----
server/server.go | 45 +++++++++++++++++--
structs/struct.go | 1 +
template/config_template.go | 1 +
utils/utils.go | 86 ++++++++++++++++++++++++++++++++-----
8 files changed, 156 insertions(+), 32 deletions(-)
diff --git a/applogic/gensokyo.go b/applogic/gensokyo.go
index 60d5a94..eb5c435 100644
--- a/applogic/gensokyo.go
+++ b/applogic/gensokyo.go
@@ -206,18 +206,14 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
}
}
- // 读取URL参数 "selfid"
- selfid := r.URL.Query().Get("selfid")
- if selfid != "" {
- // 使用 prompt 变量进行后续处理
- fmt.Printf("收到selfid参数: %s\n", selfid)
- }
+ // 直接从ob11事件获取selfid
+ selfid := strconv.FormatInt(message.SelfID, 10)
// 读取URL参数 "api"
api := r.URL.Query().Get("api")
- if selfid != "" {
+ if api != "" {
// 使用 prompt 变量进行后续处理
- fmt.Printf("收到api参数: %s\n", selfid)
+ fmt.Printf("收到api参数: %s\n", api)
}
// 打印日志信息,包括prompt参数
diff --git a/config/config.go b/config/config.go
index c87ae21..5fda48c 100644
--- a/config/config.go
+++ b/config/config.go
@@ -231,6 +231,16 @@ func IPWhiteList() []string {
return nil
}
+// 获取HttpPaths
+func GetHttpPaths() []string {
+ mu.Lock()
+ defer mu.Unlock()
+ if instance != nil {
+ return instance.Settings.HttpPaths
+ }
+ return nil
+}
+
// 获取最大上下文
func GetMaxTokensHunyuan(options ...string) int {
mu.Lock()
diff --git a/main.go b/main.go
index c950854..7de4084 100644
--- a/main.go
+++ b/main.go
@@ -195,6 +195,11 @@ func main() {
log.Fatalf("Failed to load blacklist: %v", err)
}
+ // 判断是否设置多个http地址,获取对应关系
+ if len(config.GetHttpPaths()) > 0 {
+ utils.FetchAndStoreUserIDs()
+ }
+
// 启动黑名单文件变动监听
go utils.WatchBlacklist(blacklistPath)
diff --git a/readme.md b/readme.md
index 6df07f8..f6750d1 100644
--- a/readme.md
+++ b/readme.md
@@ -32,16 +32,6 @@ _✨ 适用于Gensokyo以及Onebotv11的大模型一键端 ✨_
并发环境下的sse内存安全,支持维持多用户同时双向sse传输
----
-
-## 效果
-
-![效果图](/pic/3.png)
-
-![效果图](/pic/4.png)
-
----
-
## 支持llm平台
腾讯混元
@@ -117,6 +107,14 @@ AhoCorasick算法实现的超高效文本IN-Out替换规则,可大量替换n
支持中间件开发,在gensokyo框架层到gensokyo-llm的http请求之间,可开发中间件实现向量拓展,数据库拓展,动态修改用户问题.
+支持反向ws连接,支持同时连接多个onebotv11的http-api
+
+---
+
+## 使用教程
+
+施工中...(部署非常简单,有一定onebotv11机器人部署经验者可参考config.yml注释直接部署出来.)
+
---
# API接口调用说明
@@ -285,6 +283,16 @@ exitOnQ需要enhancedPromptChoices=true,其实enhancedPromptChoices最好就是t
promptMarks和switchOnQ、switchOnA在功能上是相同的,都是根据关键字跳转分支,promptMarks先执行,不分轮次不分QA,switchOnQ和switchOnA更具体,区分Q和A,区分轮次,实现细节跳转。
+---
+
+## 故事模式效果(QQ开放平台)
+
+![效果图](/pic/3.png)
+
+![效果图](/pic/4.png)
+
+---
+
## 已知问题
如果有固定且不需要切换的分支,请设置该yml的promptMarksLength为99999
diff --git a/server/server.go b/server/server.go
index eaa1706..bfcc210 100644
--- a/server/server.go
+++ b/server/server.go
@@ -30,12 +30,49 @@ var upgrader = websocket.Upgrader{
},
}
+// 全局变量和互斥锁
+var (
+ selfIDs []string
+ selfIDsMu sync.Mutex
+)
+
+// AddSelfID 添加一个 ID 到全局切片中
+func AddSelfID(id string) {
+ selfIDsMu.Lock()
+ defer selfIDsMu.Unlock()
+ selfIDs = append(selfIDs, id)
+}
+
+// GetSelfIDs 返回当前保存的所有 ID
+func GetSelfIDs() []string {
+ selfIDsMu.Lock()
+ defer selfIDsMu.Unlock()
+ // 返回切片的副本以防止外部修改
+ copiedIDs := make([]string, len(selfIDs))
+ copy(copiedIDs, selfIDs)
+ return copiedIDs
+}
+
+// IsSelfIDExists 检查一个 ID 是否存在于全局切片中
+func IsSelfIDExists(id string) bool {
+ selfIDsMu.Lock()
+ defer selfIDsMu.Unlock()
+ for _, sid := range selfIDs {
+ if sid == id {
+ return true
+ }
+ }
+ return false
+}
+
// 用于处理WebSocket连接
func WsHandler(w http.ResponseWriter, r *http.Request, config *config.Config) {
// 从请求头或URL查询参数中提取token
tokenFromHeader := r.Header.Get("Authorization")
selfID := r.Header.Get("X-Self-ID")
fmtf.Printf("接入机器人X-Self-ID[%v]", selfID)
+ // 加入到数组里
+ AddSelfID(selfID)
var token string
if strings.HasPrefix(tokenFromHeader, "Token ") {
token = strings.TrimPrefix(tokenFromHeader, "Token ")
@@ -86,13 +123,13 @@ func WsHandler(w http.ResponseWriter, r *http.Request, config *config.Config) {
}
if messageType == websocket.TextMessage {
- processWSMessage(p, selfID)
+ processWSMessage(p)
}
}
}
// 处理收到的信息
-func processWSMessage(msg []byte, selfid string) {
+func processWSMessage(msg []byte) {
var genericMap map[string]interface{}
if err := json.Unmarshal(msg, &genericMap); err != nil {
log.Printf("Error unmarshalling message to map: %v, Original message: %s\n", err, string(msg))
@@ -131,9 +168,9 @@ func processWSMessage(msg []byte, selfid string) {
// 构造请求URL
var url string
if config.GetLotus() == "" {
- url = "http://127.0.0.1:" + fmt.Sprint(port) + "/gensokyo?selfid=" + selfid
+ url = "http://127.0.0.1:" + fmt.Sprint(port) + "/gensokyo"
} else {
- url = config.GetLotus() + "/gensokyo?selfid=" + selfid
+ url = config.GetLotus() + "/gensokyo"
}
// 创建POST请求
diff --git a/structs/struct.go b/structs/struct.go
index a04e96e..3c9cebd 100644
--- a/structs/struct.go
+++ b/structs/struct.go
@@ -254,6 +254,7 @@ type Settings struct {
Port int `yaml:"port"`
SelfPath string `yaml:"selfPath"`
HttpPath string `yaml:"path"`
+ HttpPaths []string `yaml:"paths"`
Lotus string `yaml:"lotus"`
PathToken string `yaml:"pathToken"`
SystemPrompt []string `yaml:"systemPrompt"`
diff --git a/template/config_template.go b/template/config_template.go
index 215e99a..d258476 100644
--- a/template/config_template.go
+++ b/template/config_template.go
@@ -10,6 +10,7 @@ settings:
port : 46233 #本程序监听端口,支持gensokyo http上报, 请在gensokyo的反向http配置加入 post_url: ["http://127.0.0.1:port/gensokyo"]
selfPath : "" #本程序监听地址,不包含http头,请放通port到公网,仅发图场景需要填写,可以是域名,暂不支持https.
path : "http://123.123.123.123:11111" #调用gensokyo api的地址,填入 gensokyo 的 正向http地址 http_address: "0.0.0.0:46231" 对应填入 "http://127.0.0.1:46231"
+ paths : [] #当要连接多个onebotv11的http正向地址时,多个地址填入这里.
lotus : "" #当填写另一个gensokyo-llm的http地址时,将请求另一个的conversation端点,实现多个llm不需要多次配置,简化配置,单独使用请忽略留空.例:http://192.168.0.1:12345(包含http头和端口)
pathToken : "" #gensokyo正向http-api的access_token(是onebotv11标准的)
apiType : 0 #0=混元 1=文心(文心平台包含了N种模型...) 2=gpt 3=rwkv 4=通义千问 5=智谱AI
diff --git a/utils/utils.go b/utils/utils.go
index 0c57b76..f543ef5 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -44,6 +44,57 @@ type MessageIDInfo struct {
var UserIDMessageIDs = make(map[int64][]MessageIDInfo)
var muUserIDMessageIDs sync.RWMutex // 用于UserIDMessageIDs的读写锁
+var (
+ baseURLMap = make(map[string]string)
+ baseURLMapMu sync.Mutex
+)
+
+// 结构体用于解析 JSON 响应
+type loginInfoResponse struct {
+ Status string `json:"status"`
+ Retcode int `json:"retcode"`
+ Data struct {
+ UserID int64 `json:"user_id"`
+ Nickname string `json:"nickname"`
+ } `json:"data"`
+}
+
+// 构造 URL 并请求数据
+func FetchAndStoreUserIDs() {
+ httpPaths := config.GetHttpPaths()
+ for _, baseURL := range httpPaths {
+ url := baseURL + "/get_login_info"
+ resp, err := http.Get(url)
+ if err != nil {
+ fmtf.Printf("Error fetching login info from %s: %v", url, err)
+ continue
+ }
+ defer resp.Body.Close()
+
+ var result loginInfoResponse
+ if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
+ fmtf.Printf("Error decoding response from %s: %v", url, err)
+ continue
+ }
+
+ if result.Retcode == 0 && result.Status == "ok" {
+ fmtf.Printf("成功绑定机器人selfid[%v]onebot api baseURL[%v]", result.Data.UserID, baseURL)
+ baseURLMapMu.Lock()
+ useridstr := strconv.FormatInt(result.Data.UserID, 10)
+ baseURLMap[useridstr] = baseURL
+ baseURLMapMu.Unlock()
+ }
+ }
+}
+
+// GetBaseURLByUserID 通过 user_id 获取 baseURL
+func GetBaseURLByUserID(userID string) (string, bool) {
+ baseURLMapMu.Lock()
+ defer baseURLMapMu.Unlock()
+ url, exists := baseURLMap[userID]
+ return url, exists
+}
+
func GenerateUUID() string {
return uuid.New().String()
}
@@ -158,7 +209,7 @@ func ExtractEventDetails(eventData map[string]interface{}) (string, structs.Usag
func SendGroupMessage(groupID int64, userID int64, message string, selfid string) error {
//TODO: 用userid作为了echo,在ws收到回调信息的时候,加入到全局撤回数组,AddMessageID,实现撤回
- if selfid != "" {
+ if server.IsSelfIDExists(selfid) {
// 创建消息结构体
msg := map[string]interface{}{
"action": "send_group_msg",
@@ -173,8 +224,13 @@ func SendGroupMessage(groupID int64, userID int64, message string, selfid string
// 发送消息
return server.SendMessageBySelfID(selfid, msg)
}
- // 获取基础URL
- baseURL := config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
+ var baseURL string
+ if len(config.GetHttpPaths()) > 0 {
+ baseURL, _ = GetBaseURLByUserID(selfid)
+ } else {
+ // 获取基础URL
+ baseURL = config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
+ }
// 构建完整的URL
baseURL = baseURL + "/send_group_msg"
@@ -255,7 +311,7 @@ func SendGroupMessage(groupID int64, userID int64, message string, selfid string
func SendGroupMessageMdPromptKeyboard(groupID int64, userID int64, message string, selfid string, newmsg string, response string, promptstr string) error {
//TODO: 用userid作为了echo,在ws收到回调信息的时候,加入到全局撤回数组,AddMessageID,实现反向ws连接时候的撤回
- if selfid != "" {
+ if server.IsSelfIDExists(selfid) {
// 创建消息结构体
msg := map[string]interface{}{
"action": "send_group_msg",
@@ -493,7 +549,7 @@ func SendGroupMessageMdPromptKeyboard(groupID int64, userID int64, message strin
}
func SendPrivateMessage(UserID int64, message string, selfid string) error {
- if selfid != "" {
+ if server.IsSelfIDExists(selfid) {
// 创建消息结构体
msg := map[string]interface{}{
"action": "send_private_msg",
@@ -507,8 +563,13 @@ func SendPrivateMessage(UserID int64, message string, selfid string) error {
// 发送消息
return server.SendMessageBySelfID(selfid, msg)
}
- // 获取基础URL
- baseURL := config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
+ var baseURL string
+ if len(config.GetHttpPaths()) > 0 {
+ baseURL, _ = GetBaseURLByUserID(selfid)
+ } else {
+ // 获取基础URL
+ baseURL = config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
+ }
// 构建完整的URL
baseURL = baseURL + "/send_private_msg"
@@ -587,7 +648,7 @@ func SendPrivateMessage(UserID int64, message string, selfid string) error {
}
func SendPrivateMessageRaw(UserID int64, message string, selfid string) error {
- if selfid != "" {
+ if server.IsSelfIDExists(selfid) {
// 创建消息结构体
msg := map[string]interface{}{
"action": "send_private_msg",
@@ -601,8 +662,13 @@ func SendPrivateMessageRaw(UserID int64, message string, selfid string) error {
// 发送消息
return server.SendMessageBySelfID(selfid, msg)
}
- // 获取基础URL
- baseURL := config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
+ var baseURL string
+ if len(config.GetHttpPaths()) > 0 {
+ baseURL, _ = GetBaseURLByUserID(selfid)
+ } else {
+ // 获取基础URL
+ baseURL = config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
+ }
// 构建完整的URL
baseURL = baseURL + "/send_private_msg"
From e2a3709e3f506e5ca2d43e5e674d4b3902e82797 Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Sun, 19 May 2024 14:54:47 +0800
Subject: [PATCH 07/12] Beta121 (#119)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
* beta118
* beta119
* beta120
* beta121
---
readme.md | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/readme.md b/readme.md
index f6750d1..df0318c 100644
--- a/readme.md
+++ b/readme.md
@@ -168,6 +168,16 @@ settings:
GET /gensokyo?prompt=example&api=conversation_ernie
```
+支持端点列表:(需配置:allApi : true)
+```golang
+http.HandleFunc("/conversation_gpt", app.ChatHandlerChatgpt)
+ http.HandleFunc("/conversation_hunyuan", app.ChatHandlerHunyuan)
+ http.HandleFunc("/conversation_ernie", app.ChatHandlerErnie)
+ http.HandleFunc("/conversation_rwkv", app.ChatHandlerRwkv)
+ http.HandleFunc("/conversation_tyqw", app.ChatHandlerTyqw)
+ http.HandleFunc("/conversation_glm", app.ChatHandlerGlm)
+```
+
## 请求 `/conversation` 端点
与 `/gensokyo` 类似,`/conversation` 端点支持附加 `prompt` 参数。
From 21a233dbeddaa86300f7177f0ad7b9a8b67c4741 Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Sun, 19 May 2024 23:14:44 +0800
Subject: [PATCH 08/12] Beta122 (#120)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
* beta118
* beta119
* beta120
* beta121
* beta122
---
...47\345\244\247\346\250\241\345\236\213.md" | 90 +++++++++++++++++
...3-\345\233\275\351\231\205\347\257\207.md" | 49 ++++++++++
...216\245one-api\346\225\231\347\250\213.md" | 39 ++++++++
...45\346\234\272\345\231\250\344\272\272.md" | 98 +++++++++++++++++++
readme.md | 18 ++--
5 files changed, 287 insertions(+), 7 deletions(-)
create mode 100644 "docs/\344\270\255\347\272\247-\345\244\247\346\250\241\345\236\213api\351\205\215\347\275\256\347\244\272\344\276\213-\345\233\275\344\272\247\345\244\247\346\250\241\345\236\213.md"
create mode 100644 "docs/\344\270\255\347\272\247-\345\244\247\346\250\241\345\236\213api\351\205\215\347\275\256\347\244\272\344\276\213-\345\233\275\351\231\205\347\257\207.md"
create mode 100644 "docs/\344\270\255\347\272\247-\345\257\271\346\216\245one-api\346\225\231\347\250\213.md"
create mode 100644 "docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
diff --git "a/docs/\344\270\255\347\272\247-\345\244\247\346\250\241\345\236\213api\351\205\215\347\275\256\347\244\272\344\276\213-\345\233\275\344\272\247\345\244\247\346\250\241\345\236\213.md" "b/docs/\344\270\255\347\272\247-\345\244\247\346\250\241\345\236\213api\351\205\215\347\275\256\347\244\272\344\276\213-\345\233\275\344\272\247\345\244\247\346\250\241\345\236\213.md"
new file mode 100644
index 0000000..90bc014
--- /dev/null
+++ "b/docs/\344\270\255\347\272\247-\345\244\247\346\250\241\345\236\213api\351\205\215\347\275\256\347\244\272\344\276\213-\345\233\275\344\272\247\345\244\247\346\250\241\345\236\213.md"
@@ -0,0 +1,90 @@
+# 国产大模型配置实例
+
+### 混元配置项
+配置混元模型需要以下参数:
+```yaml
+secretId: "xxx"
+secretKey: "xxx"
+region: ""
+maxTokensHunyuan: 1024
+hunyuanType: 3 # 可选类型:0=高级版, 1=标准版std, 2=hunyuan-lite, 3=hunyuan-standard, 4=hunyuan-standard-256K, 5=hunyuan-pro
+hunyuanStreamModeration: true # 启用流式内容审核
+topPHunyuan: 1.0
+temperatureHunyuan: 1.0 # 控制生成内容的随机性
+```
+
+### 文心配置项
+配置文心模型时需要以下参数,这里涵盖了接口的调用以及特殊参数的设置:
+```yaml
+wenxinAccessToken: "xxx"
+wenxinApiPath: "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant"
+wenxinEmbeddingUrl: "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/embeddings/embedding-v1" # 百度的embedding接口URL
+maxTokenWenxin: 1024
+wenxinTopp: 0.7 # 控制输出文本的多样性,取值范围0.1~1.0,默认0.7
+wenxinPenaltyScore: 1.0 # 增加生成token的惩罚,以减少重复,值越大惩罚越重
+wenxinMaxOutputTokens: 100 # 模型最大输出token数,范围2~1024
+```
+
+### RWKV 模型配置(rwkv runner)
+```yaml
+rwkvApiPath: "https://" # 符合RWKV标准的API地址
+rwkvMaxTokens: 100
+rwkvTemperature: 1.1
+rwkvTopP: 0.5
+rwkvPresencePenalty: 0.5
+rwkvFrequencyPenalty: 1.1
+rwkvPenaltyDecay: 0.99
+rwkvTopK: 25
+rwkvSseType: 0
+rwkvGlobalPenalty: false
+rwkvStop:
+ - "\n\nUser"
+rwkvUserName: "User"
+rwkvAssistantName: "Assistant"
+rwkvSystemName: "System"
+rwkvPreSystem: false
+```
+
+### TYQW 模型配置
+```yaml
+tyqwApiPath: "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"
+tyqwMaxTokens: 1500
+tyqwModel: "qwen-turbo"
+tyqwApiKey: "sk-"
+tyqwWorkspace: ""
+tyqwTemperature: 0.85
+tyqwTopP: 0.9
+tyqwPresencePenalty: 0.2
+tyqwFrequencyPenalty: 0.2
+tyqwRepetitionPenalty: 1.1
+tyqwPenaltyDecay: 0.99
+tyqwTopK: 40
+tyqwSeed: 1234
+tyqwSseType: 1
+tyqwGlobalPenalty: false
+tyqwStop:
+ - "\n\nUser"
+tyqwUserName: "User"
+tyqwAssistantName: "Assistant"
+tyqwSystemName: "System"
+tyqwPreSystem: false
+tyqwEnableSearch: false
+```
+
+### GLM 模型配置
+```yaml
+glmApiPath: "https://open.bigmodel.cn/api/paas/v4/chat/completions"
+glmModel: "glm-3-turbo"
+glmApiKey: ".xxx"
+glmRequestID: ""
+glmDoSample: true
+glmTemperature: 0.95
+glmTopP: 0.9
+glmMaxTokens: 1024
+glmStop:
+ - "stop_token"
+glmTools:
+ - ""
+glmToolChoice: "auto"
+glmUserID: ""
+```
\ No newline at end of file
diff --git "a/docs/\344\270\255\347\272\247-\345\244\247\346\250\241\345\236\213api\351\205\215\347\275\256\347\244\272\344\276\213-\345\233\275\351\231\205\347\257\207.md" "b/docs/\344\270\255\347\272\247-\345\244\247\346\250\241\345\236\213api\351\205\215\347\275\256\347\244\272\344\276\213-\345\233\275\351\231\205\347\257\207.md"
new file mode 100644
index 0000000..a773693
--- /dev/null
+++ "b/docs/\344\270\255\347\272\247-\345\244\247\346\250\241\345\236\213api\351\205\215\347\275\256\347\244\272\344\276\213-\345\233\275\351\231\205\347\257\207.md"
@@ -0,0 +1,49 @@
+### 国际模型配置实例
+
+#### api2d 配置项
+```yaml
+gptModel: "gpt-3.5-turbo"
+gptApiPath: "https://openai.api2d.net/v1/chat/completions"
+gptToken: "fk207628-***********"
+maxTokenGpt: 1024
+gptModeration: false # 额外走腾讯云检查安全,不合规直接拦截. 仅api2d支持
+gptSafeMode: false
+gptSseType: 0
+```
+
+#### openai 测试配置
+```yaml
+gptModel: "gpt-3.5-turbo"
+gptApiPath: "https://api.openai.com/v1/chat/completions"
+gptToken: "sk_8*******"
+maxTokenGpt: 1024
+gptModeration: false # 额外走腾讯云检查安全,不合规直接拦截. 仅api2d支持
+gptSafeMode: false
+gptSseType: 0
+standardGptApi: true # 标准的gptApi, OpenAI 和 Groq 需要开启
+```
+
+#### Groq 测试配置
+```yaml
+gptModel: "llama3-70b-8192"
+gptApiPath: "https://api.groq.com/openai/v1/chat/completions"
+gptToken: "gsk_8*******"
+maxTokenGpt: 1024
+gptModeration: false # 额外走腾讯云检查安全,不合规直接拦截. 仅api2d支持
+gptSafeMode: false
+gptSseType: 0
+standardGptApi: true # 标准的gptApi, OpenAI 和 Groq 需要开启
+```
+
+#### One-API 测试配置(该项目也支持国内多个大模型,具体请参考one-api接入教程)
+[one-api](https://github.com/songquanpeng/one-api)
+```yaml
+gptModel: "chatglm_turbo"
+gptApiPath: "http://127.0.0.1:3000/v1/chat/completions"
+gptToken: "sk-d*****"
+maxTokenGpt: 1024
+gptModeration: false # 额外走腾讯云检查安全,不合规直接拦截. 仅api2d支持
+gptSafeMode: false
+gptSseType: 0
+standardGptApi: true # 标准的gptApi, OpenAI 和 Groq 需要开启
+```
\ No newline at end of file
diff --git "a/docs/\344\270\255\347\272\247-\345\257\271\346\216\245one-api\346\225\231\347\250\213.md" "b/docs/\344\270\255\347\272\247-\345\257\271\346\216\245one-api\346\225\231\347\250\213.md"
new file mode 100644
index 0000000..9345e4e
--- /dev/null
+++ "b/docs/\344\270\255\347\272\247-\345\257\271\346\216\245one-api\346\225\231\347\250\213.md"
@@ -0,0 +1,39 @@
+### 开始使用 One-API对接gsk-llm
+
+**步骤 1: 下载 One-API**
+- One-API 是一个轻便易用的项目,包含一个可执行文件,无需其他环境支持,且带有 Web UI。
+- 下载链接:[one-api](https://github.com/songquanpeng/one-api)
+
+**步骤 2: 运行 One-API**
+- 执行下载的 One-API 可执行文件。
+- 在浏览器中打开 `http://localhost:3000/`。
+
+**步骤 3: 登录**
+- 使用默认用户名 `root` 和密码 `123456` 登录。
+
+**步骤 4: 创建 API 渠道**
+- 在网页控制台的顶栏选择“渠道”-“添加新的渠道”。
+- 为你的模型渠道命名,并在模型栏中输入你申请的模型名称,该栏支持自动补全。
+- 输入你从模型所在平台(如腾讯云、智谱、通义等)获取的 API access token。
+- 点击“提交”以创建 API 渠道。
+
+**步骤 5: 生成令牌**
+- 点击顶栏的“令牌”并创建一个新令牌。
+- 选择要使用的模型,创建令牌后点击绿色的“复制”按钮复制生成的令牌。
+
+**步骤 6: 配置 gsk-llm**
+- 在 gsk-llm 配置文件中更新以下配置以连接到你的 one-api 平台。
+```yaml
+# One-API 测试配置
+gptModel: "chatglm_turbo" # 使用的模型名称
+gptApiPath: "http://127.0.0.1:3000/v1/chat/completions" # One-API 服务的端口号
+gptToken: "sk-dbmr0Oxxxxxxxxxxxxxxxxxxxxxxx" # 生成的密钥
+maxTokenGpt: 1024
+gptModeration: false
+gptSafeMode: false
+gptSseType: 0
+standardGptApi: true # 启用标准 GPT API
+```
+
+这样配置后,你就可以灵活地管理用量和使用的模型了。本项目的配置文件是热更新的,你不需要重启来应用配置.
+
diff --git "a/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md" "b/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
new file mode 100644
index 0000000..7deaf70
--- /dev/null
+++ "b/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
@@ -0,0 +1,98 @@
+
+# Gensokyo-LLM (gsk-llm) 初阶教程
+
+## 名词介绍
+**gsk-llm**:在本教程中,我们将 Gensokyo-LLM 缩写为 **gsk-llm**。
+
+**OneBot v11 实现端**:实现了 OneBot v11 标准的应用。在教程中使用 Gensokyo,任何采用 OneBot v11 的实现端均可成功对接使用。
+
+## 支持实现端列表
+访问 [OneBot 生态系统](https://onebot.dev/ecosystem.html) 查看支持实现端的完整列表。
+
+## 接入方法
+
+### 使用ob11反向 WebSocket 接入
+1. 直接让机器人连接到以下本程序地址的 port 上:
+ - **反向链接地址**:`ws://127.0.0.1:46233`
+ - **Port**:46233
+
+连接成功后,机器人便可收发信息。
+
+### 使用ob11 HTTP API 接入方法
+1. 运行 gsk-llm 的 exe 可执行程序。
+2. 打开 `config.yml` 文件并进行以下设置:
+ - **通用配置项**:
+ ```
+ allApi: true # 同时开启全部 API
+ useSse: true # 通过 stream 方式发送信息
+ port: 46233
+ path: "http://192.168.0.102:33800"
+ ```
+ - **配置监听地址**:确保没有端口冲突,可以保持默认。
+ - **配置 OneBot v11 的正向 HTTP API 地址**:
+ ```
+ path: "http://127.0.0.1:46233/gensokyo"
+ ```
+ - **上报消息地址**:
+ ```
+ http://192.168.0.102:33800
+ ```
+ - **API 类型选择**:
+ ```
+ apiType: 5 # 选择适合的 API 类型,文末对api类型有讲解
+ ```
+ - **API Key 设置**:填入对应平台的 API Key。
+
+3. 设置 `systemPrompt` 为需要的人设提示词。
+
+4. 根据注释完成其他必要配置。
+
+一旦配置完成,你的机器人将作为一个基本的 AI 聊天对话机器人运行。
+
+### 特别配置解释
+- **useSse: true**:API 通过 stream 方式发送信息,机器人将流式地发送信息。
+- **splitByPuntuations**: 40 #私聊截断率
+- **splitByPuntuationsGroup**: 40 #群聊截断率,仅在 SSE 时有效,100 表示每句截断。
+
+建议截断率取值范围为 30-40,以便优化信息流的连贯性。
+
+---
+
+### API apiType 类型选择
+
+在配置文件中,`apiType` 用于指定使用的 API 类型。您可以根据需要选择以下编号对应的 API 类型:
+
+- **0:混元**
+- **1:文心**
+- **2:GPT**
+- **3:RWKV**
+- **4:TYQW**
+- **5:GLm**
+
+确保您有对应平台的 API key。
+
+#### 特殊配置:API Type 2
+
+当 `apiType` 设置为 **2(GPT)** 时,本程序支持兼容包括但不限于以下项目,以及所有采用 OpenAI 格式的 API 或中转项目:
+
+- [one-api](https://github.com/songquanpeng/one-api)
+- [groq](https://console.groq.com)
+
+对于完全标准的 OpenAI 格式 API,调整配置如下:
+- `standardGptApi: true` 表示启用原生的 OpenAI 格式
+
+对于特殊的 OpenAI API 格式(api2d),则使用:
+- `standardGptApi: false`
+
+API2d 提供了一些额外的配置,如安全模式和腾讯云审核等:
+- [api-2d](https://api2d.com/)
+
+#### 网络代理设置
+
+可以通过设置 `proxy: "http://192.168.0.113:7890"` 来使本程序通过网络代理。
+
+#### 使用须知
+
+请注意,部分平台如 QQ 开放平台和微信开放平台要求模型需要通过算法备案。请不要在这些平台使用未备案的模型。由此产生的服务号或机器人被下线的问题,本项目已尽到提醒的责任,概不负责。
+
+---
\ No newline at end of file
diff --git a/readme.md b/readme.md
index df0318c..b54daad 100644
--- a/readme.md
+++ b/readme.md
@@ -10,6 +10,16 @@
_✨ 适用于Gensokyo以及Onebotv11的大模型一键端 ✨_
+---
+## 文档&教程
+
+[初阶-简单接入机器人](/docs/初阶-简单接入机器人.md):简单将机器人接入QQ等6大平台
+
+[中级-对接one-api教程](/docs/中级-对接one-api教程.md):可视化管理大模型api
+
+[中级-大模型api配置示例-国产大模型](/docs/中级-大模型api配置示例-国产大模型.md)
+
+[中级-大模型api配置示例-国际篇](/docs/中级-大模型api配置示例-国际篇.md)
---
## 特性
@@ -111,12 +121,6 @@ AhoCorasick算法实现的超高效文本IN-Out替换规则,可大量替换n
---
-## 使用教程
-
-施工中...(部署非常简单,有一定onebotv11机器人部署经验者可参考config.yml注释直接部署出来.)
-
----
-
# API接口调用说明
本文档提供了关于API接口的调用方法和配置文件的格式说明,帮助用户正确使用和配置。
@@ -170,7 +174,7 @@ GET /gensokyo?prompt=example&api=conversation_ernie
支持端点列表:(需配置:allApi : true)
```golang
-http.HandleFunc("/conversation_gpt", app.ChatHandlerChatgpt)
+ http.HandleFunc("/conversation_gpt", app.ChatHandlerChatgpt)
http.HandleFunc("/conversation_hunyuan", app.ChatHandlerHunyuan)
http.HandleFunc("/conversation_ernie", app.ChatHandlerErnie)
http.HandleFunc("/conversation_rwkv", app.ChatHandlerRwkv)
From 8cc5b3d73c0ec10f60de74f9a878b485d113d2fc Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Sun, 19 May 2024 23:16:39 +0800
Subject: [PATCH 09/12] Update readme.md (#121)
---
readme.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index b54daad..5db889d 100644
--- a/readme.md
+++ b/readme.md
@@ -20,6 +20,7 @@ _✨ 适用于Gensokyo以及Onebotv11的大模型一键端 ✨_
[中级-大模型api配置示例-国产大模型](/docs/中级-大模型api配置示例-国产大模型.md)
[中级-大模型api配置示例-国际篇](/docs/中级-大模型api配置示例-国际篇.md)
+
---
## 特性
@@ -462,4 +463,4 @@ GetAIPromptkeyboardPath可以是自身地址,可以带有prompt参数
3. **Inklewriter**
- **项目主页**,[Ink on GitHub](https://github.com/inkle/ink).
- - 它是一个允许用户创建交互式故事的网页平台。它设计了**ink**语言,它是一个开源项目,用于编写交互式叙述和游戏。
\ No newline at end of file
+ - 它是一个允许用户创建交互式故事的网页平台。它设计了**ink**语言,它是一个开源项目,用于编写交互式叙述和游戏。
From f567a821b27787a4963ef5416a37f07eadc1ebf7 Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Sun, 19 May 2024 23:21:41 +0800
Subject: [PATCH 10/12] Beta123 (#122)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
* beta118
* beta119
* beta120
* beta121
* beta122
* beta123
---
...\245\345\205\245\346\234\272\345\231\250\344\272\272.md" | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git "a/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md" "b/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
index 7deaf70..783d281 100644
--- "a/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
+++ "b/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
@@ -29,13 +29,13 @@
path: "http://192.168.0.102:33800"
```
- **配置监听地址**:确保没有端口冲突,可以保持默认。
- - **配置 OneBot v11 的正向 HTTP API 地址**:
+ - **上报消息地址**:
```
path: "http://127.0.0.1:46233/gensokyo"
```
- - **上报消息地址**:
+ - **配置 OneBot v11 的正向 HTTP API 地址**:
```
- http://192.168.0.102:33800
+ http://192.168.0.102:33800(该地址是onebotv11实现端的所在ip地址:http监听端口)
```
- **API 类型选择**:
```
From ea82b87f812fe3ed0af5ddcb09a2d74c24bb312f Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Sun, 19 May 2024 23:24:39 +0800
Subject: [PATCH 11/12] Beta124 (#123)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
* beta118
* beta119
* beta120
* beta121
* beta122
* beta123
* beta124
---
...16\245\345\205\245\346\234\272\345\231\250\344\272\272.md" | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git "a/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md" "b/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
index 783d281..2ddd001 100644
--- "a/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
+++ "b/docs/\345\210\235\351\230\266-\347\256\200\345\215\225\346\216\245\345\205\245\346\234\272\345\231\250\344\272\272.md"
@@ -29,11 +29,11 @@
path: "http://192.168.0.102:33800"
```
- **配置监听地址**:确保没有端口冲突,可以保持默认。
- - **上报消息地址**:
+ - **上报消息地址**(在onebotv11实现端配置,指向gsk-llm):
```
path: "http://127.0.0.1:46233/gensokyo"
```
- - **配置 OneBot v11 的正向 HTTP API 地址**:
+ - **配置 OneBot v11 的正向 HTTP API 地址**(在gsk-llm配置,指向onebotv11实现端):
```
http://192.168.0.102:33800(该地址是onebotv11实现端的所在ip地址:http监听端口)
```
From 5414683ff14e47721afa685b20d89aa3139ccc7e Mon Sep 17 00:00:00 2001
From: SanaeFox <36219542+Hoshinonyaruko@users.noreply.github.com>
Date: Mon, 20 May 2024 00:50:41 +0800
Subject: [PATCH 12/12] Beta125 (#124)
* beta1
* beta2
* beta3
* beta4
* beta5
* beta6
* beta7
* beta8
* beta9
* beta10
* beta11
* beta12
* beta13
* beta14
* beta15
* beta16
* beta16
* beta19
* beta20
* beta21
* beta22
* beta23
* beta24
* beta25
* beta27
* beta28
* beta29
* beta30
* beta31
* beta33
* beta34
* beta35
* beta36
* beta37
* beta38
* beta39
* beta40
* beta41
* beta42
* beta43
* beta44
* beta45
* beta45
* beta46
* beat48
* beta49
* beta50
* beta51
* beta52
* beta53
* beta54
* beta55
* beta57
* beta58
* beta59
* beta61
* beta62
* beta63
* beta63
* beta64
* beta65
* beta66
* beta67
* beta70
* beta71
* beta72
* beta72
* beta74
* beta75
* beta76
* beta77
* beta78
* beta79
* beta80
* beta81
* beta82
* beta83
* beta85
* beta86
* beta87
* beta88
* beta89
* beta90
* beta91
* beta92
* beta93
* beta94
* beta94
* beta96
* beta97
* beta98
* beta99
* beta100
* beta101
* beta102
* beta104
* beta105
* beta106
* beta107
* beta108
* beta109
* beta110
* beta111
* beta112
* beta113
* beta115
* beta116
* beta117
* beta118
* beta119
* beta120
* beta121
* beta122
* beta123
* beta124
* beta125
---
applogic/chatglm.go | 2 +-
applogic/gensokyo.go | 2 +-
applogic/hunyuan.go | 46 ++++++++++++++++++++++++++++++++------------
config/config.go | 32 ++++++++++++++++++++++++++++++
4 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/applogic/chatglm.go b/applogic/chatglm.go
index 14b4aac..382f57a 100644
--- a/applogic/chatglm.go
+++ b/applogic/chatglm.go
@@ -59,7 +59,7 @@ func (app *App) ChatHandlerGlm(w http.ResponseWriter, r *http.Request) {
// 读取URL参数 "userid"
useridstr := r.URL.Query().Get("userid")
- if promptstr != "" {
+ if useridstr != "" {
// prompt 参数存在,可以根据需要进一步处理或记录
fmtf.Printf("Received userid parameter: %s\n", useridstr)
}
diff --git a/applogic/gensokyo.go b/applogic/gensokyo.go
index eb5c435..9c320ed 100644
--- a/applogic/gensokyo.go
+++ b/applogic/gensokyo.go
@@ -558,7 +558,7 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
}
// glm会根据userid参数来封禁用户
- if config.GetApiType() == 5 {
+ if config.GetApiType() == 5 || basePath == "/conversation_glm" {
urlParams.Add("userid", strconv.FormatInt(message.UserID, 10))
}
diff --git a/applogic/hunyuan.go b/applogic/hunyuan.go
index 2efd13a..a8d96ae 100644
--- a/applogic/hunyuan.go
+++ b/applogic/hunyuan.go
@@ -7,6 +7,7 @@ import (
"strings"
"sync"
+ "github.com/google/uuid"
"github.com/hoshinonyaruko/gensokyo-llm/config"
"github.com/hoshinonyaruko/gensokyo-llm/fmtf"
"github.com/hoshinonyaruko/gensokyo-llm/hunyuan"
@@ -15,8 +16,12 @@ import (
"github.com/hoshinonyaruko/gensokyo-llm/utils"
)
-var messageBuilder strings.Builder
-var groupUserMessages sync.Map
+var (
+ messageBuilder strings.Builder
+ groupUserMessages sync.Map
+ mutexhunyuan sync.Mutex
+ lastCompleteResponseshunyuan sync.Map // 存储每个conversationId的完整累积信息
+)
func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
@@ -655,10 +660,16 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
return
}
- var responseTextBuilder strings.Builder
- var totalUsage structs.UsageInfo
+ // 生成一个随机的UUID
+ randomUUID, err := uuid.NewRandom()
+ if err != nil {
+ http.Error(w, "Failed to generate UUID", http.StatusInternalServerError)
+ return
+ }
+ var totalUsage structs.UsageInfo // 有并发问题
for event := range response.BaseSSEResponse.Events {
+
if event.Err != nil {
fmtf.Fprintf(w, "data: %s\n\n", fmtf.Sprintf("接收事件时发生错误: %v", event.Err))
flusher.Flush()
@@ -673,13 +684,24 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
continue
}
+ // 在修改共享资源之前锁定Mutex
+ mutexhunyuan.Lock()
+ // 由于同一个上下文中 msg.ConversationID是相同的,而我们要区分更细粒度 所以添加UUID openai的api则设计了更细粒度的stramid,可以直接使用
+ conversationId := msg.ConversationID + randomUUID.String()
+ // 读取完整信息
+ completeResponse, _ := lastCompleteResponseshunyuan.LoadOrStore(conversationId, "")
+ // 提取出本次请求的响应
responseText, usageInfo := utils.ExtractEventDetails(eventData)
- responseTextBuilder.WriteString(responseText)
+ // 更新存储的完整累积信息
+ updatedCompleteResponse := completeResponse.(string) + responseText
+ lastCompleteResponseshunyuan.Store(conversationId, updatedCompleteResponse)
+ // 完成修改后解锁Mutex
+ mutexhunyuan.Unlock()
+
totalUsage.PromptTokens += usageInfo.PromptTokens
totalUsage.CompletionTokens += usageInfo.CompletionTokens
- // 发送当前事件的响应数据,但不包含assistantMessageID
- //fmtf.Printf("发送当前事件的响应数据,但不包含assistantMessageID\n")
+ // 构建并发送当前事件的响应数据
tempResponseMap := map[string]interface{}{
"response": responseText,
"conversationId": msg.ConversationID,
@@ -693,12 +715,13 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
}
// 处理完所有事件后,生成并发送包含assistantMessageID的最终响应
- responseText := responseTextBuilder.String()
- fmtf.Printf("处理完所有事件后,生成并发送包含assistantMessageID的最终响应:%v\n", responseText)
+ conversationId := msg.ConversationID + randomUUID.String()
+ completeResponse, _ := lastCompleteResponseshunyuan.LoadOrStore(conversationId, "")
+ fmtf.Printf("处理完所有事件后,生成并发送包含assistantMessageID的最终响应:%v\n", completeResponse.(string))
assistantMessageID, err := app.addMessage(structs.Message{
ConversationID: msg.ConversationID,
ParentMessageID: userMessageID,
- Text: responseText,
+ Text: completeResponse.(string),
Role: "assistant",
})
@@ -708,7 +731,7 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
}
finalResponseMap := map[string]interface{}{
- "response": responseText,
+ "response": completeResponse.(string),
"conversationId": msg.ConversationID,
"messageId": assistantMessageID,
"details": map[string]interface{}{
@@ -720,7 +743,6 @@ func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) {
flusher.Flush()
}
}
-
}
func truncateHistoryHunYuan(history []structs.Message, prompt string, promptstr string) []structs.Message {
diff --git a/config/config.go b/config/config.go
index 5fda48c..cb2f2f9 100644
--- a/config/config.go
+++ b/config/config.go
@@ -450,6 +450,10 @@ func getGptTokenInternal(options ...string) string {
return getGptTokenInternal() // 递归调用内部函数,不传递任何参数
}
+ if gptToken == "" {
+ return getGptTokenInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return gptToken
}
@@ -484,6 +488,10 @@ func getMaxTokenGptInternal(options ...string) int {
return getMaxTokenGptInternal() // 递归调用内部函数,不传递任何参数
}
+ if maxTokenGpt == 0 {
+ return getMaxTokenGptInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return maxTokenGpt
}
@@ -2486,6 +2494,10 @@ func getGlmApiPathInternal(options ...string) string {
return getGlmApiPathInternal() // 递归调用内部函数,不传递任何参数
}
+ if apiPath == "" {
+ return getGlmApiPathInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return apiPath
}
@@ -2520,6 +2532,10 @@ func getGlmModelInternal(options ...string) string {
return getGlmModelInternal() // 递归调用内部函数,不传递任何参数
}
+ if model == "" {
+ return getGlmModelInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return model
}
@@ -2554,6 +2570,10 @@ func getGlmApiKeyInternal(options ...string) string {
return getGlmApiKeyInternal() // 递归调用内部函数,不传递任何参数
}
+ if apiKey == "" {
+ return getGlmApiKeyInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return apiKey
}
@@ -2588,6 +2608,10 @@ func getGlmMaxTokensInternal(options ...string) int {
return getGlmMaxTokensInternal() // 递归调用内部函数,不传递任何参数
}
+ if maxTokens == 0 {
+ return getGlmMaxTokensInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return maxTokens
}
@@ -2622,6 +2646,10 @@ func getGlmTemperatureInternal(options ...string) float64 {
return getGlmTemperatureInternal() // 递归调用内部函数,不传递任何参数
}
+ if temperature == 0 {
+ return getGlmTemperatureInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return temperature
}
@@ -2696,6 +2724,10 @@ func getGlmTopPInternal(options ...string) float64 {
return getGlmTopPInternal() // 递归调用内部函数,不传递任何参数
}
+ if topP == 0 {
+ return getGlmTopPInternal() // 递归调用内部函数,不传递任何参数
+ }
+
return topP
}