fix: enforce Rule 1 JSON wrappers across 80+ files, fix 6 bugs

- Replace all encoding/json direct calls with common.Marshal/Unmarshal/DecodeJson per Rule 1
- Fix Dify nil pointer dereference on remote image upload (relay-dify.go)
- Fix Claude relay file content type detection for text/* and PDF (relay-claude.go)
- Fix unsafe type assertions in Claude relay and Vertex GetModelRegion
- Fix StreamScanner unconditionally resetting pre-existing StreamStatus
- Add inferMimeTypeFromFilename() for proper MIME type handling in DTO
- Fix Mac build script hardcoded DMG version (now reads from tauri.conf.json)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 12:39:02 +08:00
co-authored by Claude Opus 4.6
parent 16410270a1
commit f43aa269d6
82 changed files with 340 additions and 324 deletions
+2 -1
View File
@@ -12,7 +12,8 @@ CANONICAL_OUTPUT_DIR="${DESKTOP_DIR}/build-artifacts/macos-arm64"
APP_BUNDLE_NAME="HeiCode.app"
APP_BUNDLE_ID="com.heicode.desktop"
DMG_VOLUME_NAME="Heicode"
DEFAULT_DMG_BASENAME="Heicode_0.1.0_aarch64.dmg"
APP_VERSION="$(bun -e "console.log(require('${DESKTOP_DIR}/src-tauri/tauri.conf.json').version)" 2>/dev/null || echo "0.0.0")"
DEFAULT_DMG_BASENAME="Heicode_${APP_VERSION}_aarch64.dmg"
usage() {
cat <<'EOF'
+5 -6
View File
@@ -2,7 +2,6 @@ package common
import (
"encoding/base64"
"encoding/json"
"net/url"
"regexp"
"strconv"
@@ -35,7 +34,7 @@ func GetRandomString(length int) string {
}
func MapToJsonStr(m map[string]interface{}) string {
bytes, err := json.Marshal(m)
bytes, err := Marshal(m)
if err != nil {
return ""
}
@@ -53,7 +52,7 @@ func StrToMap(str string) (map[string]interface{}, error) {
func StrToJsonArray(str string) ([]interface{}, error) {
var js []interface{}
err := json.Unmarshal([]byte(str), &js)
err := Unmarshal([]byte(str), &js)
if err != nil {
return nil, err
}
@@ -62,12 +61,12 @@ func StrToJsonArray(str string) ([]interface{}, error) {
func IsJsonArray(str string) bool {
var js []interface{}
return json.Unmarshal([]byte(str), &js) == nil
return Unmarshal([]byte(str), &js) == nil
}
func IsJsonObject(str string) bool {
var js map[string]interface{}
return json.Unmarshal([]byte(str), &js) == nil
return Unmarshal([]byte(str), &js) == nil
}
func String2Int(str string) int {
@@ -102,7 +101,7 @@ func GetJsonString(data any) string {
if data == nil {
return ""
}
b, _ := json.Marshal(data)
b, _ := Marshal(data)
return string(b)
}
+2 -3
View File
@@ -1,7 +1,6 @@
package common
import (
"encoding/json"
"sync"
)
@@ -15,7 +14,7 @@ var topupGroupRatioMutex sync.RWMutex
func TopupGroupRatio2JSONString() string {
topupGroupRatioMutex.RLock()
defer topupGroupRatioMutex.RUnlock()
jsonBytes, err := json.Marshal(topupGroupRatio)
jsonBytes, err := Marshal(topupGroupRatio)
if err != nil {
SysError("error marshalling topup group ratio: " + err.Error())
}
@@ -26,7 +25,7 @@ func UpdateTopupGroupRatioByJSONString(jsonStr string) error {
topupGroupRatioMutex.Lock()
defer topupGroupRatioMutex.Unlock()
topupGroupRatio = make(map[string]float64)
return json.Unmarshal([]byte(jsonStr), &topupGroupRatio)
return Unmarshal([]byte(jsonStr), &topupGroupRatio)
}
func GetTopupGroupRatio(name string) float64 {
+2 -3
View File
@@ -3,7 +3,6 @@ package common
import (
crand "crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
"html/template"
"io"
@@ -290,12 +289,12 @@ func GetPointer[T any](v T) *T {
func Any2Type[T any](data any) (T, error) {
var zero T
bytes, err := json.Marshal(data)
bytes, err := Marshal(data)
if err != nil {
return zero, err
}
var res T
err = json.Unmarshal(bytes, &res)
err = Unmarshal(bytes, &res)
if err != nil {
return zero, err
}
+11 -12
View File
@@ -1,7 +1,6 @@
package controller
import (
"encoding/json"
"errors"
"fmt"
"io"
@@ -174,7 +173,7 @@ func updateChannelCloseAIBalance(channel *model.Channel) (float64, error) {
return 0, err
}
response := OpenAICreditGrants{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -189,7 +188,7 @@ func updateChannelOpenAISBBalance(channel *model.Channel) (float64, error) {
return 0, err
}
response := OpenAISBUsageResponse{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -213,7 +212,7 @@ func updateChannelAIProxyBalance(channel *model.Channel) (float64, error) {
return 0, err
}
response := AIProxyUserOverviewResponse{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -232,7 +231,7 @@ func updateChannelAPI2GPTBalance(channel *model.Channel) (float64, error) {
return 0, err
}
response := API2GPTUsageResponse{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -247,7 +246,7 @@ func updateChannelSiliconFlowBalance(channel *model.Channel) (float64, error) {
return 0, err
}
response := SiliconFlowUsageResponse{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -269,7 +268,7 @@ func updateChannelDeepSeekBalance(channel *model.Channel) (float64, error) {
return 0, err
}
response := DeepSeekUsageResponse{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -298,7 +297,7 @@ func updateChannelAIGC2DBalance(channel *model.Channel) (float64, error) {
return 0, err
}
response := APGC2DGPTUsageResponse{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -313,7 +312,7 @@ func updateChannelOpenRouterBalance(channel *model.Channel) (float64, error) {
return 0, err
}
response := OpenRouterCreditResponse{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -343,7 +342,7 @@ func updateChannelMoonshotBalance(channel *model.Channel) (float64, error) {
}
response := MoonshotBalanceResponse{}
err = json.Unmarshal(body, &response)
err = common.Unmarshal(body, &response)
if err != nil {
return 0, err
}
@@ -396,7 +395,7 @@ func updateChannelBalance(channel *model.Channel) (float64, error) {
return 0, err
}
subscription := OpenAISubscriptionResponse{}
err = json.Unmarshal(body, &subscription)
err = common.Unmarshal(body, &subscription)
if err != nil {
return 0, err
}
@@ -412,7 +411,7 @@ func updateChannelBalance(channel *model.Channel) (float64, error) {
return 0, err
}
usage := OpenAIUsageResponse{}
err = json.Unmarshal(body, &usage)
err = common.Unmarshal(body, &usage)
if err != nil {
return 0, err
}
+6 -6
View File
@@ -547,7 +547,7 @@ func getVertexArrayKeys(keys string) ([]string, error) {
case string:
keyStr = strings.TrimSpace(v)
default:
bytes, err := json.Marshal(v)
bytes, err := common.Marshal(v)
if err != nil {
return nil, fmt.Errorf("Vertex AI key JSON 编码失败: %w", err)
}
@@ -886,7 +886,7 @@ func UpdateChannel(c *gin.Context) {
if strings.HasPrefix(strings.TrimSpace(originChannel.Key), "[") {
// JSON数组格式
var arr []json.RawMessage
if err := json.Unmarshal([]byte(strings.TrimSpace(originChannel.Key)), &arr); err == nil {
if err := common.Unmarshal([]byte(strings.TrimSpace(originChannel.Key)), &arr); err == nil {
existingKeys = make([]string, len(arr))
for i, v := range arr {
existingKeys[i] = string(v)
@@ -1071,7 +1071,7 @@ func FetchModels(c *gin.Context) {
} `json:"data"`
}
if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
if err := common.DecodeJson(response.Body, &result); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": err.Error(),
@@ -1817,7 +1817,7 @@ func OllamaPullModelStream(c *gin.Context) {
// 创建进度回调函数
progressCallback := func(progress ollama.OllamaPullResponse) {
data, _ := json.Marshal(progress)
data, _ := common.Marshal(progress)
fmt.Fprintf(c.Writer, "data: %s\n\n", string(data))
c.Writer.Flush()
}
@@ -1826,12 +1826,12 @@ func OllamaPullModelStream(c *gin.Context) {
err = ollama.PullOllamaModelStream(baseURL, key, req.ModelName, progressCallback)
if err != nil {
errorData, _ := json.Marshal(gin.H{
errorData, _ := common.Marshal(gin.H{
"error": err.Error(),
})
fmt.Fprintf(c.Writer, "data: %s\n\n", string(errorData))
} else {
successData, _ := json.Marshal(gin.H{
successData, _ := common.Marshal(gin.H{
"message": fmt.Sprintf("Model %s pulled successfully", req.ModelName),
})
fmt.Fprintf(c.Writer, "data: %s\n\n", string(successData))
+5 -6
View File
@@ -3,7 +3,6 @@
package controller
import (
"encoding/json"
"net/http"
"github.com/heicode/manager/common"
@@ -30,11 +29,11 @@ func MigrateConsoleSetting(c *gin.Context) {
// 处理 APIInfo
if v := valMap["ApiInfo"]; v != "" {
var arr []map[string]interface{}
if err := json.Unmarshal([]byte(v), &arr); err == nil {
if err := common.Unmarshal([]byte(v), &arr); err == nil {
if len(arr) > 50 {
arr = arr[:50]
}
bytes, _ := json.Marshal(arr)
bytes, _ := common.Marshal(arr)
model.UpdateOption("console_setting.api_info", string(bytes))
}
model.UpdateOption("ApiInfo", "")
@@ -47,7 +46,7 @@ func MigrateConsoleSetting(c *gin.Context) {
// FAQ 转换
if v := valMap["FAQ"]; v != "" {
var arr []map[string]interface{}
if err := json.Unmarshal([]byte(v), &arr); err == nil {
if err := common.Unmarshal([]byte(v), &arr); err == nil {
out := []map[string]interface{}{}
for _, item := range arr {
q, _ := item["question"].(string)
@@ -65,7 +64,7 @@ func MigrateConsoleSetting(c *gin.Context) {
if len(out) > 50 {
out = out[:50]
}
bytes, _ := json.Marshal(out)
bytes, _ := common.Marshal(out)
model.UpdateOption("console_setting.faq", string(bytes))
}
model.UpdateOption("FAQ", "")
@@ -84,7 +83,7 @@ func MigrateConsoleSetting(c *gin.Context) {
"description": "",
},
}
bytes, _ := json.Marshal(groups)
bytes, _ := common.Marshal(groups)
model.UpdateOption("console_setting.uptime_kuma_groups", string(bytes))
}
// 清空旧键内容
+1 -2
View File
@@ -2,7 +2,6 @@ package controller
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"
@@ -66,7 +65,7 @@ func TestIoNetConnection(c *gin.Context) {
return
}
if len(bytes.TrimSpace(rawBody)) > 0 {
if err := json.Unmarshal(rawBody, &req); err != nil {
if err := common.Unmarshal(rawBody, &req); err != nil {
common.ApiErrorMsg(c, "invalid request payload")
return
}
+2 -3
View File
@@ -1,7 +1,6 @@
package controller
import (
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -61,7 +60,7 @@ func getDiscordUserInfoByCode(code string) (*DiscordUser, error) {
}
defer res.Body.Close()
var discordResponse DiscordResponse
err = json.NewDecoder(res.Body).Decode(&discordResponse)
err = common.DecodeJson(res.Body, &discordResponse)
if err != nil {
return nil, err
}
@@ -88,7 +87,7 @@ func getDiscordUserInfoByCode(code string) (*DiscordUser, error) {
}
var discordUser DiscordUser
err = json.NewDecoder(res2.Body).Decode(&discordUser)
err = common.DecodeJson(res2.Body, &discordUser)
if err != nil {
return nil, err
}
+3 -4
View File
@@ -2,7 +2,6 @@ package controller
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -33,7 +32,7 @@ func getGitHubUserInfoByCode(code string) (*GitHubUser, error) {
return nil, errors.New("无效的参数")
}
values := map[string]string{"client_id": common.GitHubClientId, "client_secret": common.GitHubClientSecret, "code": code}
jsonData, err := json.Marshal(values)
jsonData, err := common.Marshal(values)
if err != nil {
return nil, err
}
@@ -53,7 +52,7 @@ func getGitHubUserInfoByCode(code string) (*GitHubUser, error) {
}
defer res.Body.Close()
var oAuthResponse GitHubOAuthResponse
err = json.NewDecoder(res.Body).Decode(&oAuthResponse)
err = common.DecodeJson(res.Body, &oAuthResponse)
if err != nil {
return nil, err
}
@@ -69,7 +68,7 @@ func getGitHubUserInfoByCode(code string) (*GitHubUser, error) {
}
defer res2.Body.Close()
var githubUser GitHubUser
err = json.NewDecoder(res2.Body).Decode(&githubUser)
err = common.DecodeJson(res2.Body, &githubUser)
if err != nil {
return nil, err
}
+2 -3
View File
@@ -3,7 +3,6 @@ package controller
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
@@ -134,7 +133,7 @@ func fetchAgnetMe(baseURL, accessToken string) (agnetMeEnvelope, int, error) {
if err != nil {
return out, res.StatusCode, err
}
if err := json.Unmarshal(body, &out); err != nil {
if err := common.Unmarshal(body, &out); err != nil {
return out, res.StatusCode, fmt.Errorf("invalid response from Agnet /me: %w", err)
}
return out, res.StatusCode, nil
@@ -158,7 +157,7 @@ func fetchAgnetRefresh(baseURL, refreshToken string) (access string, refresh str
return "", "", err
}
var env agnetRefreshEnvelope
if err := json.Unmarshal(body, &env); err != nil {
if err := common.Unmarshal(body, &env); err != nil {
return "", "", fmt.Errorf("invalid response from Agnet /refresh: %w", err)
}
if !env.Success || env.Data.Token == "" {
+2 -3
View File
@@ -2,7 +2,6 @@ package controller
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -120,7 +119,7 @@ func getLinuxdoUserInfoByCode(code string, c *gin.Context) (*LinuxdoUser, error)
AccessToken string `json:"access_token"`
Message string `json:"message"`
}
if err := json.NewDecoder(res.Body).Decode(&tokenRes); err != nil {
if err := common.DecodeJson(res.Body, &tokenRes); err != nil {
return nil, err
}
@@ -144,7 +143,7 @@ func getLinuxdoUserInfoByCode(code string, c *gin.Context) (*LinuxdoUser, error)
defer res2.Body.Close()
var linuxdoUser LinuxdoUser
if err := json.NewDecoder(res2.Body).Decode(&linuxdoUser); err != nil {
if err := common.DecodeJson(res2.Body, &linuxdoUser); err != nil {
return nil, err
}
+6 -7
View File
@@ -3,7 +3,6 @@ package controller
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
@@ -79,7 +78,7 @@ func UpdateMidjourneyTaskBulk() {
}
requestUrl := fmt.Sprintf("%s/mj/task/list-by-condition", *midjourneyChannel.BaseURL)
body, _ := json.Marshal(map[string]any{
body, _ := common.Marshal(map[string]any{
"ids": taskIds,
})
req, err := http.NewRequest("POST", requestUrl, bytes.NewBuffer(body))
@@ -109,7 +108,7 @@ func UpdateMidjourneyTaskBulk() {
continue
}
var responseItems []dto.MidjourneyDto
err = json.Unmarshal(responseBody, &responseItems)
err = common.Unmarshal(responseBody, &responseItems)
if err != nil {
logger.LogError(ctx, fmt.Sprintf("Get Mjp Task parse body error2: %v, body: %s", err, string(responseBody)))
continue
@@ -142,11 +141,11 @@ func UpdateMidjourneyTaskBulk() {
task.Status = responseItem.Status
task.FailReason = responseItem.FailReason
if responseItem.Properties != nil {
propertiesStr, _ := json.Marshal(responseItem.Properties)
propertiesStr, _ := common.Marshal(responseItem.Properties)
task.Properties = string(propertiesStr)
}
if responseItem.Buttons != nil {
buttonStr, _ := json.Marshal(responseItem.Buttons)
buttonStr, _ := common.Marshal(responseItem.Buttons)
task.Buttons = string(buttonStr)
}
// 映射 VideoUrl
@@ -154,7 +153,7 @@ func UpdateMidjourneyTaskBulk() {
// 映射 VideoUrls - 将数组序列化为 JSON 字符串
if responseItem.VideoUrls != nil && len(responseItem.VideoUrls) > 0 {
videoUrlsStr, err := json.Marshal(responseItem.VideoUrls)
videoUrlsStr, err := common.Marshal(responseItem.VideoUrls)
if err != nil {
logger.LogError(ctx, fmt.Sprintf("序列化 VideoUrls 失败: %v", err))
task.VideoUrls = "[]" // 失败时设置为空数组
@@ -242,7 +241,7 @@ func checkMjTaskNeedUpdate(oldTask *model.Midjourney, newTask dto.MidjourneyDto)
}
// 检查 VideoUrls 是否需要更新
if newTask.VideoUrls != nil && len(newTask.VideoUrls) > 0 {
newVideoUrlsStr, _ := json.Marshal(newTask.VideoUrls)
newVideoUrlsStr, _ := common.Marshal(newTask.VideoUrls)
if oldTask.VideoUrls != string(newVideoUrlsStr) {
return true
}
+2 -3
View File
@@ -1,7 +1,6 @@
package controller
import (
"encoding/json"
"sort"
"strconv"
"strings"
@@ -192,7 +191,7 @@ func enrichModels(models []*model.Model) {
mm := models[idx]
if mm.Endpoints == "" {
eps := model.GetModelSupportEndpointTypes(mm.ModelName)
if b, err := json.Marshal(eps); err == nil {
if b, err := common.Marshal(eps); err == nil {
mm.Endpoints = string(b)
}
}
@@ -282,7 +281,7 @@ func enrichModels(models []*model.Model) {
for et := range es {
eps = append(eps, et)
}
if b, err := json.Marshal(eps); err == nil {
if b, err := common.Marshal(eps); err == nil {
mm.Endpoints = string(b)
}
}
+4 -4
View File
@@ -180,10 +180,10 @@ func fetchJSON[T any](ctx context.Context, url string, out *upstreamEnvelope[T])
cacheMutex.Unlock()
// Try decode as envelope first
if err := json.Unmarshal(buf, out); err != nil {
if err := common.Unmarshal(buf, out); err != nil {
// Try decode as pure array
var arr []T
if err2 := json.Unmarshal(buf, &arr); err2 != nil {
if err2 := common.Unmarshal(buf, &arr); err2 != nil {
lastErr = err
return
}
@@ -205,9 +205,9 @@ func fetchJSON[T any](ctx context.Context, url string, out *upstreamEnvelope[T])
lastErr = errors.New("cache miss for 304 response")
return
}
if err := json.Unmarshal(buf, out); err != nil {
if err := common.Unmarshal(buf, out); err != nil {
var arr []T
if err2 := json.Unmarshal(buf, &arr); err2 != nil {
if err2 := common.Unmarshal(buf, &arr); err2 != nil {
lastErr = err
return
}
+2 -3
View File
@@ -1,7 +1,6 @@
package controller
import (
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -63,7 +62,7 @@ func getOidcUserInfoByCode(code string) (*OidcUser, error) {
}
defer res.Body.Close()
var oidcResponse OidcResponse
err = json.NewDecoder(res.Body).Decode(&oidcResponse)
err = common.DecodeJson(res.Body, &oidcResponse)
if err != nil {
return nil, err
}
@@ -90,7 +89,7 @@ func getOidcUserInfoByCode(code string) (*OidcUser, error) {
}
var oidcUser OidcUser
err = json.NewDecoder(res2.Body).Decode(&oidcUser)
err = common.DecodeJson(res2.Body, &oidcUser)
if err != nil {
return nil, err
}
+3 -4
View File
@@ -2,7 +2,6 @@ package controller
import (
"context"
"encoding/json"
"fmt"
"io"
"time"
@@ -153,7 +152,7 @@ func updateVideoSingleTask(ctx context.Context, adaptor channel.TaskAdaptor, cha
if taskResult.TotalTokens > 0 {
// 获取模型名称
var taskData map[string]interface{}
if err := json.Unmarshal(task.Data, &taskData); err == nil {
if err := common.Unmarshal(task.Data, &taskData); err == nil {
if modelName, ok := taskData["model"].(string); ok && modelName != "" {
// 获取模型价格和倍率
modelRatio, hasRatioSetting, _ := ratio_setting.GetModelRatio(modelName)
@@ -280,7 +279,7 @@ func updateVideoSingleTask(ctx context.Context, adaptor channel.TaskAdaptor, cha
func redactVideoResponseBody(body []byte) []byte {
var m map[string]any
if err := json.Unmarshal(body, &m); err != nil {
if err := common.Unmarshal(body, &m); err != nil {
return body
}
resp, _ := m["response"].(map[string]any)
@@ -297,7 +296,7 @@ func redactVideoResponseBody(body []byte) []byte {
}
}
}
b, err := json.Marshal(m)
b, err := common.Marshal(m)
if err != nil {
return body
}
+3 -4
View File
@@ -6,7 +6,6 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/heicode/manager/common"
@@ -76,7 +75,7 @@ func (*CreemAdaptor) RequestPay(c *gin.Context, req *CreemPayRequest) {
// 解析产品列表
var products []CreemProduct
err := json.Unmarshal([]byte(setting.CreemProducts), &products)
err := common.Unmarshal([]byte(setting.CreemProducts), &products)
if err != nil {
logger.LogError(c.Request.Context(), fmt.Sprintf("Creem 产品配置解析失败 user_id=%d error=%q", c.GetInt("id"), err.Error()))
c.JSON(http.StatusOK, gin.H{"message": "error", "data": "产品配置错误"})
@@ -402,7 +401,7 @@ func genCreemLink(ctx context.Context, referenceId string, product *CreemProduct
}
// 序列化请求数据
jsonData, err := json.Marshal(requestData)
jsonData, err := common.Marshal(requestData)
if err != nil {
return "", fmt.Errorf("序列化请求数据失败: %v", err)
}
@@ -443,7 +442,7 @@ func genCreemLink(ctx context.Context, referenceId string, product *CreemProduct
}
// 解析响应
var checkoutResp CreemCheckoutResponse
err = json.Unmarshal(body, &checkoutResp)
err = common.Unmarshal(body, &checkoutResp)
if err != nil {
return "", fmt.Errorf("解析响应失败: %v", err)
}
+2 -2
View File
@@ -2,13 +2,13 @@ package controller
import (
"context"
"encoding/json"
"errors"
"net/http"
"strconv"
"strings"
"time"
"github.com/heicode/manager/common"
"github.com/heicode/manager/setting/console_setting"
"github.com/gin-gonic/gin"
@@ -51,7 +51,7 @@ func getAndDecode(ctx context.Context, client *http.Client, url string, dest int
return errors.New("non-200 status")
}
return json.NewDecoder(resp.Body).Decode(dest)
return common.DecodeJson(resp.Body, dest)
}
func fetchGroupData(ctx context.Context, client *http.Client, groupConfig map[string]interface{}) UptimeGroupResult {
+9 -10
View File
@@ -1,7 +1,6 @@
package controller
import (
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -35,7 +34,7 @@ func Login(c *gin.Context) {
return
}
var loginRequest LoginRequest
err := json.NewDecoder(c.Request.Body).Decode(&loginRequest)
err := common.DecodeJson(c.Request.Body,&loginRequest)
if err != nil {
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
return
@@ -145,7 +144,7 @@ func Register(c *gin.Context) {
return
}
var user model.User
err := json.NewDecoder(c.Request.Body).Decode(&user)
err := common.DecodeJson(c.Request.Body,&user)
if err != nil {
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
return
@@ -508,7 +507,7 @@ func generateDefaultSidebarConfig(userRole int) string {
// 普通用户不包含admin区域
// 转换为JSON字符串
configBytes, err := json.Marshal(defaultConfig)
configBytes, err := common.Marshal(defaultConfig)
if err != nil {
common.SysLog("生成默认边栏配置失败: " + err.Error())
return ""
@@ -546,7 +545,7 @@ func GetUserModels(c *gin.Context) {
func UpdateUser(c *gin.Context) {
var updatedUser model.User
err := json.NewDecoder(c.Request.Body).Decode(&updatedUser)
err := common.DecodeJson(c.Request.Body,&updatedUser)
if err != nil || updatedUser.Id == 0 {
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
return
@@ -627,7 +626,7 @@ func AdminClearUserBinding(c *gin.Context) {
func UpdateSelf(c *gin.Context) {
var requestData map[string]interface{}
err := json.NewDecoder(c.Request.Body).Decode(&requestData)
err := common.DecodeJson(c.Request.Body,&requestData)
if err != nil {
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
return
@@ -691,12 +690,12 @@ func UpdateSelf(c *gin.Context) {
// 原有的用户信息更新逻辑
var user model.User
requestDataBytes, err := json.Marshal(requestData)
requestDataBytes, err := common.Marshal(requestData)
if err != nil {
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
return
}
err = json.Unmarshal(requestDataBytes, &user)
err = common.Unmarshal(requestDataBytes, &user)
if err != nil {
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
return
@@ -806,7 +805,7 @@ func DeleteSelf(c *gin.Context) {
func CreateUser(c *gin.Context) {
var user model.User
err := json.NewDecoder(c.Request.Body).Decode(&user)
err := common.DecodeJson(c.Request.Body,&user)
user.Username = strings.TrimSpace(user.Username)
if err != nil || user.Username == "" || user.Password == "" {
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
@@ -853,7 +852,7 @@ type ManageRequest struct {
// ManageUser Only admin user can do this
func ManageUser(c *gin.Context) {
var req ManageRequest
err := json.NewDecoder(c.Request.Body).Decode(&req)
err := common.DecodeJson(c.Request.Body,&req)
if err != nil {
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
+1 -2
View File
@@ -1,7 +1,6 @@
package controller
import (
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -40,7 +39,7 @@ func getWeChatIdByCode(code string) (string, error) {
}
defer httpResponse.Body.Close()
var res wechatLoginResponse
err = json.NewDecoder(httpResponse.Body).Decode(&res)
err = common.DecodeJson(httpResponse.Body, &res)
if err != nil {
return "", err
}
+1 -1
View File
@@ -414,7 +414,7 @@ func (c *ClaudeRequest) GetTools() []any {
func (c *ClaudeRequest) GetEfforts() string {
var OutputConfig OutputConfigForEffort
if err := json.Unmarshal(c.OutputConfig, &OutputConfig); err == nil {
if err := common.Unmarshal(c.OutputConfig, &OutputConfig); err == nil {
effort := OutputConfig.Effort
return effort
}
+44 -1
View File
@@ -386,7 +386,8 @@ func (m *MediaContent) ToFileSource() types.FileSource {
if file == nil || file.FileData == "" {
return nil
}
return types.NewFileSourceFromData(file.FileData, "")
mimeType := inferMimeTypeFromFilename(file.FileName)
return types.NewFileSourceFromData(file.FileData, mimeType)
case ContentTypeVideoUrl:
video := m.GetVideoUrl()
if video == nil || video.Url == "" {
@@ -397,6 +398,48 @@ func (m *MediaContent) ToFileSource() types.FileSource {
return nil
}
func inferMimeTypeFromFilename(filename string) string {
if filename == "" {
return ""
}
idx := strings.LastIndex(filename, ".")
if idx < 0 {
return ""
}
ext := strings.ToLower(filename[idx:])
switch ext {
case ".pdf":
return "application/pdf"
case ".txt", ".md", ".csv", ".log", ".json", ".xml", ".yaml", ".yml", ".html", ".htm", ".css", ".js", ".ts", ".go", ".py", ".java", ".c", ".cpp", ".h", ".rs", ".sh", ".bat", ".ps1", ".toml", ".ini", ".cfg", ".conf", ".sql", ".rb", ".php", ".swift", ".kt", ".r", ".m", ".lua":
return "text/plain"
case ".png":
return "image/png"
case ".jpg", ".jpeg":
return "image/jpeg"
case ".gif":
return "image/gif"
case ".webp":
return "image/webp"
case ".svg":
return "image/svg+xml"
case ".mp3":
return "audio/mpeg"
case ".wav":
return "audio/wav"
case ".mp4":
return "video/mp4"
case ".webm":
return "video/webm"
case ".doc", ".docx":
return "application/msword"
case ".xls", ".xlsx":
return "application/vnd.ms-excel"
case ".ppt", ".pptx":
return "application/vnd.ms-powerpoint"
}
return ""
}
type MessageImageUrl struct {
Url string `json:"url"`
Detail string `json:"detail,omitempty"`
+1 -2
View File
@@ -2,7 +2,6 @@ package middleware
import (
"bytes"
"encoding/json"
"io"
"net/http"
@@ -35,7 +34,7 @@ func JimengRequestConvert() func(c *gin.Context) {
"metadata": originalReq,
}
jsonData, err := json.Marshal(unifiedReq)
jsonData, err := common.Marshal(unifiedReq)
if err != nil {
abortWithOpenAiMessage(c, http.StatusInternalServerError, "Failed to marshal request body")
return
+1 -2
View File
@@ -2,7 +2,6 @@ package middleware
import (
"bytes"
"encoding/json"
"io"
"github.com/heicode/manager/common"
@@ -32,7 +31,7 @@ func KlingRequestConvert() func(c *gin.Context) {
"metadata": originalReq,
}
jsonData, err := json.Marshal(unifiedReq)
jsonData, err := common.Marshal(unifiedReq)
if err != nil {
c.Next()
return
+1 -2
View File
@@ -1,7 +1,6 @@
package middleware
import (
"encoding/json"
"net/http"
"net/url"
@@ -48,7 +47,7 @@ func TurnstileCheck() gin.HandlerFunc {
}
defer rawRes.Body.Close()
var res turnstileCheckResponse
err = json.NewDecoder(rawRes.Body).Decode(&res)
err = common.DecodeJson(rawRes.Body, &res)
if err != nil {
common.SysLog(err.Error())
c.JSON(http.StatusOK, gin.H{
+1 -1
View File
@@ -223,7 +223,7 @@ func (channel *Channel) GetOtherInfo() map[string]interface{} {
}
func (channel *Channel) SetOtherInfo(otherInfo map[string]interface{}) {
otherInfoBytes, err := json.Marshal(otherInfo)
otherInfoBytes, err := common.Marshal(otherInfo)
if err != nil {
common.SysLog(fmt.Sprintf("failed to marshal other info: channel_id=%d, tag=%s, name=%s, error=%v", channel.Id, channel.GetTag(), channel.Name, err))
return
+2 -3
View File
@@ -2,7 +2,6 @@ package model
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"strings"
@@ -46,7 +45,7 @@ func (p *PasskeyCredential) TransportList() []protocol.AuthenticatorTransport {
return nil
}
var transports []string
if err := json.Unmarshal([]byte(p.Transports), &transports); err != nil {
if err := common.Unmarshal([]byte(p.Transports), &transports); err != nil {
return nil
}
result := make([]protocol.AuthenticatorTransport, 0, len(transports))
@@ -65,7 +64,7 @@ func (p *PasskeyCredential) SetTransports(list []protocol.AuthenticatorTransport
for i, transport := range list {
stringList[i] = string(transport)
}
encoded, err := json.Marshal(stringList)
encoded, err := common.Marshal(stringList)
if err != nil {
return
}
+1 -1
View File
@@ -44,7 +44,7 @@ func (j *JSONValue) Scan(value interface{}) error {
return nil
default:
// 其他类型尝试序列化为 JSON
b, err := json.Marshal(v)
b, err := common.Marshal(v)
if err != nil {
return err
}
+2 -3
View File
@@ -1,7 +1,6 @@
package model
import (
"encoding/json"
"fmt"
"strings"
@@ -220,7 +219,7 @@ func updatePricing() {
continue
}
var raw map[string]interface{}
if err := json.Unmarshal([]byte(meta.Endpoints), &raw); err == nil {
if err := common.Unmarshal([]byte(meta.Endpoints), &raw); err == nil {
endpoints := make([]string, 0, len(raw))
for k, v := range raw {
switch v.(type) {
@@ -264,7 +263,7 @@ func updatePricing() {
continue
}
var raw map[string]interface{}
if err := json.Unmarshal([]byte(meta.Endpoints), &raw); err == nil {
if err := common.Unmarshal([]byte(meta.Endpoints), &raw); err == nil {
for k, v := range raw {
switch val := v.(type) {
case string:
+3 -3
View File
@@ -2,13 +2,13 @@ package oauth
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
"time"
"github.com/heicode/manager/common"
"github.com/heicode/manager/i18n"
"github.com/heicode/manager/logger"
"github.com/heicode/manager/model"
@@ -84,7 +84,7 @@ func (p *DiscordProvider) ExchangeToken(ctx context.Context, code string, c *gin
logger.LogDebug(ctx, "[OAuth-Discord] ExchangeToken response status: %d", res.StatusCode)
var discordResponse discordOAuthResponse
err = json.NewDecoder(res.Body).Decode(&discordResponse)
err = common.DecodeJson(res.Body,&discordResponse)
if err != nil {
logger.LogError(ctx, fmt.Sprintf("[OAuth-Discord] ExchangeToken decode error: %s", err.Error()))
return nil, err
@@ -134,7 +134,7 @@ func (p *DiscordProvider) GetUserInfo(ctx context.Context, token *OAuthToken) (*
}
var discordUser discordUser
err = json.NewDecoder(res.Body).Decode(&discordUser)
err = common.DecodeJson(res.Body,&discordUser)
if err != nil {
logger.LogError(ctx, fmt.Sprintf("[OAuth-Discord] GetUserInfo decode error: %s", err.Error()))
return nil, err
+3 -4
View File
@@ -3,7 +3,6 @@ package oauth
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
@@ -57,7 +56,7 @@ func (p *GitHubProvider) ExchangeToken(ctx context.Context, code string, c *gin.
"client_secret": common.GitHubClientSecret,
"code": code,
}
jsonData, err := json.Marshal(values)
jsonData, err := common.Marshal(values)
if err != nil {
return nil, err
}
@@ -82,7 +81,7 @@ func (p *GitHubProvider) ExchangeToken(ctx context.Context, code string, c *gin.
logger.LogDebug(ctx, "[OAuth-GitHub] ExchangeToken response status: %d", res.StatusCode)
var oAuthResponse gitHubOAuthResponse
err = json.NewDecoder(res.Body).Decode(&oAuthResponse)
err = common.DecodeJson(res.Body,&oAuthResponse)
if err != nil {
logger.LogError(ctx, fmt.Sprintf("[OAuth-GitHub] ExchangeToken decode error: %s", err.Error()))
return nil, err
@@ -135,7 +134,7 @@ func (p *GitHubProvider) GetUserInfo(ctx context.Context, token *OAuthToken) (*O
}
var githubUser gitHubUser
err = json.NewDecoder(res.Body).Decode(&githubUser)
err = common.DecodeJson(res.Body,&githubUser)
if err != nil {
logger.LogError(ctx, fmt.Sprintf("[OAuth-GitHub] GetUserInfo decode error: %s", err.Error()))
return nil, err
+2 -3
View File
@@ -3,7 +3,6 @@ package oauth
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"net/url"
@@ -90,7 +89,7 @@ func (p *LinuxDOProvider) ExchangeToken(ctx context.Context, code string, c *gin
AccessToken string `json:"access_token"`
Message string `json:"message"`
}
if err := json.NewDecoder(res.Body).Decode(&tokenRes); err != nil {
if err := common.DecodeJson(res.Body,&tokenRes); err != nil {
logger.LogError(ctx, fmt.Sprintf("[OAuth-LinuxDO] ExchangeToken decode error: %s", err.Error()))
return nil, err
}
@@ -130,7 +129,7 @@ func (p *LinuxDOProvider) GetUserInfo(ctx context.Context, token *OAuthToken) (*
logger.LogDebug(ctx, "[OAuth-LinuxDO] GetUserInfo response status: %d", res.StatusCode)
var linuxdoUser linuxdoUser
if err := json.NewDecoder(res.Body).Decode(&linuxdoUser); err != nil {
if err := common.DecodeJson(res.Body,&linuxdoUser); err != nil {
logger.LogError(ctx, fmt.Sprintf("[OAuth-LinuxDO] GetUserInfo decode error: %s", err.Error()))
return nil, err
}
+3 -3
View File
@@ -2,13 +2,13 @@ package oauth
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
"time"
"github.com/heicode/manager/common"
"github.com/heicode/manager/i18n"
"github.com/heicode/manager/logger"
"github.com/heicode/manager/model"
@@ -86,7 +86,7 @@ func (p *OIDCProvider) ExchangeToken(ctx context.Context, code string, c *gin.Co
logger.LogDebug(ctx, "[OAuth-OIDC] ExchangeToken response status: %d", res.StatusCode)
var oidcResponse oidcOAuthResponse
err = json.NewDecoder(res.Body).Decode(&oidcResponse)
err = common.DecodeJson(res.Body,&oidcResponse)
if err != nil {
logger.LogError(ctx, fmt.Sprintf("[OAuth-OIDC] ExchangeToken decode error: %s", err.Error()))
return nil, err
@@ -138,7 +138,7 @@ func (p *OIDCProvider) GetUserInfo(ctx context.Context, token *OAuthToken) (*OAu
}
var oidcUser oidcUser
err = json.NewDecoder(res.Body).Decode(&oidcUser)
err = common.DecodeJson(res.Body,&oidcUser)
if err != nil {
logger.LogError(ctx, fmt.Sprintf("[OAuth-OIDC] GetUserInfo decode error: %s", err.Error()))
return nil, err
+3 -3
View File
@@ -1,10 +1,10 @@
package ali
import (
"encoding/json"
"io"
"net/http"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
relaycommon "github.com/heicode/manager/relay/common"
"github.com/heicode/manager/service"
@@ -40,7 +40,7 @@ func RerankHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayI
service.CloseResponseBodyGracefully(resp)
var aliResponse AliRerankResponse
err = json.Unmarshal(responseBody, &aliResponse)
err = common.Unmarshal(responseBody, &aliResponse)
if err != nil {
return types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError), nil
}
@@ -64,7 +64,7 @@ func RerankHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayI
Usage: usage,
}
jsonResponse, err := json.Marshal(rerankResponse)
jsonResponse, err := common.Marshal(rerankResponse)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
+1 -1
View File
@@ -44,7 +44,7 @@ func formatRequest(requestBody io.Reader, requestHeader http.Header) (*AwsClaude
var tempArray []string
tempArray = strings.Split(anthropicBetaValues, ",")
if len(tempArray) > 0 {
betaJson, err := json.Marshal(tempArray)
betaJson, err := common.Marshal(tempArray)
if err != nil {
return nil, err
}
+1 -2
View File
@@ -2,7 +2,6 @@ package aws
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
@@ -321,7 +320,7 @@ func handleNovaRequest(c *gin.Context, info *relaycommon.RelayInfo, a *Adaptor)
} `json:"usage"`
}
if err := json.Unmarshal(awsResp.Body, &novaResp); err != nil {
if err := common.Unmarshal(awsResp.Body, &novaResp); err != nil {
return types.NewError(errors.Wrap(err, "unmarshal nova response"), types.ErrorCodeBadResponseBody), nil
}
+5 -6
View File
@@ -1,7 +1,6 @@
package baidu
import (
"encoding/json"
"errors"
"fmt"
"io"
@@ -145,7 +144,7 @@ func baiduHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respon
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
service.CloseResponseBodyGracefully(resp)
err = json.Unmarshal(responseBody, &baiduResponse)
err = common.Unmarshal(responseBody, &baiduResponse)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
@@ -153,7 +152,7 @@ func baiduHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respon
return types.NewError(fmt.Errorf("%s", baiduResponse.ErrorMsg), types.ErrorCodeBadResponseBody), nil
}
fullTextResponse := responseBaidu2OpenAI(&baiduResponse)
jsonResponse, err := json.Marshal(fullTextResponse)
jsonResponse, err := common.Marshal(fullTextResponse)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
@@ -170,7 +169,7 @@ func baiduEmbeddingHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *ht
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
service.CloseResponseBodyGracefully(resp)
err = json.Unmarshal(responseBody, &baiduResponse)
err = common.Unmarshal(responseBody, &baiduResponse)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
@@ -178,7 +177,7 @@ func baiduEmbeddingHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *ht
return types.NewError(fmt.Errorf("%s", baiduResponse.ErrorMsg), types.ErrorCodeBadResponseBody), nil
}
fullTextResponse := embeddingResponseBaidu2OpenAI(&baiduResponse)
jsonResponse, err := json.Marshal(fullTextResponse)
jsonResponse, err := common.Marshal(fullTextResponse)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
@@ -230,7 +229,7 @@ func getBaiduAccessTokenHelper(apiKey string) (*BaiduAccessToken, error) {
defer res.Body.Close()
var accessToken BaiduAccessToken
err = json.NewDecoder(res.Body).Decode(&accessToken)
err = common.DecodeJson(res.Body, &accessToken)
if err != nil {
return nil, err
}
+31 -15
View File
@@ -1,6 +1,7 @@
package claude
import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
@@ -54,8 +55,8 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe
Description: tool.Function.Description,
}
claudeTool.InputSchema = make(map[string]interface{})
if params["type"] != nil {
claudeTool.InputSchema["type"] = params["type"].(string)
if typeVal, ok := params["type"].(string); ok {
claudeTool.InputSchema["type"] = typeVal
}
claudeTool.InputSchema["properties"] = params["properties"]
claudeTool.InputSchema["required"] = params["required"]
@@ -385,20 +386,35 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe
if err != nil {
return nil, fmt.Errorf("get file data failed: %s", err.Error())
}
claudeMediaMessage := dto.ClaudeMediaMessage{
Source: &dto.ClaudeMessageSource{
Type: "base64",
},
if strings.HasPrefix(mimeType, "text/") {
decodedBytes, decErr := base64.StdEncoding.DecodeString(base64Data)
if decErr != nil {
continue
}
text := string(decodedBytes)
claudeMediaMessages = append(claudeMediaMessages, dto.ClaudeMediaMessage{
Type: "text",
Text: common.GetPointer(text),
})
} else if strings.HasPrefix(mimeType, "application/pdf") {
claudeMediaMessages = append(claudeMediaMessages, dto.ClaudeMediaMessage{
Type: "document",
Source: &dto.ClaudeMessageSource{
Type: "base64",
MediaType: mimeType,
Data: base64Data,
},
})
} else if strings.HasPrefix(mimeType, "image/") {
claudeMediaMessages = append(claudeMediaMessages, dto.ClaudeMediaMessage{
Type: "image",
Source: &dto.ClaudeMessageSource{
Type: "base64",
MediaType: mimeType,
Data: base64Data,
},
})
}
if strings.HasPrefix(mimeType, "application/pdf") {
claudeMediaMessage.Type = "document"
} else {
claudeMediaMessage.Type = "image"
}
claudeMediaMessage.Source.MediaType = mimeType
claudeMediaMessage.Source.Data = base64Data
claudeMediaMessages = append(claudeMediaMessages, claudeMediaMessage)
continue
}
}
@@ -2,12 +2,12 @@ package cloudflare
import (
"bufio"
"encoding/json"
"io"
"net/http"
"strings"
"time"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
"github.com/heicode/manager/logger"
relaycommon "github.com/heicode/manager/relay/common"
@@ -51,7 +51,7 @@ func cfStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Res
}
var response dto.ChatCompletionsStreamResponse
err := json.Unmarshal([]byte(data), &response)
err := common.Unmarshal([]byte(data), &response)
if err != nil {
logger.LogError(c, "error_unmarshalling_stream_response: "+err.Error())
continue
@@ -97,7 +97,7 @@ func cfHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Response)
}
service.CloseResponseBodyGracefully(resp)
var response dto.TextResponse
err = json.Unmarshal(responseBody, &response)
err = common.Unmarshal(responseBody, &response)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
@@ -109,7 +109,7 @@ func cfHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Response)
usage := service.ResponseText2Usage(c, responseText, info.UpstreamModelName, info.GetEstimatePromptTokens())
response.Usage = *usage
response.Id = helper.GetResponseID(c)
jsonResponse, err := json.Marshal(response)
jsonResponse, err := common.Marshal(response)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
@@ -126,7 +126,7 @@ func cfSTTHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respon
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
service.CloseResponseBodyGracefully(resp)
err = json.Unmarshal(responseBody, &cfResp)
err = common.Unmarshal(responseBody, &cfResp)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
@@ -135,7 +135,7 @@ func cfSTTHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respon
Text: cfResp.Result.Text,
}
jsonResponse, err := json.Marshal(audioResp)
jsonResponse, err := common.Marshal(audioResp)
if err != nil {
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
}
+6 -7
View File
@@ -2,7 +2,6 @@ package cohere
import (
"bufio"
"encoding/json"
"io"
"net/http"
"strings"
@@ -119,7 +118,7 @@ func cohereStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http
}
data = strings.TrimSuffix(data, "\r")
var cohereResp CohereResponse
err := json.Unmarshal([]byte(data), &cohereResp)
err := common.Unmarshal([]byte(data), &cohereResp)
if err != nil {
common.SysLog("error unmarshalling stream response: " + err.Error())
return true
@@ -154,7 +153,7 @@ func cohereStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http
}
responseText += cohereResp.Text
}
jsonStr, err := json.Marshal(openaiResp)
jsonStr, err := common.Marshal(openaiResp)
if err != nil {
common.SysLog("error marshalling stream response: " + err.Error())
return true
@@ -180,7 +179,7 @@ func cohereHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respo
}
service.CloseResponseBodyGracefully(resp)
var cohereResp CohereResponseResult
err = json.Unmarshal(responseBody, &cohereResp)
err = common.Unmarshal(responseBody, &cohereResp)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
@@ -204,7 +203,7 @@ func cohereHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respo
},
}
jsonResponse, err := json.Marshal(openaiResp)
jsonResponse, err := common.Marshal(openaiResp)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
@@ -221,7 +220,7 @@ func cohereRerankHandler(c *gin.Context, resp *http.Response, info *relaycommon.
}
service.CloseResponseBodyGracefully(resp)
var cohereResp CohereRerankResponseResult
err = json.Unmarshal(responseBody, &cohereResp)
err = common.Unmarshal(responseBody, &cohereResp)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
@@ -240,7 +239,7 @@ func cohereRerankHandler(c *gin.Context, resp *http.Response, info *relaycommon.
rerankResp.Results = cohereResp.Results
rerankResp.Usage = usage
jsonResponse, err := json.Marshal(rerankResp)
jsonResponse, err := common.Marshal(rerankResp)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
+15 -15
View File
@@ -1,16 +1,16 @@
package coze
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"time"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
"github.com/heicode/manager/relay/channel"
"github.com/heicode/manager/relay/common"
relaycommon "github.com/heicode/manager/relay/common"
"github.com/heicode/manager/types"
"github.com/gin-gonic/gin"
@@ -19,33 +19,33 @@ import (
type Adaptor struct {
}
func (a *Adaptor) ConvertGeminiRequest(*gin.Context, *common.RelayInfo, *dto.GeminiChatRequest) (any, error) {
func (a *Adaptor) ConvertGeminiRequest(*gin.Context, *relaycommon.RelayInfo, *dto.GeminiChatRequest) (any, error) {
//TODO implement me
return nil, errors.New("not implemented")
}
// ConvertAudioRequest implements channel.Adaptor.
func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *common.RelayInfo, request dto.AudioRequest) (io.Reader, error) {
func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.AudioRequest) (io.Reader, error) {
return nil, errors.New("not implemented")
}
// ConvertClaudeRequest implements channel.Adaptor.
func (a *Adaptor) ConvertClaudeRequest(c *gin.Context, info *common.RelayInfo, request *dto.ClaudeRequest) (any, error) {
func (a *Adaptor) ConvertClaudeRequest(c *gin.Context, info *relaycommon.RelayInfo, request *dto.ClaudeRequest) (any, error) {
return nil, errors.New("not implemented")
}
// ConvertEmbeddingRequest implements channel.Adaptor.
func (a *Adaptor) ConvertEmbeddingRequest(c *gin.Context, info *common.RelayInfo, request dto.EmbeddingRequest) (any, error) {
func (a *Adaptor) ConvertEmbeddingRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.EmbeddingRequest) (any, error) {
return nil, errors.New("not implemented")
}
// ConvertImageRequest implements channel.Adaptor.
func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *common.RelayInfo, request dto.ImageRequest) (any, error) {
func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.ImageRequest) (any, error) {
return nil, errors.New("not implemented")
}
// ConvertOpenAIRequest implements channel.Adaptor.
func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *common.RelayInfo, request *dto.GeneralOpenAIRequest) (any, error) {
func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayInfo, request *dto.GeneralOpenAIRequest) (any, error) {
if request == nil {
return nil, errors.New("request is nil")
}
@@ -53,7 +53,7 @@ func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *common.RelayInfo, r
}
// ConvertOpenAIResponsesRequest implements channel.Adaptor.
func (a *Adaptor) ConvertOpenAIResponsesRequest(c *gin.Context, info *common.RelayInfo, request dto.OpenAIResponsesRequest) (any, error) {
func (a *Adaptor) ConvertOpenAIResponsesRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.OpenAIResponsesRequest) (any, error) {
return nil, errors.New("not implemented")
}
@@ -63,7 +63,7 @@ func (a *Adaptor) ConvertRerankRequest(c *gin.Context, relayMode int, request dt
}
// DoRequest implements channel.Adaptor.
func (a *Adaptor) DoRequest(c *gin.Context, info *common.RelayInfo, requestBody io.Reader) (any, error) {
func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, requestBody io.Reader) (any, error) {
if info.IsStream {
return channel.DoApiRequest(a, c, info, requestBody)
}
@@ -79,7 +79,7 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *common.RelayInfo, requestBody
if err != nil {
return nil, err
}
err = json.Unmarshal(respBody, &cozeResponse)
err = common.Unmarshal(respBody, &cozeResponse)
if cozeResponse.Code != 0 {
return nil, errors.New(cozeResponse.Msg)
}
@@ -102,7 +102,7 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *common.RelayInfo, requestBody
}
// DoResponse implements channel.Adaptor.
func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *common.RelayInfo) (usage any, err *types.NewAPIError) {
func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) {
if info.IsStream {
usage, err = cozeChatStreamHandler(c, info, resp)
} else {
@@ -122,17 +122,17 @@ func (a *Adaptor) GetModelList() []string {
}
// GetRequestURL implements channel.Adaptor.
func (a *Adaptor) GetRequestURL(info *common.RelayInfo) (string, error) {
func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
return fmt.Sprintf("%s/v3/chat", info.ChannelBaseUrl), nil
}
// Init implements channel.Adaptor.
func (a *Adaptor) Init(info *common.RelayInfo) {
func (a *Adaptor) Init(info *relaycommon.RelayInfo) {
}
// SetupRequestHeader implements channel.Adaptor.
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *common.RelayInfo) error {
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *relaycommon.RelayInfo) error {
channel.SetupApiRequestHeader(info, c, req)
req.Set("Authorization", "Bearer "+info.ApiKey)
return nil
+7 -7
View File
@@ -56,7 +56,7 @@ func cozeChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Res
var response dto.TextResponse
var cozeResponse CozeChatDetailResponse
response.Model = info.UpstreamModelName
err = json.Unmarshal(responseBody, &cozeResponse)
err = common.Unmarshal(responseBody, &cozeResponse)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
@@ -86,7 +86,7 @@ func cozeChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Res
FinishReason: "stop",
},
}
jsonResponse, err := json.Marshal(response)
jsonResponse, err := common.Marshal(response)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
@@ -154,7 +154,7 @@ func handleCozeEvent(c *gin.Context, event string, data string, responseText *st
case "conversation.chat.completed":
// 将 data 解析为 CozeChatResponseData
var chatData CozeChatResponseData
err := json.Unmarshal([]byte(data), &chatData)
err := common.Unmarshal([]byte(data), &chatData)
if err != nil {
common.SysLog("error_unmarshalling_stream_response: " + err.Error())
return
@@ -171,14 +171,14 @@ func handleCozeEvent(c *gin.Context, event string, data string, responseText *st
case "conversation.message.delta":
// 将 data 解析为 CozeChatV3MessageDetail
var messageData CozeChatV3MessageDetail
err := json.Unmarshal([]byte(data), &messageData)
err := common.Unmarshal([]byte(data), &messageData)
if err != nil {
common.SysLog("error_unmarshalling_stream_response: " + err.Error())
return
}
var content string
err = json.Unmarshal(messageData.Content, &content)
err = common.Unmarshal(messageData.Content, &content)
if err != nil {
common.SysLog("error_unmarshalling_stream_response: " + err.Error())
return
@@ -203,7 +203,7 @@ func handleCozeEvent(c *gin.Context, event string, data string, responseText *st
case "error":
var errorData CozeError
err := json.Unmarshal([]byte(data), &errorData)
err := common.Unmarshal([]byte(data), &errorData)
if err != nil {
common.SysLog("error_unmarshalling_stream_response: " + err.Error())
return
@@ -242,7 +242,7 @@ func checkIfChatComplete(a *Adaptor, c *gin.Context, info *relaycommon.RelayInfo
if err != nil {
return fmt.Errorf("read response body failed: %w", err), false
}
err = json.Unmarshal(responseBody, &cozeResponse)
err = common.Unmarshal(responseBody, &cozeResponse)
if err != nil {
return fmt.Errorf("unmarshal response body failed: %w", err), false
}
+10 -8
View File
@@ -110,7 +110,7 @@ func uploadDifyFile(c *gin.Context, info *relaycommon.RelayInfo, user string, me
var result struct {
Id string `json:"id"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
if err := common.DecodeJson(resp.Body, &result); err != nil {
common.SysLog("failed to decode response: " + err.Error())
return nil
}
@@ -135,7 +135,7 @@ func requestOpenAI2Dify(c *gin.Context, info *relaycommon.RelayInfo, request dto
user = json.RawMessage(helper.GetResponseID(c))
}
var stringUser string
err := json.Unmarshal(user, &stringUser)
err := common.Unmarshal(user, &stringUser)
if err != nil {
common.SysLog("failed to unmarshal user: " + err.Error())
stringUser = helper.GetResponseID(c)
@@ -159,9 +159,11 @@ func requestOpenAI2Dify(c *gin.Context, info *relaycommon.RelayInfo, request dto
media := mediaContent.GetImageMedia()
var file *DifyFile
if media.IsRemoteImage() {
file.Type = media.MimeType
file.TransferMode = "remote_url"
file.URL = media.Url
file = &DifyFile{
Type: media.MimeType,
TransferMode: "remote_url",
URL: media.Url,
}
} else {
file = uploadDifyFile(c, info, difyReq.User, mediaContent)
}
@@ -225,7 +227,7 @@ func difyStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R
helper.SetEventStreamHeaders(c)
helper.StreamScannerHandler(c, resp, info, func(data string, sr *helper.StreamResult) {
var difyResponse DifyChunkChatCompletionResponse
if err := json.Unmarshal([]byte(data), &difyResponse); err != nil {
if err := common.Unmarshal([]byte(data), &difyResponse); err != nil {
common.SysLog("error unmarshalling stream response: " + err.Error())
sr.Error(err)
return
@@ -266,7 +268,7 @@ func difyHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respons
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
service.CloseResponseBodyGracefully(resp)
err = json.Unmarshal(responseBody, &difyResponse)
err = common.Unmarshal(responseBody, &difyResponse)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
@@ -285,7 +287,7 @@ func difyHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respons
FinishReason: "stop",
}
fullTextResponse.Choices = append(fullTextResponse.Choices, choice)
jsonResponse, err := json.Marshal(fullTextResponse)
jsonResponse, err := common.Marshal(fullTextResponse)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
+2 -2
View File
@@ -1,12 +1,12 @@
package jimeng
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
"github.com/heicode/manager/relay/channel"
"github.com/heicode/manager/relay/channel/openai"
@@ -79,7 +79,7 @@ func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *relaycommon.RelayInf
}
if len(request.ExtraFields) > 0 {
if err := json.Unmarshal(request.ExtraFields, &payload); err != nil {
if err := common.Unmarshal(request.ExtraFields, &payload); err != nil {
return nil, fmt.Errorf("failed to unmarshal extra fields: %w", err)
}
}
+3 -3
View File
@@ -1,11 +1,11 @@
package jimeng
import (
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
relaycommon "github.com/heicode/manager/relay/common"
"github.com/heicode/manager/service"
@@ -57,7 +57,7 @@ func jimengImageHandler(c *gin.Context, resp *http.Response, info *relaycommon.R
}
service.CloseResponseBodyGracefully(resp)
err = json.Unmarshal(responseBody, &jimengResponse)
err = common.Unmarshal(responseBody, &jimengResponse)
if err != nil {
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
@@ -74,7 +74,7 @@ func jimengImageHandler(c *gin.Context, resp *http.Response, info *relaycommon.R
// Convert Jimeng response to OpenAI format
fullTextResponse := responseJimeng2OpenAIImage(c, &jimengResponse, info)
jsonResponse, err := json.Marshal(fullTextResponse)
jsonResponse, err := common.Marshal(fullTextResponse)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
+2 -2
View File
@@ -5,7 +5,6 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
@@ -15,6 +14,7 @@ import (
"strings"
"time"
"github.com/heicode/manager/common"
"github.com/heicode/manager/logger"
"github.com/gin-gonic/gin"
)
@@ -41,7 +41,7 @@ import (
const HexPayloadHashKey = "HexPayloadHash"
func SetPayloadHash(c *gin.Context, req any) error {
body, err := json.Marshal(req)
body, err := common.Marshal(req)
if err != nil {
return err
}
+3 -3
View File
@@ -2,12 +2,12 @@ package minimax
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
"github.com/heicode/manager/relay/channel"
"github.com/heicode/manager/relay/channel/claude"
@@ -56,12 +56,12 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf
// 同步扩展字段的厂商自定义metadata
if len(request.Metadata) > 0 {
if err := json.Unmarshal(request.Metadata, &minimaxRequest); err != nil {
if err := common.Unmarshal(request.Metadata, &minimaxRequest); err != nil {
return nil, fmt.Errorf("error unmarshalling metadata to minimax request: %w", err)
}
}
jsonData, err := json.Marshal(minimaxRequest)
jsonData, err := common.Marshal(minimaxRequest)
if err != nil {
return nil, fmt.Errorf("error marshalling minimax request: %w", err)
}
+2 -2
View File
@@ -2,13 +2,13 @@ package minimax
import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
relaycommon "github.com/heicode/manager/relay/common"
"github.com/heicode/manager/types"
@@ -117,7 +117,7 @@ func handleTTSResponse(c *gin.Context, resp *http.Response, info *relaycommon.Re
// Parse response
var minimaxResp MiniMaxTTSResponse
if unmarshalErr := json.Unmarshal(body, &minimaxResp); unmarshalErr != nil {
if unmarshalErr := common.Unmarshal(body, &minimaxResp); unmarshalErr != nil {
return nil, types.NewErrorWithStatusCode(
fmt.Errorf("failed to unmarshal minimax TTS response: %w", unmarshalErr),
types.ErrorCodeBadResponseBody,
+1 -2
View File
@@ -1,7 +1,6 @@
package mokaai
import (
"encoding/json"
"io"
"net/http"
@@ -59,7 +58,7 @@ func mokaEmbeddingHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *htt
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
service.CloseResponseBodyGracefully(resp)
err = json.Unmarshal(responseBody, &baiduResponse)
err = common.Unmarshal(responseBody, &baiduResponse)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
+4 -5
View File
@@ -2,7 +2,6 @@ package ollama
import (
"bufio"
"encoding/json"
"fmt"
"io"
"net/http"
@@ -32,7 +31,7 @@ func openAIChatToOllamaChat(c *gin.Context, r *dto.GeneralOpenAIRequest) (*Ollam
} else if r.ResponseFormat.Type == "json_schema" {
if len(r.ResponseFormat.JsonSchema) > 0 {
var schema any
_ = json.Unmarshal(r.ResponseFormat.JsonSchema, &schema)
_ = common.Unmarshal(r.ResponseFormat.JsonSchema, &schema)
chatReq.Format = schema
}
}
@@ -127,7 +126,7 @@ func openAIChatToOllamaChat(c *gin.Context, r *dto.GeneralOpenAIRequest) (*Ollam
for _, tc := range parsed {
var args interface{}
if tc.Function.Arguments != "" {
_ = json.Unmarshal([]byte(tc.Function.Arguments), &args)
_ = common.Unmarshal([]byte(tc.Function.Arguments), &args)
}
if args == nil {
args = map[string]any{}
@@ -180,7 +179,7 @@ func openAIToGenerate(c *gin.Context, r *dto.GeneralOpenAIRequest) (*OllamaGener
gen.Format = "json"
} else if r.ResponseFormat.Type == "json_schema" {
var schema any
_ = json.Unmarshal(r.ResponseFormat.JsonSchema, &schema)
_ = common.Unmarshal(r.ResponseFormat.JsonSchema, &schema)
gen.Format = schema
}
}
@@ -510,7 +509,7 @@ func FetchOllamaVersion(baseURL, apiKey string) (string, error) {
Version string `json:"version"`
}
if err := json.Unmarshal(body, &versionResp); err != nil {
if err := common.Unmarshal(body, &versionResp); err != nil {
return "", fmt.Errorf("解析响应失败: %v", err)
}
+7 -7
View File
@@ -88,7 +88,7 @@ func ollamaStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http
continue
}
var chunk ollamaChatStreamChunk
if err := json.Unmarshal([]byte(line), &chunk); err != nil {
if err := common.Unmarshal([]byte(line), &chunk); err != nil {
logger.LogError(c, "ollama stream json decode error: "+err.Error()+" line="+line)
return usage, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
@@ -123,7 +123,7 @@ func ollamaStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http
if raw != "" && raw != "null" {
// Unmarshal the JSON string to get the actual content without quotes
var thinkingContent string
if err := json.Unmarshal(chunk.Message.Thinking, &thinkingContent); err == nil {
if err := common.Unmarshal(chunk.Message.Thinking, &thinkingContent); err == nil {
delta.Choices[0].Delta.SetReasoningContent(thinkingContent)
} else {
// Fallback to raw string if it's not a JSON string
@@ -136,7 +136,7 @@ func ollamaStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http
delta.Choices[0].Delta.ToolCalls = make([]dto.ToolCallResponse, 0, len(chunk.Message.ToolCalls))
for _, tc := range chunk.Message.ToolCalls {
// arguments -> string
argBytes, _ := json.Marshal(tc.Function.Arguments)
argBytes, _ := common.Marshal(tc.Function.Arguments)
toolId := fmt.Sprintf("call_%d", toolCallIndex)
tr := dto.ToolCallResponse{ID: toolId, Type: "function", Function: dto.FunctionResponse{Name: tc.Function.Name, Arguments: string(argBytes)}}
tr.SetIndex(toolCallIndex)
@@ -205,7 +205,7 @@ func ollamaChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R
continue
}
var ck ollamaChatStreamChunk
if err := json.Unmarshal([]byte(ln), &ck); err != nil {
if err := common.Unmarshal([]byte(ln), &ck); err != nil {
if len(lines) == 1 {
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
@@ -218,7 +218,7 @@ func ollamaChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R
if raw != "" && raw != "null" {
// Unmarshal the JSON string to get the actual content without quotes
var thinkingContent string
if err := json.Unmarshal(ck.Message.Thinking, &thinkingContent); err == nil {
if err := common.Unmarshal(ck.Message.Thinking, &thinkingContent); err == nil {
reasoningBuilder.WriteString(thinkingContent)
} else {
// Fallback to raw string if it's not a JSON string
@@ -235,7 +235,7 @@ func ollamaChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R
if !parsedAny {
var single ollamaChatStreamChunk
if err := json.Unmarshal(body, &single); err != nil {
if err := common.Unmarshal(body, &single); err != nil {
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
lastChunk = single
@@ -245,7 +245,7 @@ func ollamaChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R
if raw != "" && raw != "null" {
// Unmarshal the JSON string to get the actual content without quotes
var thinkingContent string
if err := json.Unmarshal(single.Message.Thinking, &thinkingContent); err == nil {
if err := common.Unmarshal(single.Message.Thinking, &thinkingContent); err == nil {
reasoningBuilder.WriteString(thinkingContent)
} else {
// Fallback to raw string if it's not a JSON string
+1 -1
View File
@@ -281,7 +281,7 @@ func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayIn
// 没有做排除3.5Haiku等,要出问题再加吧,最佳兼容性(不是
if request.THINKING != nil && strings.HasPrefix(info.UpstreamModelName, "anthropic") {
var thinking dto.Thinking // Claude标准Thinking格式
if err := json.Unmarshal(request.THINKING, &thinking); err != nil {
if err := common.Unmarshal(request.THINKING, &thinking); err != nil {
return nil, fmt.Errorf("error Unmarshal thinking: %w", err)
}
+4 -5
View File
@@ -1,7 +1,6 @@
package openai
import (
"encoding/json"
"strings"
"github.com/heicode/manager/common"
@@ -106,12 +105,12 @@ func processTokens(relayMode int, streamItems []string, responseTextBuilder *str
func processChatCompletions(streamResp string, streamItems []string, responseTextBuilder *strings.Builder, toolCount *int) error {
var streamResponses []dto.ChatCompletionsStreamResponse
if err := json.Unmarshal(common.StringToByteSlice(streamResp), &streamResponses); err != nil {
if err := common.Unmarshal(common.StringToByteSlice(streamResp), &streamResponses); err != nil {
// 一次性解析失败,逐个解析
common.SysLog("error unmarshalling stream response: " + err.Error())
for _, item := range streamItems {
var streamResponse dto.ChatCompletionsStreamResponse
if err := json.Unmarshal(common.StringToByteSlice(item), &streamResponse); err != nil {
if err := common.Unmarshal(common.StringToByteSlice(item), &streamResponse); err != nil {
return err
}
if err := ProcessStreamResponse(streamResponse, responseTextBuilder, toolCount); err != nil {
@@ -142,12 +141,12 @@ func processChatCompletions(streamResp string, streamItems []string, responseTex
func processCompletions(streamResp string, streamItems []string, responseTextBuilder *strings.Builder) error {
var streamResponses []dto.CompletionsStreamResponse
if err := json.Unmarshal(common.StringToByteSlice(streamResp), &streamResponses); err != nil {
if err := common.Unmarshal(common.StringToByteSlice(streamResp), &streamResponses); err != nil {
// 一次性解析失败,逐个解析
common.SysLog("error unmarshalling stream response: " + err.Error())
for _, item := range streamItems {
var streamResponse dto.CompletionsStreamResponse
if err := json.Unmarshal(common.StringToByteSlice(item), &streamResponse); err != nil {
if err := common.Unmarshal(common.StringToByteSlice(item), &streamResponse); err != nil {
continue
}
for _, choice := range streamResponse.Choices {
+3 -4
View File
@@ -1,7 +1,6 @@
package palm
import (
"encoding/json"
"io"
"net/http"
@@ -65,7 +64,7 @@ func palmStreamHandler(c *gin.Context, resp *http.Response) (*types.NewAPIError,
}
service.CloseResponseBodyGracefully(resp)
var palmResponse PaLMChatResponse
err = json.Unmarshal(responseBody, &palmResponse)
err = common.Unmarshal(responseBody, &palmResponse)
if err != nil {
common.SysLog("error unmarshalling stream response: " + err.Error())
stopChan <- true
@@ -77,7 +76,7 @@ func palmStreamHandler(c *gin.Context, resp *http.Response) (*types.NewAPIError,
if len(palmResponse.Candidates) > 0 {
responseText = palmResponse.Candidates[0].Content
}
jsonResponse, err := json.Marshal(fullTextResponse)
jsonResponse, err := common.Marshal(fullTextResponse)
if err != nil {
common.SysLog("error marshalling stream response: " + err.Error())
stopChan <- true
@@ -108,7 +107,7 @@ func palmHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respons
}
service.CloseResponseBodyGracefully(resp)
var palmResponse PaLMChatResponse
err = json.Unmarshal(responseBody, &palmResponse)
err = common.Unmarshal(responseBody, &palmResponse)
if err != nil {
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
+1 -2
View File
@@ -2,7 +2,6 @@ package replicate
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
@@ -111,7 +110,7 @@ func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *relaycommon.RelayInf
if len(request.OutputFormat) > 0 {
var outputFormat string
if err := json.Unmarshal(request.OutputFormat, &outputFormat); err == nil && strings.TrimSpace(outputFormat) != "" {
if err := common.Unmarshal(request.OutputFormat, &outputFormat); err == nil && strings.TrimSpace(outputFormat) != "" {
inputPayload["output_format"] = outputFormat
}
}
@@ -1,10 +1,10 @@
package siliconflow
import (
"encoding/json"
"io"
"net/http"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
relaycommon "github.com/heicode/manager/relay/common"
"github.com/heicode/manager/service"
@@ -20,7 +20,7 @@ func siliconflowRerankHandler(c *gin.Context, info *relaycommon.RelayInfo, resp
}
service.CloseResponseBodyGracefully(resp)
var siliconflowResp SFRerankResponse
err = json.Unmarshal(responseBody, &siliconflowResp)
err = common.Unmarshal(responseBody, &siliconflowResp)
if err != nil {
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
@@ -34,7 +34,7 @@ func siliconflowRerankHandler(c *gin.Context, info *relaycommon.RelayInfo, resp
Usage: *usage,
}
jsonResponse, err := json.Marshal(rerankResp)
jsonResponse, err := common.Marshal(rerankResp)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
@@ -5,7 +5,6 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
@@ -140,7 +139,7 @@ func tencentHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Resp
return nil, types.NewOpenAIError(err, types.ErrorCodeReadResponseBodyFailed, http.StatusInternalServerError)
}
service.CloseResponseBodyGracefully(resp)
err = json.Unmarshal(responseBody, &tencentSb)
err = common.Unmarshal(responseBody, &tencentSb)
if err != nil {
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
@@ -193,7 +192,7 @@ func getTencentSign(req TencentChatRequest, adaptor *Adaptor, secId, secKey stri
canonicalHeaders := fmt.Sprintf("content-type:%s\nhost:%s\nx-tc-action:%s\n",
"application/json", host, strings.ToLower(adaptor.Action))
signedHeaders := "content-type;host;x-tc-action"
payload, _ := json.Marshal(req)
payload, _ := common.Marshal(req)
hashedRequestPayload := sha256hex(string(payload))
canonicalRequest := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s",
httpRequestMethod,
+1 -2
View File
@@ -1,7 +1,6 @@
package vertex
import (
"encoding/json"
"errors"
"fmt"
"io"
@@ -305,7 +304,7 @@ func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayIn
}
if len(request.ExtraBody) > 0 {
var extra map[string]any
if err := json.Unmarshal(request.ExtraBody, &extra); err == nil {
if err := common.Unmarshal(request.ExtraBody, &extra); err == nil {
if n, ok := extra["n"].(float64); ok && n > 0 {
imgReq.N = lo.ToPtr(uint(n))
}
+6 -7
View File
@@ -9,14 +9,13 @@ func GetModelRegion(other string, localModelName string) string {
if err != nil {
return other // return original if parsing fails
}
if m[localModelName] != nil {
return m[localModelName].(string)
} else {
if v, ok := m["default"]; ok {
return v.(string)
}
return "global"
if val, ok := m[localModelName].(string); ok {
return val
}
if val, ok := m["default"].(string); ok {
return val
}
return "global"
}
return other
}
@@ -3,13 +3,13 @@ package vertex
import (
"crypto/rsa"
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"net/http"
"net/url"
"strings"
"github.com/heicode/manager/common"
relaycommon "github.com/heicode/manager/relay/common"
"github.com/heicode/manager/service"
@@ -129,7 +129,7 @@ func exchangeJwtForAccessToken(signedJWT string, info *relaycommon.RelayInfo) (s
defer resp.Body.Close()
var result map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
if err := common.DecodeJson(resp.Body, &result); err != nil {
return "", err
}
@@ -172,7 +172,7 @@ func exchangeJwtForAccessTokenWithProxy(signedJWT string, proxy string) (string,
defer resp.Body.Close()
var result map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
if err := common.DecodeJson(resp.Body, &result); err != nil {
return "", err
}
+3 -2
View File
@@ -10,6 +10,7 @@ import (
"path/filepath"
"strings"
"github.com/heicode/manager/common"
channelconstant "github.com/heicode/manager/constant"
"github.com/heicode/manager/dto"
"github.com/heicode/manager/relay/channel"
@@ -86,7 +87,7 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf
}
if len(request.Metadata) > 0 {
if err = json.Unmarshal(request.Metadata, &volcRequest); err != nil {
if err = common.Unmarshal(request.Metadata, &volcRequest); err != nil {
return nil, fmt.Errorf("error unmarshalling metadata to volcengine request: %w", err)
}
}
@@ -97,7 +98,7 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf
info.IsStream = true
}
jsonData, err := json.Marshal(volcRequest)
jsonData, err := common.Marshal(volcRequest)
if err != nil {
return nil, fmt.Errorf("error marshalling volcengine request: %w", err)
}
+3 -3
View File
@@ -3,13 +3,13 @@ package volcengine
import (
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
relaycommon "github.com/heicode/manager/relay/common"
"github.com/heicode/manager/types"
@@ -154,7 +154,7 @@ func handleTTSResponse(c *gin.Context, resp *http.Response, info *relaycommon.Re
defer resp.Body.Close()
var volcResp VolcengineTTSResponse
if unmarshalErr := json.Unmarshal(body, &volcResp); unmarshalErr != nil {
if unmarshalErr := common.Unmarshal(body, &volcResp); unmarshalErr != nil {
return nil, types.NewErrorWithStatusCode(
errors.New("failed to parse volcengine response"),
types.ErrorCodeBadResponseBody,
@@ -226,7 +226,7 @@ func handleTTSWebSocketResponse(c *gin.Context, requestURL string, volcRequest V
}
defer conn.Close()
payload, marshalErr := json.Marshal(volcRequest)
payload, marshalErr := common.Marshal(volcRequest)
if marshalErr != nil {
return nil, types.NewErrorWithStatusCode(
fmt.Errorf("failed to marshal request: %w", marshalErr),
+3 -4
View File
@@ -4,7 +4,6 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/url"
@@ -143,7 +142,7 @@ func xunfeiStreamHandler(c *gin.Context, textRequest dto.GeneralOpenAIRequest, a
usage.CompletionTokens += xunfeiResponse.Payload.Usage.Text.CompletionTokens
usage.TotalTokens += xunfeiResponse.Payload.Usage.Text.TotalTokens
response := streamResponseXunfei2OpenAI(&xunfeiResponse)
jsonResponse, err := json.Marshal(response)
jsonResponse, err := common.Marshal(response)
if err != nil {
common.SysLog("error marshalling stream response: " + err.Error())
return true
@@ -191,7 +190,7 @@ func xunfeiHandler(c *gin.Context, textRequest dto.GeneralOpenAIRequest, appId s
xunfeiResponse.Payload.Choices.Text[0].Content = content
response := responseXunfei2OpenAI(&xunfeiResponse)
jsonResponse, err := json.Marshal(response)
jsonResponse, err := common.Marshal(response)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
@@ -228,7 +227,7 @@ func xunfeiMakeRequest(textRequest dto.GeneralOpenAIRequest, domain, authUrl, ap
break
}
var response XunfeiChatResponse
err = json.Unmarshal(msg, &response)
err = common.Unmarshal(msg, &response)
if err != nil {
common.SysLog("error unmarshalling stream response: " + err.Error())
break
+5 -6
View File
@@ -2,7 +2,6 @@ package zhipu
import (
"bufio"
"encoding/json"
"io"
"net/http"
"strings"
@@ -187,7 +186,7 @@ func zhipuStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.
select {
case data := <-dataChan:
response := streamResponseZhipu2OpenAI(data)
jsonResponse, err := json.Marshal(response)
jsonResponse, err := common.Marshal(response)
if err != nil {
common.SysLog("error marshalling stream response: " + err.Error())
return true
@@ -196,13 +195,13 @@ func zhipuStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.
return true
case data := <-metaChan:
var zhipuResponse ZhipuStreamMetaResponse
err := json.Unmarshal([]byte(data), &zhipuResponse)
err := common.Unmarshal([]byte(data), &zhipuResponse)
if err != nil {
common.SysLog("error unmarshalling stream response: " + err.Error())
return true
}
response, zhipuUsage := streamMetaResponseZhipu2OpenAI(&zhipuResponse)
jsonResponse, err := json.Marshal(response)
jsonResponse, err := common.Marshal(response)
if err != nil {
common.SysLog("error marshalling stream response: " + err.Error())
return true
@@ -226,7 +225,7 @@ func zhipuHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respon
return nil, types.NewOpenAIError(err, types.ErrorCodeReadResponseBodyFailed, http.StatusInternalServerError)
}
service.CloseResponseBodyGracefully(resp)
err = json.Unmarshal(responseBody, &zhipuResponse)
err = common.Unmarshal(responseBody, &zhipuResponse)
if err != nil {
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
@@ -237,7 +236,7 @@ func zhipuHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respon
}, resp.StatusCode)
}
fullTextResponse := responseZhipu2OpenAI(&zhipuResponse)
jsonResponse, err := json.Marshal(fullTextResponse)
jsonResponse, err := common.Marshal(fullTextResponse)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
+5 -5
View File
@@ -1,21 +1,21 @@
package helper
import (
"encoding/json"
"errors"
"fmt"
"strings"
"github.com/heicode/manager/common"
"github.com/heicode/manager/dto"
"github.com/heicode/manager/relay/common"
relaycommon "github.com/heicode/manager/relay/common"
relayconstant "github.com/heicode/manager/relay/constant"
"github.com/heicode/manager/setting/ratio_setting"
"github.com/gin-gonic/gin"
)
func ModelMappedHelper(c *gin.Context, info *common.RelayInfo, request dto.Request) error {
func ModelMappedHelper(c *gin.Context, info *relaycommon.RelayInfo, request dto.Request) error {
if info.ChannelMeta == nil {
info.ChannelMeta = &common.ChannelMeta{}
info.ChannelMeta = &relaycommon.ChannelMeta{}
}
isResponsesCompact := info.RelayMode == relayconstant.RelayModeResponsesCompact
@@ -29,7 +29,7 @@ func ModelMappedHelper(c *gin.Context, info *common.RelayInfo, request dto.Reque
modelMapping := c.GetString("model_mapping")
if modelMapping != "" && modelMapping != "{}" {
modelMap := make(map[string]string)
err := json.Unmarshal([]byte(modelMapping), &modelMap)
err := common.Unmarshal([]byte(modelMapping), &modelMap)
if err != nil {
return fmt.Errorf("unmarshal_model_mapping_failed")
}
+3 -2
View File
@@ -40,8 +40,9 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon
return
}
// 无条件新建 StreamStatus
info.StreamStatus = relaycommon.NewStreamStatus()
if info.StreamStatus == nil {
info.StreamStatus = relaycommon.NewStreamStatus()
}
// 确保响应体总是被关闭
defer func() {
+1 -2
View File
@@ -1,7 +1,6 @@
package helper
import (
"encoding/json"
"errors"
"fmt"
"math"
@@ -156,7 +155,7 @@ func GetAndValidOpenAIImageRequest(c *gin.Context, relayMode int) (*dto.ImageReq
imageRequest.Quality = formData.Get("quality")
imageRequest.Size = formData.Get("size")
if imageValue := formData.Get("image"); imageValue != "" {
imageRequest.Image, _ = json.Marshal(imageValue)
imageRequest.Image, _ = common.Marshal(imageValue)
}
if imageRequest.Model == "gpt-image-1" {
+8 -9
View File
@@ -2,7 +2,6 @@ package relay
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
@@ -115,7 +114,7 @@ func RelayMidjourneyNotify(c *gin.Context) *dto.MidjourneyResponse {
midjourneyTask.FinishTime = midjRequest.FinishTime
midjourneyTask.ImageUrl = midjRequest.ImageUrl
midjourneyTask.VideoUrl = midjRequest.VideoUrl
videoUrlsStr, _ := json.Marshal(midjRequest.VideoUrls)
videoUrlsStr, _ := common.Marshal(midjRequest.VideoUrls)
midjourneyTask.VideoUrls = string(videoUrlsStr)
midjourneyTask.Status = midjRequest.Status
midjourneyTask.FailReason = midjRequest.FailReason
@@ -157,21 +156,21 @@ func coverMidjourneyTaskDto(c *gin.Context, originTask *model.Midjourney) (midjo
midjourneyTask.Prompt = originTask.Prompt
if originTask.Buttons != "" {
var buttons []dto.ActionButton
err := json.Unmarshal([]byte(originTask.Buttons), &buttons)
err := common.Unmarshal([]byte(originTask.Buttons), &buttons)
if err == nil {
midjourneyTask.Buttons = buttons
}
}
if originTask.VideoUrls != "" {
var videoUrls []dto.ImgUrls
err := json.Unmarshal([]byte(originTask.VideoUrls), &videoUrls)
err := common.Unmarshal([]byte(originTask.VideoUrls), &videoUrls)
if err == nil {
midjourneyTask.VideoUrls = videoUrls
}
}
if originTask.Properties != "" {
var properties dto.Properties
err := json.Unmarshal([]byte(originTask.Properties), &properties)
err := common.Unmarshal([]byte(originTask.Properties), &properties)
if err == nil {
midjourneyTask.Properties = &properties
}
@@ -271,7 +270,7 @@ func RelaySwapFace(c *gin.Context, info *relaycommon.RelayInfo) *dto.MidjourneyR
return service.MidjourneyErrorWrapper(constant.MjRequestError, "insert_midjourney_task_failed")
}
c.Writer.WriteHeader(mjResp.StatusCode)
respBody, err := json.Marshal(midjResponse)
respBody, err := common.Marshal(midjResponse)
if err != nil {
return service.MidjourneyErrorWrapper(constant.MjRequestError, "unmarshal_response_body_failed")
}
@@ -307,7 +306,7 @@ func RelayMidjourneyTaskImageSeed(c *gin.Context) *dto.MidjourneyResponse {
}
midjResponse := &midjResponseWithStatus.Response
c.Writer.WriteHeader(midjResponseWithStatus.StatusCode)
respBody, err := json.Marshal(midjResponse)
respBody, err := common.Marshal(midjResponse)
if err != nil {
return service.MidjourneyErrorWrapper(constant.MjRequestError, "unmarshal_response_body_failed")
}
@@ -330,7 +329,7 @@ func RelayMidjourneyTask(c *gin.Context, relayMode int) *dto.MidjourneyResponse
}
}
midjourneyTask := coverMidjourneyTaskDto(c, originTask)
respBody, err = json.Marshal(midjourneyTask)
respBody, err = common.Marshal(midjourneyTask)
if err != nil {
return &dto.MidjourneyResponse{
Code: 4,
@@ -359,7 +358,7 @@ func RelayMidjourneyTask(c *gin.Context, relayMode int) *dto.MidjourneyResponse
if tasks == nil {
tasks = make([]dto.MidjourneyDto, 0)
}
respBody, err = json.Marshal(tasks)
respBody, err = common.Marshal(tasks)
if err != nil {
return &dto.MidjourneyResponse{
Code: 4,
+1 -2
View File
@@ -5,7 +5,6 @@ import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -310,7 +309,7 @@ func decodeJWTClaims(token string) (map[string]any, bool) {
return nil, false
}
var claims map[string]any
if err := json.Unmarshal(payloadRaw, &claims); err != nil {
if err := common.Unmarshal(payloadRaw, &claims); err != nil {
return nil, false
}
return claims, true
+5 -6
View File
@@ -1,7 +1,6 @@
package service
import (
"encoding/json"
"fmt"
"strings"
@@ -36,7 +35,7 @@ func ClaudeToOpenAIRequest(claudeRequest dto.ClaudeRequest, info *relaycommon.Re
if isOpenRouter {
if effort := claudeRequest.GetEfforts(); effort != "" {
effortBytes, _ := json.Marshal(effort)
effortBytes, _ := common.Marshal(effort)
openAIRequest.Verbosity = effortBytes
}
if claudeRequest.Thinking != nil {
@@ -51,7 +50,7 @@ func ClaudeToOpenAIRequest(claudeRequest dto.ClaudeRequest, info *relaycommon.Re
Enabled: true,
}
}
reasoningJSON, err := json.Marshal(reasoning)
reasoningJSON, err := common.Marshal(reasoning)
if err != nil {
return nil, fmt.Errorf("failed to marshal reasoning: %w", err)
}
@@ -648,7 +647,7 @@ func stopReasonOpenAI2Claude(reason string) string {
}
func toJSONString(v interface{}) string {
b, err := json.Marshal(v)
b, err := common.Marshal(v)
if err != nil {
return "{}"
}
@@ -870,7 +869,7 @@ func ResponseOpenAI2Gemini(openAIResponse *dto.OpenAITextResponse, info *relayco
// 解析参数
var args map[string]interface{}
if toolCall.Function.Arguments != "" {
if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &args); err != nil {
if err := common.Unmarshal([]byte(toolCall.Function.Arguments), &args); err != nil {
args = map[string]interface{}{"arguments": toolCall.Function.Arguments}
}
} else {
@@ -973,7 +972,7 @@ func StreamResponseOpenAI2Gemini(openAIResponse *dto.ChatCompletionsStreamRespon
// 解析参数
var args map[string]interface{}
if toolCall.Function.Arguments != "" {
if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &args); err != nil {
if err := common.Unmarshal([]byte(toolCall.Function.Arguments), &args); err != nil {
args = map[string]interface{}{"arguments": toolCall.Function.Arguments}
}
} else {
+1 -1
View File
@@ -41,7 +41,7 @@ func DoWorkerRequest(req *WorkerRequest) (*http.Response, error) {
}
// 序列化worker请求数据
workerPayload, err := json.Marshal(req)
workerPayload, err := common.Marshal(req)
if err != nil {
return nil, fmt.Errorf("failed to marshal worker payload: %v", err)
}
+4 -5
View File
@@ -2,7 +2,6 @@ package service
import (
"context"
"encoding/json"
"io"
"log"
"net/http"
@@ -170,7 +169,7 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
var mapResult map[string]interface{}
// if get request, no need to read request body
if c.Request.Method != "GET" {
err := json.NewDecoder(c.Request.Body).Decode(&mapResult)
err := common.DecodeJson(c.Request.Body, &mapResult)
if err != nil {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "read_request_body_failed", http.StatusInternalServerError), nullBytes, err
}
@@ -192,7 +191,7 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
mapResult["prompt"] = prompt
}
}
reqBody, err := json.Marshal(mapResult)
reqBody, err := common.Marshal(mapResult)
if err != nil {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "marshal_request_body_failed", http.StatusInternalServerError), nullBytes, err
}
@@ -240,9 +239,9 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
if respStr == "" {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "empty_response_body", statusCode), responseBody, nil
} else {
err = json.Unmarshal(responseBody, &midjResponse)
err = common.Unmarshal(responseBody, &midjResponse)
if err != nil {
err2 := json.Unmarshal(responseBody, &midjourneyUploadsResponse)
err2 := common.Unmarshal(responseBody, &midjourneyUploadsResponse)
if err2 != nil {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "unmarshal_response_body_failed", statusCode), responseBody, err
}
+5 -4
View File
@@ -1,9 +1,10 @@
package passkey
import (
"encoding/json"
"errors"
"github.com/heicode/manager/common"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
webauthn "github.com/go-webauthn/webauthn/webauthn"
@@ -17,7 +18,7 @@ func SaveSessionData(c *gin.Context, key string, data *webauthn.SessionData) err
session.Delete(key)
return session.Save()
}
payload, err := json.Marshal(data)
payload, err := common.Marshal(data)
if err != nil {
return err
}
@@ -36,11 +37,11 @@ func PopSessionData(c *gin.Context, key string) (*webauthn.SessionData, error) {
var data webauthn.SessionData
switch value := raw.(type) {
case string:
if err := json.Unmarshal([]byte(value), &data); err != nil {
if err := common.Unmarshal([]byte(value), &data); err != nil {
return nil, err
}
case []byte:
if err := json.Unmarshal(value, &data); err != nil {
if err := common.Unmarshal(value, &data); err != nil {
return nil, err
}
default:
+1 -2
View File
@@ -2,7 +2,6 @@ package service
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
@@ -215,7 +214,7 @@ func sendGotifyNotify(gotifyUrl string, gotifyToken string, priority int, data d
}
// 序列化为 JSON
payloadBytes, err := json.Marshal(payload)
payloadBytes, err := common.Marshal(payload)
if err != nil {
return fmt.Errorf("failed to marshal gotify payload: %v", err)
}
+1 -2
View File
@@ -5,7 +5,6 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"net/http"
"time"
@@ -49,7 +48,7 @@ func SendWebhookNotify(webhookURL string, secret string, data dto.Notify) error
}
// 序列化负载
payloadBytes, err := json.Marshal(payload)
payloadBytes, err := common.Marshal(payload)
if err != nil {
return fmt.Errorf("failed to marshal webhook payload: %v", err)
}
+2 -4
View File
@@ -1,8 +1,6 @@
package setting
import (
"encoding/json"
"github.com/heicode/manager/common"
)
@@ -38,11 +36,11 @@ var Chats = []map[string]string{
func UpdateChatsByJsonString(jsonString string) error {
Chats = make([]map[string]string, 0)
return json.Unmarshal([]byte(jsonString), &Chats)
return common.Unmarshal([]byte(jsonString), &Chats)
}
func Chats2JsonString() string {
jsonBytes, err := json.Marshal(Chats)
jsonBytes, err := common.Marshal(Chats)
if err != nil {
common.SysLog("error marshalling chats: " + err.Error())
return "[]"
+6 -7
View File
@@ -1,7 +1,6 @@
package config
import (
"encoding/json"
"reflect"
"strconv"
"strings"
@@ -134,7 +133,7 @@ func configToMap(config interface{}) (map[string]string, error) {
case reflect.Ptr:
// 处理指针类型:如果非 nil,序列化指向的值
if !field.IsNil() {
bytes, err := json.Marshal(field.Interface())
bytes, err := common.Marshal(field.Interface())
if err != nil {
return nil, err
}
@@ -145,7 +144,7 @@ func configToMap(config interface{}) (map[string]string, error) {
}
case reflect.Map, reflect.Slice, reflect.Struct:
// 复杂类型使用JSON序列化
bytes, err := json.Marshal(field.Interface())
bytes, err := common.Marshal(field.Interface())
if err != nil {
return nil, err
}
@@ -247,22 +246,22 @@ func updateConfigFromMap(config interface{}, configMap map[string]string) error
field.Set(reflect.New(field.Type().Elem()))
}
// 反序列化到指针指向的值
err := json.Unmarshal([]byte(strValue), field.Interface())
err := common.Unmarshal([]byte(strValue), field.Interface())
if err != nil {
continue
}
}
case reflect.Map:
// json.Unmarshal merges into existing maps (keeps old keys that are
// common.Unmarshal merges into existing maps (keeps old keys that are
// absent from the new JSON). Allocate a fresh map so removed keys
// are properly cleared.
fresh := reflect.New(field.Type())
if err := json.Unmarshal([]byte(strValue), fresh.Interface()); err != nil {
if err := common.Unmarshal([]byte(strValue), fresh.Interface()); err != nil {
continue
}
field.Set(fresh.Elem())
case reflect.Slice, reflect.Struct:
err := json.Unmarshal([]byte(strValue), field.Addr().Interface())
err := common.Unmarshal([]byte(strValue), field.Addr().Interface())
if err != nil {
continue
}
@@ -1,13 +1,14 @@
package console_setting
import (
"encoding/json"
"fmt"
"net/url"
"regexp"
"sort"
"strings"
"time"
"github.com/heicode/manager/common"
)
var (
@@ -24,7 +25,7 @@ var (
func parseJSONArray(jsonStr string, typeName string) ([]map[string]interface{}, error) {
var list []map[string]interface{}
if err := json.Unmarshal([]byte(jsonStr), &list); err != nil {
if err := common.Unmarshal([]byte(jsonStr), &list); err != nil {
return nil, fmt.Errorf("%s格式错误:%s", typeName, err.Error())
}
return list, nil
@@ -55,7 +56,7 @@ func getJSONList(jsonStr string) []map[string]interface{} {
return []map[string]interface{}{}
}
var list []map[string]interface{}
json.Unmarshal([]byte(jsonStr), &list)
common.Unmarshal([]byte(jsonStr), &list)
return list
}
+3 -4
View File
@@ -1,7 +1,6 @@
package setting
import (
"encoding/json"
"fmt"
"math"
"sync"
@@ -20,7 +19,7 @@ func ModelRequestRateLimitGroup2JSONString() string {
ModelRequestRateLimitMutex.RLock()
defer ModelRequestRateLimitMutex.RUnlock()
jsonBytes, err := json.Marshal(ModelRequestRateLimitGroup)
jsonBytes, err := common.Marshal(ModelRequestRateLimitGroup)
if err != nil {
common.SysLog("error marshalling model ratio: " + err.Error())
}
@@ -32,7 +31,7 @@ func UpdateModelRequestRateLimitGroupByJSONString(jsonStr string) error {
defer ModelRequestRateLimitMutex.RUnlock()
ModelRequestRateLimitGroup = make(map[string][2]int)
return json.Unmarshal([]byte(jsonStr), &ModelRequestRateLimitGroup)
return common.Unmarshal([]byte(jsonStr), &ModelRequestRateLimitGroup)
}
func GetGroupRateLimit(group string) (totalCount, successCount int, found bool) {
@@ -52,7 +51,7 @@ func GetGroupRateLimit(group string) (totalCount, successCount int, found bool)
func CheckModelRequestRateLimitGroup(jsonStr string) error {
checkModelRequestRateLimitGroup := make(map[string][2]int)
err := json.Unmarshal([]byte(jsonStr), &checkModelRequestRateLimitGroup)
err := common.Unmarshal([]byte(jsonStr), &checkModelRequestRateLimitGroup)
if err != nil {
return err
}
+1 -2
View File
@@ -1,7 +1,6 @@
package ratio_setting
import (
"encoding/json"
"errors"
"github.com/heicode/manager/common"
@@ -112,7 +111,7 @@ func UpdateGroupGroupRatioByJSONString(jsonStr string) error {
func CheckGroupRatio(jsonStr string) error {
checkGroupRatio := make(map[string]float64)
err := json.Unmarshal([]byte(jsonStr), &checkGroupRatio)
err := common.Unmarshal([]byte(jsonStr), &checkGroupRatio)
if err != nil {
return err
}
+2 -3
View File
@@ -1,7 +1,6 @@
package setting
import (
"encoding/json"
"sync"
"github.com/heicode/manager/common"
@@ -28,7 +27,7 @@ func UserUsableGroups2JSONString() string {
userUsableGroupsMutex.RLock()
defer userUsableGroupsMutex.RUnlock()
jsonBytes, err := json.Marshal(userUsableGroups)
jsonBytes, err := common.Marshal(userUsableGroups)
if err != nil {
common.SysLog("error marshalling user groups: " + err.Error())
}
@@ -40,7 +39,7 @@ func UpdateUserUsableGroupsByJSONString(jsonStr string) error {
defer userUsableGroupsMutex.Unlock()
userUsableGroups = make(map[string]string)
return json.Unmarshal([]byte(jsonStr), &userUsableGroups)
return common.Unmarshal([]byte(jsonStr), &userUsableGroups)
}
func GetUsableGroupDescription(groupName string) string {