Compare commits

..

53 Commits

Author SHA1 Message Date
Calcium-Ion
b19b2d62df Merge pull request #2339 from QuantumNous/revert-2330-pr/fix-nano-banana-err
Revert "fix: nano-banana not compatible imageSize"
2025-11-30 18:48:09 +08:00
Calcium-Ion
f9c8624f2c Merge pull request #2338 from QuantumNous/revert-2321-pr/gemini-image-edit
Revert "Gemini Image系列支持图像编辑"
2025-11-30 18:48:01 +08:00
Calcium-Ion
6c8253156b Merge pull request #2337 from QuantumNous/revert-2315-pr/gemini-veo3.1-i2v
Revert "Gemini Veo3.1[AI Studio]增加图生视频支持"
2025-11-30 18:47:50 +08:00
Calcium-Ion
a66b314f5b Merge pull request #2336 from QuantumNous/revert-2309-pr/fix-gemini-ImageConfig
Revert "fix: gemini image correct generationConfig"
2025-11-30 18:47:39 +08:00
Seefs
e29ff0060d Revert "fix: nano-banana not compatible imageSize" 2025-11-30 18:46:10 +08:00
Seefs
d4a2c2ab54 Revert "Gemini Image系列支持图像编辑" 2025-11-30 18:45:54 +08:00
Seefs
ded463ee57 Revert "Gemini Veo3.1[AI Studio]增加图生视频支持" 2025-11-30 18:45:37 +08:00
Seefs
e337936227 Revert "fix: gemini image correct generationConfig" 2025-11-30 18:45:23 +08:00
Seefs
8d0827cb9e Merge pull request #2314 from seefs001/fix/i18n-missing
fix(i18n): fill missing translations in i18n.
2025-11-30 16:31:52 +08:00
Calcium-Ion
c07331ee21 Merge pull request #2304 from seefs001/fix/claude-missing-field
fix: claude request missing field
2025-11-30 16:22:35 +08:00
Calcium-Ion
287a59e2fd fix: edit vertex key type (#2311) 2025-11-30 16:21:49 +08:00
Seefs
451c594e34 Merge pull request #2334 from seefs001/feature/glm-coding
feat: glm coding plan && kimi coding plan
2025-11-30 16:21:12 +08:00
Calcium-Ion
46a18c4658 Merge pull request #2335 from seefs001/fix/nano-banana-pro-4k
fix: nano banana pro 4k(StreamScannerMaxBufferMB env)
2025-11-30 16:20:46 +08:00
Calcium-Ion
d5cb53154f Merge pull request #2312 from ImogeneOctaviap794/feat/enhance-playground-debugging
feat(playground): enhance SSE debugging and add image paste support with i18n
2025-11-30 16:20:39 +08:00
Seefs
2b54e5fc53 Merge pull request #2330 from feitianbubu/pr/fix-nano-banana-err
fix: nano-banana not compatible imageSize
2025-11-30 16:18:20 +08:00
Seefs
2520c8b25d fix: nano banana pro 4k(StreamScannerMaxBufferMB env) 2025-11-30 16:08:25 +08:00
Seefs
590745b846 Merge pull request #2329 from mfzzf/fix/aws-anthropic-http-err-code
fix(aws): extract HTTP status code from AWS SDK errors
2025-11-29 15:19:01 +08:00
feitianbubu
77eb536b69 fix: nano-banana not compatible imageSize 2025-11-29 00:58:25 +08:00
jason.mei
c6a8e4c252 fix(aws): simplify HTTP status code extraction from AWS errors 2025-11-28 18:03:53 +08:00
jason.mei
f2e51963dc fix(aws): extract HTTP status code from AWS SDK errors 2025-11-28 17:43:37 +08:00
IcedTangerine
fa72a27a59 Merge pull request #2324 from feitianbubu/pr/video-download-oai
feat: 视频下载和界面预览统一使用OAI标准接口
2025-11-28 17:03:39 +08:00
feitianbubu
2a77453e1a feat: all video preview use videos/:id/content 2025-11-28 13:11:31 +08:00
IcedTangerine
b47cf4efb3 Merge pull request #2321 from feitianbubu/pr/gemini-image-edit
Gemini Image系列支持图像编辑
2025-11-27 18:04:50 +08:00
IcedTangerine
420c6e58f2 Fix defer placement for image file closure 2025-11-27 18:01:34 +08:00
IcedTangerine
4d00dad002 Fix error message formatting in relay_utils.go 2025-11-27 17:59:38 +08:00
IcedTangerine
a0982996a4 Use defer to close image file after opening
Ensure image file is closed using defer after opening.
2025-11-27 17:56:59 +08:00
IcedTangerine
36cf515617 Merge pull request #2315 from feitianbubu/pr/gemini-veo3.1-i2v
Gemini Veo3.1[AI Studio]增加图生视频支持
2025-11-27 17:24:13 +08:00
feitianbubu
cb5a37abed feat: gemini image support edit 2025-11-27 16:04:04 +08:00
feitianbubu
f7d6c36032 feat: gemini video veo3.1 add task fail check 2025-11-26 21:56:14 +08:00
feitianbubu
4a367edfde feat: gemini video veo3.1 add i2v 2025-11-26 21:56:13 +08:00
ImogeneOctaviap794
9140dee70c feat(playground): enhance SSE debugging and add image paste support with i18n
- Add SSEViewer component for interactive SSE message inspection
  * Display SSE data stream with collapsible panels
  * Show parsed JSON with syntax highlighting
  * Display key information badges (content, tokens, finish reason)
  * Support copy individual or all SSE messages
  * Show error messages with detailed information

- Support Ctrl+V to paste images in chat input
  * Enable image paste in CustomInputRender component
  * Auto-detect and add pasted images to image list
  * Show toast notifications for paste results

- Add complete i18n support for 6 languages
  * Chinese (zh): Complete translations
  * English (en): Complete translations
  * Japanese (ja): Add 28 new translations
  * French (fr): Add 28 new translations
  * Russian (ru): Add 28 new translations
  * Vietnamese (vi): Add 32 new translations

- Update .gitignore to exclude data directory
2025-11-26 20:40:32 +08:00
Calcium-Ion
95a7749e1d Merge pull request #2309 from feitianbubu/pr/fix-gemini-ImageConfig
fix: gemini image correct generationConfig
2025-11-26 18:46:06 +08:00
Seefs
a25d00bace fix: edit vertex key type 2025-11-26 18:12:36 +08:00
feitianbubu
ab3cda3202 fix: gemini image correct generationConfig 2025-11-26 15:54:11 +08:00
IcedTangerine
5ac1d02200 Merge pull request #2305 from feitianbubu/pr/add-gemini-3-pro-image-preview-oai
OAI生图接口支持gemini 3 pro image preview
2025-11-26 13:35:17 +08:00
feitianbubu
d859872e0d feat: gemini-3-pro-image-preview add extra param 2025-11-26 12:03:24 +08:00
feitianbubu
bff04514a8 feat: support gemini-3-pro-image-preview via images/generations 2025-11-26 12:03:24 +08:00
Seefs
dab5fad61e fix: claude request missing field 2025-11-26 02:06:25 +08:00
Seefs
a6a20a2069 Merge pull request #2296 from seefs001/fix/adapter-missing
fix: volcengine claude DoResponse
2025-11-25 16:45:14 +08:00
Calcium-Ion
4866b3db13 Merge pull request #2295 from seefs001/fix/adapter-missing
fix: volcengine claude DoResponse
2025-11-25 15:54:39 +08:00
Seefs
5060904331 fix: volcengine claude DoResponse 2025-11-25 15:45:31 +08:00
Calcium-Ion
393c2b620c Merge pull request #2294 from seefs001/fix/adapter-missing
fix: volcengine && baidu claude adapter
2025-11-25 15:31:26 +08:00
Seefs
e5e3e0f201 fix: volcengine && baidu claude adapter 2025-11-25 15:06:03 +08:00
Seefs
b3d5fbd9f2 Merge pull request #2282 from amikebzek/claude/analyze-gemini-integration-011nJGemhrPUdqwg3qDvmqVB
feat: enable thoughtSignature for non-function-call messages
2025-11-25 14:50:55 +08:00
Seefs
31a652f8e2 Merge pull request #2293 from prnake/claude-opus-4-5
feat: add claude-opus-4-5-20251101
2025-11-25 14:44:57 +08:00
Papersnake
79682dc542 feat: add claude-opus-4-5-20251101 2025-11-25 10:53:01 +08:00
Papersnake
5931d333cb feat: add claude-opus-4-5-20251101 ratio 2025-11-25 10:49:34 +08:00
Seefs
2f80e3fba1 Merge pull request #2261 from wzxjohn/hotfix/analytic
fix: root page does not have analytic code
2025-11-24 14:06:02 +08:00
Seefs
bd9e23ce4e Merge pull request #2264 from binorxin/main
fix: cast size to int64 before comparing with MaxUint32
2025-11-24 14:05:14 +08:00
Claude
25aed08361 feat: enable thoughtSignature for non-function-call messages
Previously thoughtSignature was only attached to messages with function
calls. This change extends the feature to also attach thoughtSignature
to the first text part of assistant/model messages when no tool_calls
are present, ensuring compatibility with Gemini thinking models in
regular conversation scenarios.
2025-11-24 00:31:20 +00:00
borx
182f3a9b4d fix: cast size to int64 before comparing with MaxUint32 2025-11-20 23:57:30 +08:00
wzxjohn
2a62aea46c fix: typo 2025-10-30 14:21:46 +08:00
wzxjohn
4a0c119140 fix(web): index page does not have analytic 2025-10-30 12:17:51 +08:00
54 changed files with 1562 additions and 337 deletions

1
.gitignore vendored
View File

@@ -21,3 +21,4 @@ web/bun.lock
electron/node_modules
electron/dist
data/

View File

@@ -303,6 +303,7 @@ docker run --name new-api -d --restart always \
| `SQL_DSN` | Database connection string | - |
| `REDIS_CONN_STRING` | Redis connection string | - |
| `STREAMING_TIMEOUT` | Streaming timeout (seconds) | `300` |
| `STREAM_SCANNER_MAX_BUFFER_MB` | Max per-line buffer (MB) for the stream scanner; increase when upstream sends huge image/base64 payloads | `64` |
| `AZURE_DEFAULT_API_VERSION` | Azure API version | `2025-04-01-preview` |
| `ERROR_LOG_ENABLED` | Error log switch | `false` |

View File

@@ -299,6 +299,7 @@ docker run --name new-api -d --restart always \
| `SQL_DSN` | Chaine de connexion à la base de données | - |
| `REDIS_CONN_STRING` | Chaine de connexion Redis | - |
| `STREAMING_TIMEOUT` | Délai d'expiration du streaming (secondes) | `300` |
| `STREAM_SCANNER_MAX_BUFFER_MB` | Taille max du buffer par ligne (Mo) pour le scanner SSE ; à augmenter quand les sorties image/base64 sont très volumineuses (ex. images 4K) | `64` |
| `AZURE_DEFAULT_API_VERSION` | Version de l'API Azure | `2025-04-01-preview` |
| `ERROR_LOG_ENABLED` | Interrupteur du journal d'erreurs | `false` |
@@ -438,4 +439,4 @@ Si ce projet vous est utile, bienvenue à nous donner une ⭐️ Étoile
<sub>Construit avec ❤️ par QuantumNous</sub>
</div>
</div>

View File

@@ -308,6 +308,7 @@ docker run --name new-api -d --restart always \
| `SQL_DSN** | データベース接続文字列 | - |
| `REDIS_CONN_STRING` | Redis接続文字列 | - |
| `STREAMING_TIMEOUT` | ストリーミング応答のタイムアウト時間(秒) | `300` |
| `STREAM_SCANNER_MAX_BUFFER_MB` | ストリームスキャナの1行あたりバッファ上限MB。4K画像など巨大なbase64 `data:` ペイロードを扱う場合は値を増加させてください | `64` |
| `AZURE_DEFAULT_API_VERSION` | Azure APIバージョン | `2025-04-01-preview` |
| `ERROR_LOG_ENABLED` | エラーログスイッチ | `false` |

View File

@@ -297,15 +297,16 @@ docker run --name new-api -d --restart always \
<details>
<summary>常用环境变量配置</summary>
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `SESSION_SECRET` | 会话密钥(多机部署必须) | - |
| `CRYPTO_SECRET` | 加密密钥Redis 必须) | - |
| `SQL_DSN` | 数据库连接字符串 | - |
| `REDIS_CONN_STRING` | Redis 连接字符串 | - |
| `STREAMING_TIMEOUT` | 流式超时时间(秒) | `300` |
| `AZURE_DEFAULT_API_VERSION` | Azure API 版本 | `2025-04-01-preview` |
| `ERROR_LOG_ENABLED` | 错误日志开关 | `false` |
| 变量名 | 说明 | 默认值 |
|--------|--------------------------------------------------------------|--------|
| `SESSION_SECRET` | 会话密钥(多机部署必须) | - |
| `CRYPTO_SECRET` | 加密密钥Redis 必须) | - |
| `SQL_DSN` | 数据库连接字符串 | - |
| `REDIS_CONN_STRING` | Redis 连接字符串 | - |
| `STREAMING_TIMEOUT` | 流式超时时间(秒) | `300` |
| `STREAM_SCANNER_MAX_BUFFER_MB` | 流式扫描器单行最大缓冲MB图像生成等超大 `data:` 片段(如 4K 图片 base64需适当调大 | `64` |
| `AZURE_DEFAULT_API_VERSION` | Azure API 版本 | `2025-04-01-preview` |
| `ERROR_LOG_ENABLED` | 错误日志开关 | `false` |
📖 **完整配置:** [环境变量文档](https://docs.newapi.pro/installation/environment-variables)

View File

@@ -4,6 +4,7 @@ import (
"embed"
"io/fs"
"net/http"
"os"
"github.com/gin-contrib/static"
)
@@ -14,7 +15,7 @@ type embedFileSystem struct {
http.FileSystem
}
func (e embedFileSystem) Exists(prefix string, path string) bool {
func (e *embedFileSystem) Exists(prefix string, path string) bool {
_, err := e.Open(path)
if err != nil {
return false
@@ -22,12 +23,21 @@ func (e embedFileSystem) Exists(prefix string, path string) bool {
return true
}
func (e *embedFileSystem) Open(name string) (http.File, error) {
if name == "/" {
// This will make sure the index page goes to NoRouter handler,
// which will use the replaced index bytes with analytic codes.
return nil, os.ErrNotExist
}
return e.FileSystem.Open(name)
}
func EmbedFolder(fsEmbed embed.FS, targetPath string) static.ServeFileSystem {
efs, err := fs.Sub(fsEmbed, targetPath)
if err != nil {
panic(err)
}
return embedFileSystem{
return &embedFileSystem{
FileSystem: http.FS(efs),
}
}

View File

@@ -114,6 +114,7 @@ func initConstantEnv() {
constant.StreamingTimeout = GetEnvOrDefault("STREAMING_TIMEOUT", 300)
constant.DifyDebug = GetEnvOrDefaultBool("DIFY_DEBUG", true)
constant.MaxFileDownloadMB = GetEnvOrDefault("MAX_FILE_DOWNLOAD_MB", 20)
constant.StreamScannerMaxBufferMB = GetEnvOrDefault("STREAM_SCANNER_MAX_BUFFER_MB", 64)
// ForceStreamOption 覆盖请求参数强制返回usage信息
constant.ForceStreamOption = GetEnvOrDefaultBool("FORCE_STREAM_OPTION", true)
constant.CountToken = GetEnvOrDefaultBool("CountToken", true)

View File

@@ -180,3 +180,27 @@ func GetChannelTypeName(channelType int) string {
}
return "Unknown"
}
type ChannelSpecialBase struct {
ClaudeBaseURL string
OpenAIBaseURL string
}
var ChannelSpecialBases = map[string]ChannelSpecialBase{
"glm-coding-plan": {
ClaudeBaseURL: "https://open.bigmodel.cn/api/anthropic",
OpenAIBaseURL: "https://open.bigmodel.cn/api/coding/paas/v4",
},
"glm-coding-plan-international": {
ClaudeBaseURL: "https://api.z.ai/api/anthropic",
OpenAIBaseURL: "https://api.z.ai/api/coding/paas/v4",
},
"kimi-coding-plan": {
ClaudeBaseURL: "https://api.kimi.com/coding",
OpenAIBaseURL: "https://api.kimi.com/coding/v1",
},
"doubao-coding-plan": {
ClaudeBaseURL: "https://ark.cn-beijing.volces.com/api/coding",
OpenAIBaseURL: "https://ark.cn-beijing.volces.com/api/coding/v3",
},
}

View File

@@ -3,6 +3,7 @@ package constant
var StreamingTimeout int
var DifyDebug bool
var MaxFileDownloadMB int
var StreamScannerMaxBufferMB int
var ForceStreamOption bool
var CountToken bool
var GetMediaToken bool

View File

@@ -11,7 +11,6 @@ import (
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/model"
"github.com/QuantumNous/new-api/relay/channel/volcengine"
"github.com/QuantumNous/new-api/service"
"github.com/gin-gonic/gin"
@@ -192,10 +191,20 @@ func FetchUpstreamModels(c *gin.Context) {
case constant.ChannelTypeAli:
url = fmt.Sprintf("%s/compatible-mode/v1/models", baseURL)
case constant.ChannelTypeZhipu_v4:
url = fmt.Sprintf("%s/api/paas/v4/models", baseURL)
if plan, ok := constant.ChannelSpecialBases[baseURL]; ok && plan.OpenAIBaseURL != "" {
url = fmt.Sprintf("%s/models", plan.OpenAIBaseURL)
} else {
url = fmt.Sprintf("%s/api/paas/v4/models", baseURL)
}
case constant.ChannelTypeVolcEngine:
if baseURL == volcengine.DoubaoCodingPlan {
url = fmt.Sprintf("%s/v1/models", volcengine.DoubaoCodingPlanOpenAIBaseURL)
if plan, ok := constant.ChannelSpecialBases[baseURL]; ok && plan.OpenAIBaseURL != "" {
url = fmt.Sprintf("%s/v1/models", plan.OpenAIBaseURL)
} else {
url = fmt.Sprintf("%s/v1/models", baseURL)
}
case constant.ChannelTypeMoonshot:
if plan, ok := constant.ChannelSpecialBases[baseURL]; ok && plan.OpenAIBaseURL != "" {
url = fmt.Sprintf("%s/models", plan.OpenAIBaseURL)
} else {
url = fmt.Sprintf("%s/v1/models", baseURL)
}

View File

@@ -117,13 +117,12 @@ func VideoProxy(c *gin.Context) {
return
}
req.Header.Set("x-goog-api-key", apiKey)
case constant.ChannelTypeAli:
// Video URL is directly in task.FailReason
videoURL = task.FailReason
default:
// Default (Sora, etc.): Use original logic
case constant.ChannelTypeOpenAI, constant.ChannelTypeSora:
videoURL = fmt.Sprintf("%s/v1/videos/%s/content", baseURL, task.TaskID)
req.Header.Set("Authorization", "Bearer "+channel.Key)
default:
// Video URL is directly in task.FailReason
videoURL = task.FailReason
}
req.URL, err = url.Parse(videoURL)

View File

@@ -203,6 +203,9 @@ type ClaudeRequest struct {
Stream bool `json:"stream,omitempty"`
Tools any `json:"tools,omitempty"`
ContextManagement json.RawMessage `json:"context_management,omitempty"`
OutputConfig json.RawMessage `json:"output_config,omitempty"`
OutputFormat json.RawMessage `json:"output_format,omitempty"`
Container json.RawMessage `json:"container,omitempty"`
ToolChoice any `json:"tool_choice,omitempty"`
Thinking *Thinking `json:"thinking,omitempty"`
McpServers json.RawMessage `json:"mcp_servers,omitempty"`

View File

@@ -169,7 +169,7 @@ type ImageResponse struct {
Extra any `json:"extra,omitempty"`
}
type ImageData struct {
Url string `json:"url"`
B64Json string `json:"b64_json"`
RevisedPrompt string `json:"revised_prompt"`
Url string `json:"url,omitempty"`
B64Json string `json:"b64_json,omitempty"`
RevisedPrompt string `json:"revised_prompt,omitempty"`
}

View File

@@ -18,6 +18,7 @@ var awsModelIDMap = map[string]string{
"claude-opus-4-1-20250805": "anthropic.claude-opus-4-1-20250805-v1:0",
"claude-sonnet-4-5-20250929": "anthropic.claude-sonnet-4-5-20250929-v1:0",
"claude-haiku-4-5-20251001": "anthropic.claude-haiku-4-5-20251001-v1:0",
"claude-opus-4-5-20251101": "anthropic.claude-opus-4-5-20251101-v1:0",
// Nova models
"nova-micro-v1:0": "amazon.nova-micro-v1:0",
"nova-lite-v1:0": "amazon.nova-lite-v1:0",
@@ -76,6 +77,11 @@ var awsModelCanCrossRegionMap = map[string]map[string]bool{
"ap": true,
"eu": true,
},
"anthropic.claude-opus-4-5-20251101-v1:0": {
"us": true,
"ap": true,
"eu": true,
},
"anthropic.claude-haiku-4-5-20251001-v1:0": {
"us": true,
"ap": true,

View File

@@ -25,6 +25,17 @@ import (
"github.com/aws/smithy-go/auth/bearer"
)
// getAwsErrorStatusCode extracts HTTP status code from AWS SDK error
func getAwsErrorStatusCode(err error) int {
// Check for HTTP response error which contains status code
var httpErr interface{ HTTPStatusCode() int }
if errors.As(err, &httpErr) {
return httpErr.HTTPStatusCode()
}
// Default to 500 if we can't determine the status code
return http.StatusInternalServerError
}
func newAwsClient(c *gin.Context, info *relaycommon.RelayInfo) (*bedrockruntime.Client, error) {
var (
httpClient *http.Client
@@ -173,7 +184,8 @@ func awsHandler(c *gin.Context, info *relaycommon.RelayInfo, a *Adaptor) (*types
awsResp, err := a.AwsClient.InvokeModel(c.Request.Context(), a.AwsReq.(*bedrockruntime.InvokeModelInput))
if err != nil {
return types.NewOpenAIError(errors.Wrap(err, "InvokeModel"), types.ErrorCodeAwsInvokeError, http.StatusInternalServerError), nil
statusCode := getAwsErrorStatusCode(err)
return types.NewOpenAIError(errors.Wrap(err, "InvokeModel"), types.ErrorCodeAwsInvokeError, statusCode), nil
}
claudeInfo := &claude.ClaudeResponseInfo{
@@ -199,7 +211,8 @@ func awsHandler(c *gin.Context, info *relaycommon.RelayInfo, a *Adaptor) (*types
func awsStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, a *Adaptor) (*types.NewAPIError, *dto.Usage) {
awsResp, err := a.AwsClient.InvokeModelWithResponseStream(c.Request.Context(), a.AwsReq.(*bedrockruntime.InvokeModelWithResponseStreamInput))
if err != nil {
return types.NewOpenAIError(errors.Wrap(err, "InvokeModelWithResponseStream"), types.ErrorCodeAwsInvokeError, http.StatusInternalServerError), nil
statusCode := getAwsErrorStatusCode(err)
return types.NewOpenAIError(errors.Wrap(err, "InvokeModelWithResponseStream"), types.ErrorCodeAwsInvokeError, statusCode), nil
}
stream := awsResp.GetStream()
defer stream.Close()
@@ -238,7 +251,8 @@ func handleNovaRequest(c *gin.Context, info *relaycommon.RelayInfo, a *Adaptor)
awsResp, err := a.AwsClient.InvokeModel(c.Request.Context(), a.AwsReq.(*bedrockruntime.InvokeModelInput))
if err != nil {
return types.NewError(errors.Wrap(err, "InvokeModel"), types.ErrorCodeChannelAwsClientError), nil
statusCode := getAwsErrorStatusCode(err)
return types.NewOpenAIError(errors.Wrap(err, "InvokeModel"), types.ErrorCodeAwsInvokeError, statusCode), nil
}
// 解析Nova响应

View File

@@ -21,6 +21,8 @@ var ModelList = []string{
"claude-opus-4-1-20250805-thinking",
"claude-sonnet-4-5-20250929",
"claude-sonnet-4-5-20250929-thinking",
"claude-opus-4-5-20251101",
"claude-opus-4-5-20251101-thinking",
}
var ChannelName = "claude"

View File

@@ -1,6 +1,7 @@
package gemini
import (
"encoding/json"
"errors"
"fmt"
"io"
@@ -55,9 +56,102 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf
return nil, errors.New("not implemented")
}
type ImageConfig struct {
AspectRatio string `json:"aspectRatio,omitempty"`
ImageSize string `json:"imageSize,omitempty"`
}
type SizeMapping struct {
AspectRatio string
ImageSize string
}
type QualityMapping struct {
Standard string
HD string
High string
FourK string
Auto string
}
func getImageSizeMapping() QualityMapping {
return QualityMapping{
Standard: "1K",
HD: "2K",
High: "2K",
FourK: "4K",
Auto: "1K",
}
}
func getSizeMappings() map[string]SizeMapping {
return map[string]SizeMapping{
"1536x1024": {AspectRatio: "3:2", ImageSize: ""},
"1024x1536": {AspectRatio: "2:3", ImageSize: ""},
"1024x1792": {AspectRatio: "9:16", ImageSize: ""},
"1792x1024": {AspectRatio: "16:9", ImageSize: ""},
"2048x2048": {AspectRatio: "", ImageSize: "2K"},
"4096x4096": {AspectRatio: "", ImageSize: "4K"},
}
}
func processSizeParameters(size, quality string) ImageConfig {
config := ImageConfig{} // 默认为空值
if size != "" {
if strings.Contains(size, ":") {
config.AspectRatio = size // 直接设置,不与默认值比较
} else {
if mapping, exists := getSizeMappings()[size]; exists {
if mapping.AspectRatio != "" {
config.AspectRatio = mapping.AspectRatio
}
if mapping.ImageSize != "" {
config.ImageSize = mapping.ImageSize
}
}
}
}
if quality != "" {
qualityMapping := getImageSizeMapping()
switch strings.ToLower(strings.TrimSpace(quality)) {
case "hd", "high":
config.ImageSize = qualityMapping.HD
case "4k":
config.ImageSize = qualityMapping.FourK
case "standard", "medium", "low", "auto", "1k":
config.ImageSize = qualityMapping.Standard
}
}
return config
}
func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.ImageRequest) (any, error) {
if !strings.HasPrefix(info.UpstreamModelName, "imagen") {
return nil, errors.New("not supported model for image generation")
if strings.HasPrefix(info.UpstreamModelName, "gemini-3-pro-image") {
chatRequest := dto.GeneralOpenAIRequest{
Model: request.Model,
Messages: []dto.Message{
{Role: "user", Content: request.Prompt},
},
N: int(request.N),
}
config := processSizeParameters(strings.TrimSpace(request.Size), request.Quality)
googleGenerationConfig := map[string]interface{}{
"response_modalities": []string{"TEXT", "IMAGE"},
"image_config": config,
}
extraBody := map[string]interface{}{
"google": map[string]interface{}{
"generation_config": googleGenerationConfig,
},
}
chatRequest.ExtraBody, _ = json.Marshal(extraBody)
return a.ConvertOpenAIRequest(c, info, &chatRequest)
}
// convert size to aspect ratio but allow user to specify aspect ratio
@@ -67,17 +161,8 @@ func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *relaycommon.RelayInf
if strings.Contains(size, ":") {
aspectRatio = size
} else {
switch size {
case "256x256", "512x512", "1024x1024":
aspectRatio = "1:1"
case "1536x1024":
aspectRatio = "3:2"
case "1024x1536":
aspectRatio = "2:3"
case "1024x1792":
aspectRatio = "9:16"
case "1792x1024":
aspectRatio = "16:9"
if mapping, exists := getSizeMappings()[size]; exists && mapping.AspectRatio != "" {
aspectRatio = mapping.AspectRatio
}
}
}
@@ -258,6 +343,10 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom
return GeminiImageHandler(c, info, resp)
}
if model_setting.IsGeminiModelSupportImagine(info.UpstreamModelName) {
return ChatImageHandler(c, info, resp)
}
// check if the model is an embedding model
if strings.HasPrefix(info.UpstreamModelName, "text-embedding") ||
strings.HasPrefix(info.UpstreamModelName, "embedding") ||

View File

@@ -484,6 +484,17 @@ func CovertOpenAI2Gemini(c *gin.Context, textRequest dto.GeneralOpenAIRequest, i
}
}
// 如果需要附加签名但还没有附加(没有 tool_calls 或 tool_calls 为空),
// 则在第一个文本 part 上附加 thoughtSignature
if shouldAttachThoughtSignature && !signatureAttached && len(parts) > 0 {
for i := range parts {
if parts[i].Text != "" {
parts[i].ThoughtSignature = json.RawMessage(strconv.Quote(thoughtSignatureBypassValue))
break
}
}
}
content.Parts = parts
// there's no assistant role in gemini and API shall vomit if Role is not user or model
@@ -1253,3 +1264,70 @@ func GeminiImageHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.
return usage, nil
}
func convertToOaiImageResponse(geminiResponse *dto.GeminiChatResponse) (*dto.ImageResponse, error) {
openAIResponse := &dto.ImageResponse{
Created: common.GetTimestamp(),
Data: make([]dto.ImageData, 0),
}
// extract images from candidates' inlineData
for _, candidate := range geminiResponse.Candidates {
for _, part := range candidate.Content.Parts {
if part.InlineData != nil && strings.HasPrefix(part.InlineData.MimeType, "image") {
openAIResponse.Data = append(openAIResponse.Data, dto.ImageData{
B64Json: part.InlineData.Data,
})
}
}
}
if len(openAIResponse.Data) == 0 {
return nil, errors.New("no images found in response")
}
return openAIResponse, nil
}
func ChatImageHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Response) (*dto.Usage, *types.NewAPIError) {
responseBody, readErr := io.ReadAll(resp.Body)
if readErr != nil {
return nil, types.NewOpenAIError(readErr, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
service.CloseResponseBodyGracefully(resp)
if common.DebugEnabled {
println("ChatImageHandler response:", string(responseBody))
}
var geminiResponse dto.GeminiChatResponse
if jsonErr := common.Unmarshal(responseBody, &geminiResponse); jsonErr != nil {
return nil, types.NewOpenAIError(jsonErr, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
if len(geminiResponse.Candidates) == 0 {
return nil, types.NewOpenAIError(errors.New("no images generated"), types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
openAIResponse, err := convertToOaiImageResponse(&geminiResponse)
if err != nil {
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
jsonResponse, jsonErr := json.Marshal(openAIResponse)
if jsonErr != nil {
return nil, types.NewError(jsonErr, types.ErrorCodeBadResponseBody)
}
c.Writer.Header().Set("Content-Type", "application/json")
c.Writer.WriteHeader(resp.StatusCode)
_, _ = c.Writer.Write(jsonResponse)
usage := &dto.Usage{
PromptTokens: geminiResponse.UsageMetadata.PromptTokenCount,
CompletionTokens: geminiResponse.UsageMetadata.CandidatesTokenCount,
TotalTokens: geminiResponse.UsageMetadata.TotalTokenCount,
}
return usage, nil
}

View File

@@ -6,6 +6,7 @@ import (
"io"
"net/http"
channelconstant "github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/relay/channel"
"github.com/QuantumNous/new-api/relay/channel/claude"
@@ -44,6 +45,16 @@ func (a *Adaptor) Init(info *relaycommon.RelayInfo) {
}
func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
baseURL := info.ChannelBaseUrl
if specialPlan, ok := channelconstant.ChannelSpecialBases[baseURL]; ok {
if info.RelayFormat == types.RelayFormatClaude {
return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
}
if info.RelayFormat == types.RelayFormatOpenAI {
return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
}
}
switch info.RelayFormat {
case types.RelayFormatClaude:
return fmt.Sprintf("%s/anthropic/v1/messages", info.ChannelBaseUrl), nil

View File

@@ -5,7 +5,6 @@ import (
"strings"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/logger"
relaycommon "github.com/QuantumNous/new-api/relay/common"
@@ -19,26 +18,10 @@ import (
"github.com/gin-gonic/gin"
)
// HandleStreamFormat processes a streaming response payload according to the provided RelayInfo and forwards it to the appropriate format-specific handler.
//
// It increments info.SendResponseCount, optionally converts OpenRouter "reasoning" fields to "reasoning_content" when the channel is OpenRouter and OpenRouterConvertToOpenAI is enabled, and then dispatches the (possibly modified) JSON string to the handler for the configured RelayFormat (OpenAI, Claude, or Gemini). It returns any error produced by the selected handler or nil if no handler is invoked.
// 辅助函数
func HandleStreamFormat(c *gin.Context, info *relaycommon.RelayInfo, data string, forceFormat bool, thinkToContent bool) error {
info.SendResponseCount++
// OpenRouter reasoning 字段转换reasoning -> reasoning_content
// 仅当启用转换为OpenAI兼容格式时执行
if info.ChannelType == constant.ChannelTypeOpenRouter && info.ChannelOtherSettings.OpenRouterConvertToOpenAI {
var streamResponse dto.ChatCompletionsStreamResponse
if err := common.Unmarshal(common.StringToByteSlice(data), &streamResponse); err == nil {
convertOpenRouterReasoningFieldsStream(&streamResponse)
// 重新序列化为JSON
newData, err := common.Marshal(streamResponse)
if err == nil {
data = string(newData)
}
}
}
switch info.RelayFormat {
case types.RelayFormatOpenAI:
return sendStreamData(c, info, data, forceFormat, thinkToContent)
@@ -270,26 +253,9 @@ func HandleFinalResponse(c *gin.Context, info *relaycommon.RelayInfo, lastStream
}
}
// sendResponsesStreamData sends a non-empty data chunk for the given stream response to the client.
// If data is empty, it returns without sending anything.
func sendResponsesStreamData(c *gin.Context, streamResponse dto.ResponsesStreamResponse, data string) {
if data == "" {
return
}
helper.ResponseChunkData(c, streamResponse, data)
}
// convertOpenRouterReasoningFieldsStream converts each choice's `Delta` in a streaming ChatCompletions response
// by normalizing any `reasoning` fields into `reasoning_content`.
// It applies ConvertReasoningField to every choice's Delta and is a no-op if `response` is nil or has no choices.
func convertOpenRouterReasoningFieldsStream(response *dto.ChatCompletionsStreamResponse) {
if response == nil || len(response.Choices) == 0 {
return
}
// 遍历所有choices对每个Delta使用统一的泛型函数进行转换
for i := range response.Choices {
choice := &response.Choices[i]
ConvertReasoningField(&choice.Delta)
}
}

View File

@@ -1,35 +0,0 @@
package openai
// ReasoningHolder 定义一个通用的接口用于操作包含reasoning字段的结构体
type ReasoningHolder interface {
// 获取reasoning字段的值
GetReasoning() string
// 设置reasoning字段的值
SetReasoning(reasoning string)
// 获取reasoning_content字段的值
GetReasoningContent() string
// 设置reasoning_content字段的值
SetReasoningContent(reasoningContent string)
}
// ConvertReasoningField 通用的reasoning字段转换函数
// 将reasoning字段的内容移动到reasoning_content字段
// ConvertReasoningField moves the holder's reasoning into its reasoning content and clears the original reasoning field.
// If GetReasoning returns an empty string, the holder is unchanged. When clearing, types that implement SetReasoningToNil()
// will have that method invoked; otherwise SetReasoning("") is used.
func ConvertReasoningField[T ReasoningHolder](holder T) {
reasoning := holder.GetReasoning()
if reasoning != "" {
holder.SetReasoningContent(reasoning)
}
// 使用类型断言来智能清理reasoning字段
switch h := any(holder).(type) {
case interface{ SetReasoningToNil() }:
// 流式响应指针类型设为nil
h.SetReasoningToNil()
default:
// 非流式响应:值类型,设为空字符串
holder.SetReasoning("")
}
}

View File

@@ -194,25 +194,6 @@ func OaiStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Re
return usage, nil
}
// OpenaiHandler processes an upstream OpenAI-like HTTP response, normalizes or infers token usage,
// optionally converts OpenRouter reasoning fields to OpenAI-compatible `reasoning_content`, adapts
// the response to the configured relay format (OpenAI, Claude, or Gemini), writes the final body
// to the client, and returns the computed usage.
//
// It will:
// - Handle OpenRouter enterprise wrapper responses when the channel is OpenRouter Enterprise.
// - Unmarshal the upstream body into an internal simple response and, when configured,
// convert OpenRouter `reasoning` fields into `reasoning_content`.
// - If usage prompt tokens are missing, infer completion tokens by counting tokens in choices
// (falling back to per-choice text token counting) and set Prompt/Completion/Total tokens.
// - Apply channel-specific post-processing to usage (cached token adjustments).
// - Depending on RelayFormat and channel settings, inject updated usage into the body,
// reserialize the converted simple response when ForceFormat is enabled or when OpenRouter
// conversion was applied, or convert the response to Claude/Gemini formats.
// - Write the final response body to the client via a graceful copy helper.
//
// Returns the final usage (possibly inferred or modified) or a NewAPIError describing any failure
// encountered while reading, parsing, or transforming the upstream response.
func OpenaiHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Response) (*dto.Usage, *types.NewAPIError) {
defer service.CloseResponseBodyGracefully(resp)
@@ -245,12 +226,6 @@ func OpenaiHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respo
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
// OpenRouter reasoning 字段转换reasoning -> reasoning_content
// 仅当启用转换为OpenAI兼容格式时执行修改现有无条件转换
if info.ChannelType == constant.ChannelTypeOpenRouter && info.ChannelOtherSettings.OpenRouterConvertToOpenAI {
convertOpenRouterReasoningFields(&simpleResponse)
}
if oaiError := simpleResponse.GetOpenAIError(); oaiError != nil && oaiError.Type != "" {
return nil, types.WithOpenAIError(*oaiError, resp.StatusCode)
}
@@ -296,13 +271,6 @@ func OpenaiHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respo
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
} else {
// 对于 OpenRouter仅在执行转换后重新序列化
if info.ChannelType == constant.ChannelTypeOpenRouter && info.ChannelOtherSettings.OpenRouterConvertToOpenAI {
responseBody, err = common.Marshal(simpleResponse)
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
}
break
}
case types.RelayFormatClaude:
@@ -704,10 +672,6 @@ func applyUsagePostProcessing(info *relaycommon.RelayInfo, usage *dto.Usage, res
}
}
// extractCachedTokensFromBody extracts a cached token count from a JSON response body.
// It looks for cached token values in the following fields (in order): `usage.prompt_tokens_details.cached_tokens`,
// `usage.cached_tokens`, and `usage.prompt_cache_hit_tokens`. It returns the first found value and `true`;
// if none are present or the body cannot be parsed, it returns 0 and `false`.
func extractCachedTokensFromBody(body []byte) (int, bool) {
if len(body) == 0 {
return 0, false
@@ -738,18 +702,3 @@ func extractCachedTokensFromBody(body []byte) (int, bool) {
}
return 0, false
}
// convertOpenRouterReasoningFields 转换OpenRouter响应中的reasoning字段为reasoning_content
// convertOpenRouterReasoningFields converts OpenRouter-style `reasoning` fields into `reasoning_content` for every choice's message in the provided OpenAITextResponse.
// It modifies the response in place and is a no-op if `response` is nil or contains no choices.
func convertOpenRouterReasoningFields(response *dto.OpenAITextResponse) {
if response == nil || len(response.Choices) == 0 {
return
}
// 遍历所有choices对每个Message使用统一的泛型函数进行转换
for i := range response.Choices {
choice := &response.Choices[i]
ConvertReasoningField(&choice.Message)
}
}

View File

@@ -39,6 +39,7 @@ var claudeModelMap = map[string]string{
"claude-opus-4-20250514": "claude-opus-4@20250514",
"claude-opus-4-1-20250805": "claude-opus-4-1@20250805",
"claude-sonnet-4-5-20250929": "claude-sonnet-4-5@20250929",
"claude-opus-4-5-20251101": "claude-opus-4-5@20251101",
}
const anthropicVersion = "vertex-2023-10-16"

View File

@@ -13,6 +13,7 @@ import (
channelconstant "github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/relay/channel"
"github.com/QuantumNous/new-api/relay/channel/claude"
"github.com/QuantumNous/new-api/relay/channel/openai"
relaycommon "github.com/QuantumNous/new-api/relay/common"
"github.com/QuantumNous/new-api/relay/constant"
@@ -23,11 +24,8 @@ import (
)
const (
contextKeyTTSRequest = "volcengine_tts_request"
contextKeyResponseFormat = "response_format"
DoubaoCodingPlan = "doubao-coding-plan"
DoubaoCodingPlanClaudeBaseURL = "https://ark.cn-beijing.volces.com/api/coding"
DoubaoCodingPlanOpenAIBaseURL = "https://ark.cn-beijing.volces.com/api/coding/v3"
contextKeyTTSRequest = "volcengine_tts_request"
contextKeyResponseFormat = "response_format"
)
type Adaptor struct {
@@ -39,6 +37,10 @@ func (a *Adaptor) ConvertGeminiRequest(*gin.Context, *relaycommon.RelayInfo, *dt
}
func (a *Adaptor) ConvertClaudeRequest(c *gin.Context, info *relaycommon.RelayInfo, req *dto.ClaudeRequest) (any, error) {
if _, ok := channelconstant.ChannelSpecialBases[info.ChannelBaseUrl]; ok {
adaptor := claude.Adaptor{}
return adaptor.ConvertClaudeRequest(c, info, req)
}
adaptor := openai.Adaptor{}
return adaptor.ConvertClaudeRequest(c, info, req)
}
@@ -238,11 +240,12 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
if baseUrl == "" {
baseUrl = channelconstant.ChannelBaseURLs[channelconstant.ChannelTypeVolcEngine]
}
specialPlan, hasSpecialPlan := channelconstant.ChannelSpecialBases[baseUrl]
switch info.RelayFormat {
case types.RelayFormatClaude:
if baseUrl == DoubaoCodingPlan {
return fmt.Sprintf("%s/v1/messages", DoubaoCodingPlanClaudeBaseURL), nil
if hasSpecialPlan && specialPlan.ClaudeBaseURL != "" {
return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
}
if strings.HasPrefix(info.UpstreamModelName, "bot") {
return fmt.Sprintf("%s/api/v3/bots/chat/completions", baseUrl), nil
@@ -251,8 +254,8 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
default:
switch info.RelayMode {
case constant.RelayModeChatCompletions:
if baseUrl == DoubaoCodingPlan {
return fmt.Sprintf("%s/chat/completions", DoubaoCodingPlanOpenAIBaseURL), nil
if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
}
if strings.HasPrefix(info.UpstreamModelName, "bot") {
return fmt.Sprintf("%s/api/v3/bots/chat/completions", baseUrl), nil
@@ -340,6 +343,15 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, request
}
func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) {
if info.RelayFormat == types.RelayFormatClaude {
if _, ok := channelconstant.ChannelSpecialBases[info.ChannelBaseUrl]; ok {
if info.IsStream {
return claude.ClaudeStreamHandler(c, resp, info, claude.RequestModeMessage)
}
return claude.ClaudeHandler(c, resp, info, claude.RequestModeMessage)
}
}
if info.RelayMode == constant.RelayModeAudioSpeech {
encoding := mapEncoding(c.GetString(contextKeyResponseFormat))
if info.IsStream {

View File

@@ -385,7 +385,7 @@ func (m *Message) writeSessionID(buf *bytes.Buffer) error {
}
size := len(m.SessionID)
if size > math.MaxUint32 {
if int64(size) > math.MaxUint32 {
return fmt.Errorf("session ID size (%d) exceeds max(uint32)", size)
}
@@ -407,7 +407,7 @@ func (m *Message) writeErrorCode(buf *bytes.Buffer) error {
func (m *Message) writePayload(buf *bytes.Buffer) error {
size := len(m.Payload)
if size > math.MaxUint32 {
if int64(size) > math.MaxUint32 {
return fmt.Errorf("payload size (%d) exceeds max(uint32)", size)
}

View File

@@ -6,6 +6,7 @@ import (
"io"
"net/http"
channelconstant "github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/relay/channel"
"github.com/QuantumNous/new-api/relay/channel/claude"
@@ -43,15 +44,30 @@ func (a *Adaptor) Init(info *relaycommon.RelayInfo) {
}
func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
baseURL := info.ChannelBaseUrl
if baseURL == "" {
baseURL = channelconstant.ChannelBaseURLs[channelconstant.ChannelTypeZhipu_v4]
}
specialPlan, hasSpecialPlan := channelconstant.ChannelSpecialBases[baseURL]
switch info.RelayFormat {
case types.RelayFormatClaude:
return fmt.Sprintf("%s/api/anthropic/v1/messages", info.ChannelBaseUrl), nil
if hasSpecialPlan && specialPlan.ClaudeBaseURL != "" {
return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
}
return fmt.Sprintf("%s/api/anthropic/v1/messages", baseURL), nil
default:
switch info.RelayMode {
case relayconstant.RelayModeEmbeddings:
return fmt.Sprintf("%s/api/paas/v4/embeddings", info.ChannelBaseUrl), nil
if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
return fmt.Sprintf("%s/embeddings", specialPlan.OpenAIBaseURL), nil
}
return fmt.Sprintf("%s/api/paas/v4/embeddings", baseURL), nil
default:
return fmt.Sprintf("%s/api/paas/v4/chat/completions", info.ChannelBaseUrl), nil
if hasSpecialPlan && specialPlan.OpenAIBaseURL != "" {
return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
}
return fmt.Sprintf("%s/api/paas/v4/chat/completions", baseURL), nil
}
}
}

View File

@@ -1,7 +1,7 @@
package zhipu_4v
var ModelList = []string{
"glm-4", "glm-4v", "glm-3-turbo", "glm-4-alltools", "glm-4-plus", "glm-4-0520", "glm-4-air", "glm-4-airx", "glm-4-long", "glm-4-flash", "glm-4v-plus",
"glm-4", "glm-4v", "glm-3-turbo", "glm-4-alltools", "glm-4-plus", "glm-4-0520", "glm-4-air", "glm-4-airx", "glm-4-long", "glm-4-flash", "glm-4v-plus", "glm-4.6",
}
var ChannelName = "zhipu_4v"

View File

@@ -22,11 +22,18 @@ import (
)
const (
InitialScannerBufferSize = 64 << 10 // 64KB (64*1024)
MaxScannerBufferSize = 10 << 20 // 10MB (10*1024*1024)
DefaultPingInterval = 10 * time.Second
InitialScannerBufferSize = 64 << 10 // 64KB (64*1024)
DefaultMaxScannerBufferSize = 64 << 20 // 64MB (64*1024*1024) default SSE buffer size
DefaultPingInterval = 10 * time.Second
)
func getScannerBufferSize() int {
if constant.StreamScannerMaxBufferMB > 0 {
return constant.StreamScannerMaxBufferMB << 20
}
return DefaultMaxScannerBufferSize
}
func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo, dataHandler func(data string) bool) {
if resp == nil || dataHandler == nil {
@@ -95,7 +102,7 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon
close(stopChan)
}()
scanner.Buffer(make([]byte, InitialScannerBufferSize), MaxScannerBufferSize)
scanner.Buffer(make([]byte, InitialScannerBufferSize), getScannerBufferSize())
scanner.Split(bufio.ScanLines)
SetEventStreamHeaders(c)

View File

@@ -9,9 +9,9 @@ import (
func SetVideoRouter(router *gin.Engine) {
videoV1Router := router.Group("/v1")
videoV1Router.GET("/videos/:task_id/content", controller.VideoProxy)
videoV1Router.Use(middleware.TokenAuth(), middleware.Distribute())
{
videoV1Router.GET("/videos/:task_id/content", controller.VideoProxy)
videoV1Router.POST("/video/generations", controller.RelayTask)
videoV1Router.GET("/video/generations/:task_id", controller.RelayTask)
}

View File

@@ -26,6 +26,10 @@ var defaultGeminiSettings = GeminiSettings{
SupportedImagineModels: []string{
"gemini-2.0-flash-exp-image-generation",
"gemini-2.0-flash-exp",
"gemini-3-pro-image-preview",
"gemini-2.5-flash-image",
"nano-banana",
"nano-banana-pro",
},
ThinkingAdapterEnabled: false,
ThinkingAdapterBudgetTokensPercentage: 0.6,

View File

@@ -55,6 +55,8 @@ var defaultCacheRatio = map[string]float64{
"claude-opus-4-1-20250805-thinking": 0.1,
"claude-sonnet-4-5-20250929": 0.1,
"claude-sonnet-4-5-20250929-thinking": 0.1,
"claude-opus-4-5-20251101": 0.1,
"claude-opus-4-5-20251101-thinking": 0.1,
}
var defaultCreateCacheRatio = map[string]float64{
@@ -74,6 +76,8 @@ var defaultCreateCacheRatio = map[string]float64{
"claude-opus-4-1-20250805-thinking": 1.25,
"claude-sonnet-4-5-20250929": 1.25,
"claude-sonnet-4-5-20250929-thinking": 1.25,
"claude-opus-4-5-20251101": 1.25,
"claude-opus-4-5-20251101-thinking": 1.25,
}
//var defaultCreateCacheRatio = map[string]float64{}

View File

@@ -143,6 +143,7 @@ var defaultModelRatio = map[string]float64{
"claude-3-7-sonnet-20250219-thinking": 1.5,
"claude-sonnet-4-20250514": 1.5,
"claude-sonnet-4-5-20250929": 1.5,
"claude-opus-4-5-20251101": 2.5,
"claude-3-opus-20240229": 7.5, // $15 / 1M tokens
"claude-opus-4-20250514": 7.5,
"claude-opus-4-1-20250805": 7.5,

View File

@@ -17,12 +17,87 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import React from 'react';
import React, { useRef, useEffect, useCallback } from 'react';
import { Toast } from '@douyinfe/semi-ui';
import { useTranslation } from 'react-i18next';
import { usePlayground } from '../../contexts/PlaygroundContext';
const CustomInputRender = (props) => {
const { t } = useTranslation();
const { onPasteImage, imageEnabled } = usePlayground();
const { detailProps } = props;
const { clearContextNode, uploadNode, inputNode, sendNode, onClick } =
detailProps;
const containerRef = useRef(null);
const handlePaste = useCallback(async (e) => {
const items = e.clipboardData?.items;
if (!items) return;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.type.indexOf('image') !== -1) {
e.preventDefault();
const file = item.getAsFile();
if (file) {
try {
if (!imageEnabled) {
Toast.warning({
content: t('请先在设置中启用图片功能'),
duration: 3,
});
return;
}
const reader = new FileReader();
reader.onload = (event) => {
const base64 = event.target.result;
if (onPasteImage) {
onPasteImage(base64);
Toast.success({
content: t('图片已添加'),
duration: 2,
});
} else {
Toast.error({
content: t('无法添加图片'),
duration: 2,
});
}
};
reader.onerror = () => {
console.error('Failed to read image file:', reader.error);
Toast.error({
content: t('粘贴图片失败'),
duration: 2,
});
};
reader.readAsDataURL(file);
} catch (error) {
console.error('Failed to paste image:', error);
Toast.error({
content: t('粘贴图片失败'),
duration: 2,
});
}
}
break;
}
}
}, [onPasteImage, imageEnabled, t]);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
container.addEventListener('paste', handlePaste);
return () => {
container.removeEventListener('paste', handlePaste);
};
}, [handlePaste]);
// 清空按钮
const styledClearNode = clearContextNode
@@ -57,11 +132,12 @@ const CustomInputRender = (props) => {
});
return (
<div className='p-2 sm:p-4'>
<div className='p-2 sm:p-4' ref={containerRef}>
<div
className='flex items-center gap-2 sm:gap-3 p-2 bg-gray-50 rounded-xl sm:rounded-2xl shadow-sm hover:shadow-md transition-shadow'
style={{ border: '1px solid var(--semi-color-border)' }}
onClick={onClick}
title={t('支持 Ctrl+V 粘贴图片')}
>
{/* 清空对话按钮 - 左边 */}
{styledClearNode}

View File

@@ -82,7 +82,7 @@ const CustomRequestEditor = ({
return true;
} catch (error) {
setIsValid(false);
setErrorMessage(`JSON格式错误: ${error.message}`);
setErrorMessage(`${t('JSON格式错误')}: ${error.message}`);
return false;
}
};
@@ -123,14 +123,14 @@ const CustomRequestEditor = ({
<div className='flex items-center gap-2'>
<Code size={16} className='text-gray-500' />
<Typography.Text strong className='text-sm'>
自定义请求体模式
{t('自定义请求体模式')}
</Typography.Text>
</div>
<Switch
checked={customRequestMode}
onChange={handleModeToggle}
checkedText='开'
uncheckedText='关'
checkedText={t('开')}
uncheckedText={t('关')}
size='small'
/>
</div>
@@ -140,7 +140,7 @@ const CustomRequestEditor = ({
{/* 提示信息 */}
<Banner
type='warning'
description='启用此模式后将使用您自定义的请求体发送API请求模型配置面板的参数设置将被忽略。'
description={t('启用此模式后将使用您自定义的请求体发送API请求模型配置面板的参数设置将被忽略。')}
icon={<AlertTriangle size={16} />}
className='!rounded-lg'
closeIcon={null}
@@ -150,21 +150,21 @@ const CustomRequestEditor = ({
<div>
<div className='flex items-center justify-between mb-2'>
<Typography.Text strong className='text-sm'>
请求体 JSON
{t('请求体 JSON')}
</Typography.Text>
<div className='flex items-center gap-2'>
{isValid ? (
<div className='flex items-center gap-1 text-green-600'>
<Check size={14} />
<Typography.Text className='text-xs'>
格式正确
{t('格式正确')}
</Typography.Text>
</div>
) : (
<div className='flex items-center gap-1 text-red-600'>
<X size={14} />
<Typography.Text className='text-xs'>
格式错误
{t('格式错误')}
</Typography.Text>
</div>
)}
@@ -177,7 +177,7 @@ const CustomRequestEditor = ({
disabled={!isValid}
className='!rounded-lg'
>
格式化
{t('格式化')}
</Button>
</div>
</div>
@@ -201,7 +201,7 @@ const CustomRequestEditor = ({
)}
<Typography.Text className='text-xs text-gray-500 mt-2 block'>
请输入有效的JSON格式的请求体您可以参考预览面板中的默认请求体格式
{t('请输入有效的JSON格式的请求体您可以参考预览面板中的默认请求体格式。')}
</Typography.Text>
</div>
</>

View File

@@ -29,6 +29,7 @@ import {
import { Code, Zap, Clock, X, Eye, Send } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import CodeViewer from './CodeViewer';
import SSEViewer from './SSEViewer';
const DebugPanel = ({
debugData,
@@ -180,15 +181,27 @@ const DebugPanel = ({
<div className='flex items-center gap-2'>
<Zap size={16} />
{t('响应')}
{debugData.sseMessages && debugData.sseMessages.length > 0 && (
<span className='px-1.5 py-0.5 text-xs bg-blue-100 text-blue-600 rounded-full'>
SSE ({debugData.sseMessages.length})
</span>
)}
</div>
}
itemKey='response'
>
<CodeViewer
content={debugData.response}
title='response'
language='json'
/>
{debugData.sseMessages && debugData.sseMessages.length > 0 ? (
<SSEViewer
sseData={debugData.sseMessages}
title='response'
/>
) : (
<CodeViewer
content={debugData.response}
title='response'
language='json'
/>
)}
</TabPane>
</Tabs>
</div>

View File

@@ -21,6 +21,7 @@ import React from 'react';
import { Input, Typography, Button, Switch } from '@douyinfe/semi-ui';
import { IconFile } from '@douyinfe/semi-icons';
import { FileText, Plus, X, Image } from 'lucide-react';
import { useTranslation } from 'react-i18next';
const ImageUrlInput = ({
imageUrls,
@@ -29,6 +30,7 @@ const ImageUrlInput = ({
onImageEnabledChange,
disabled = false,
}) => {
const { t } = useTranslation();
const handleAddImageUrl = () => {
const newUrls = [...imageUrls, ''];
onImageUrlsChange(newUrls);
@@ -56,11 +58,11 @@ const ImageUrlInput = ({
}
/>
<Typography.Text strong className='text-sm'>
图片地址
{t('图片地址')}
</Typography.Text>
{disabled && (
<Typography.Text className='text-xs text-orange-600'>
(已在自定义模式中忽略)
({t('已在自定义模式中忽略')})
</Typography.Text>
)}
</div>
@@ -68,8 +70,8 @@ const ImageUrlInput = ({
<Switch
checked={imageEnabled}
onChange={onImageEnabledChange}
checkedText='启用'
uncheckedText='停用'
checkedText={t('启用')}
uncheckedText={t('停用')}
size='small'
className='flex-shrink-0'
disabled={disabled}
@@ -89,19 +91,19 @@ const ImageUrlInput = ({
{!imageEnabled ? (
<Typography.Text className='text-xs text-gray-500 mb-2 block'>
{disabled
? '图片功能在自定义请求体模式下不可用'
: '启用后可添加图片URL进行多模态对话'}
? t('图片功能在自定义请求体模式下不可用')
: t('启用后可添加图片URL进行多模态对话')}
</Typography.Text>
) : imageUrls.length === 0 ? (
<Typography.Text className='text-xs text-gray-500 mb-2 block'>
{disabled
? '图片功能在自定义请求体模式下不可用'
: '点击 + 按钮添加图片URL进行多模态对话'}
? t('图片功能在自定义请求体模式下不可用')
: t('点击 + 按钮添加图片URL进行多模态对话')}
</Typography.Text>
) : (
<Typography.Text className='text-xs text-gray-500 mb-2 block'>
已添加 {imageUrls.length} 张图片
{disabled ? ' (自定义模式下不可用)' : ''}
{t('已添加')} {imageUrls.length} {t('张图片')}
{disabled ? ` (${t('自定义模式下不可用')})` : ''}
</Typography.Text>
)}

View File

@@ -19,6 +19,7 @@ For commercial licensing, please contact support@quantumnous.com
import React from 'react';
import { Input, Slider, Typography, Button, Tag } from '@douyinfe/semi-ui';
import { useTranslation } from 'react-i18next';
import {
Hash,
Thermometer,
@@ -37,6 +38,8 @@ const ParameterControl = ({
onParameterToggle,
disabled = false,
}) => {
const { t } = useTranslation();
return (
<>
{/* Temperature */}
@@ -70,7 +73,7 @@ const ParameterControl = ({
/>
</div>
<Typography.Text className='text-xs text-gray-500 mb-2'>
控制输出的随机性和创造性
{t('控制输出的随机性和创造性')}
</Typography.Text>
<Slider
step={0.1}
@@ -110,7 +113,7 @@ const ParameterControl = ({
/>
</div>
<Typography.Text className='text-xs text-gray-500 mb-2'>
核采样控制词汇选择的多样性
{t('核采样,控制词汇选择的多样性')}
</Typography.Text>
<Slider
step={0.1}
@@ -154,7 +157,7 @@ const ParameterControl = ({
/>
</div>
<Typography.Text className='text-xs text-gray-500 mb-2'>
频率惩罚减少重复词汇的出现
{t('频率惩罚,减少重复词汇的出现')}
</Typography.Text>
<Slider
step={0.1}
@@ -198,7 +201,7 @@ const ParameterControl = ({
/>
</div>
<Typography.Text className='text-xs text-gray-500 mb-2'>
存在惩罚鼓励讨论新话题
{t('存在惩罚,鼓励讨论新话题')}
</Typography.Text>
<Slider
step={0.1}
@@ -262,7 +265,7 @@ const ParameterControl = ({
Seed
</Typography.Text>
<Typography.Text className='text-xs text-gray-400'>
(可选用于复现结果)
({t('可选,用于复现结果')})
</Typography.Text>
</div>
<Button
@@ -276,7 +279,7 @@ const ParameterControl = ({
/>
</div>
<Input
placeholder='随机种子 (留空为随机)'
placeholder={t('随机种子 (留空为随机)')}
name='seed'
autoComplete='new-password'
value={inputs.seed || ''}

View File

@@ -0,0 +1,266 @@
/*
Copyright (C) 2025 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import React, { useState, useMemo, useCallback } from 'react';
import { Button, Tooltip, Toast, Collapse, Badge, Typography } from '@douyinfe/semi-ui';
import { Copy, ChevronDown, ChevronUp, Zap, CheckCircle, XCircle } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { copy } from '../../helpers';
/**
* SSEViewer component for displaying Server-Sent Events in an interactive format
* @param {Object} props - Component props
* @param {Array} props.sseData - Array of SSE messages to display
* @returns {JSX.Element} Rendered SSE viewer component
*/
const SSEViewer = ({ sseData }) => {
const { t } = useTranslation();
const [expandedKeys, setExpandedKeys] = useState([]);
const [copied, setCopied] = useState(false);
const parsedSSEData = useMemo(() => {
if (!sseData || !Array.isArray(sseData)) {
return [];
}
return sseData.map((item, index) => {
let parsed = null;
let error = null;
let isDone = false;
if (item === '[DONE]') {
isDone = true;
} else {
try {
parsed = typeof item === 'string' ? JSON.parse(item) : item;
} catch (e) {
error = e.message;
}
}
return {
index,
raw: item,
parsed,
error,
isDone,
key: `sse-${index}`,
};
});
}, [sseData]);
const stats = useMemo(() => {
const total = parsedSSEData.length;
const errors = parsedSSEData.filter(item => item.error).length;
const done = parsedSSEData.filter(item => item.isDone).length;
const valid = total - errors - done;
return { total, errors, done, valid };
}, [parsedSSEData]);
const handleToggleAll = useCallback(() => {
setExpandedKeys(prev => {
if (prev.length === parsedSSEData.length) {
return [];
} else {
return parsedSSEData.map(item => item.key);
}
});
}, [parsedSSEData]);
const handleCopyAll = useCallback(async () => {
try {
const allData = parsedSSEData
.map(item => (item.parsed ? JSON.stringify(item.parsed, null, 2) : item.raw))
.join('\n\n');
await copy(allData);
setCopied(true);
Toast.success(t('已复制全部数据'));
setTimeout(() => setCopied(false), 2000);
} catch (err) {
Toast.error(t('复制失败'));
console.error('Copy failed:', err);
}
}, [parsedSSEData, t]);
const handleCopySingle = useCallback(async (item) => {
try {
const textToCopy = item.parsed ? JSON.stringify(item.parsed, null, 2) : item.raw;
await copy(textToCopy);
Toast.success(t('已复制'));
} catch (err) {
Toast.error(t('复制失败'));
}
}, [t]);
const renderSSEItem = (item) => {
if (item.isDone) {
return (
<div className='flex items-center gap-2 p-3 bg-green-50 dark:bg-green-900/20 rounded-lg'>
<CheckCircle size={16} className='text-green-600' />
<Typography.Text className='text-green-600 font-medium'>
{t('流式响应完成')} [DONE]
</Typography.Text>
</div>
);
}
if (item.error) {
return (
<div className='space-y-2'>
<div className='flex items-center gap-2 p-3 bg-red-50 dark:bg-red-900/20 rounded-lg'>
<XCircle size={16} className='text-red-600' />
<Typography.Text className='text-red-600'>
{t('解析错误')}: {item.error}
</Typography.Text>
</div>
<div className='p-3 bg-gray-100 dark:bg-gray-800 rounded-lg font-mono text-xs overflow-auto'>
<pre>{item.raw}</pre>
</div>
</div>
);
}
return (
<div className='space-y-2'>
{/* JSON 格式化显示 */}
<div className='relative'>
<pre className='p-4 bg-gray-900 text-gray-100 rounded-lg overflow-auto text-xs font-mono leading-relaxed'>
{JSON.stringify(item.parsed, null, 2)}
</pre>
<Button
icon={<Copy size={12} />}
size='small'
theme='borderless'
onClick={() => handleCopySingle(item)}
className='absolute top-2 right-2 !bg-gray-800/80 !text-gray-300 hover:!bg-gray-700'
/>
</div>
{/* 关键信息摘要 */}
{item.parsed?.choices?.[0] && (
<div className='flex flex-wrap gap-2 text-xs'>
{item.parsed.choices[0].delta?.content && (
<Badge count={`${t('内容')}: "${String(item.parsed.choices[0].delta.content).substring(0, 20)}..."`} type='primary' />
)}
{item.parsed.choices[0].delta?.reasoning_content && (
<Badge count={t('有 Reasoning')} type='warning' />
)}
{item.parsed.choices[0].finish_reason && (
<Badge count={`${t('完成')}: ${item.parsed.choices[0].finish_reason}`} type='success' />
)}
{item.parsed.usage && (
<Badge
count={`${t('令牌')}: ${item.parsed.usage.prompt_tokens || 0}/${item.parsed.usage.completion_tokens || 0}`}
type='tertiary'
/>
)}
</div>
)}
</div>
);
};
if (!parsedSSEData || parsedSSEData.length === 0) {
return (
<div className='flex items-center justify-center h-full min-h-[200px] text-gray-500'>
<span>{t('暂无SSE响应数据')}</span>
</div>
);
}
return (
<div className='h-full flex flex-col bg-gray-50 dark:bg-gray-900/50 rounded-lg'>
{/* 头部工具栏 */}
<div className='flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 flex-shrink-0'>
<div className='flex items-center gap-3'>
<Zap size={16} className='text-blue-500' />
<Typography.Text strong>{t('SSE数据流')}</Typography.Text>
<Badge count={stats.total} type='primary' />
{stats.errors > 0 && <Badge count={`${stats.errors} ${t('错误')}`} type='danger' />}
</div>
<div className='flex items-center gap-2'>
<Tooltip content={t('复制全部')}>
<Button
icon={<Copy size={14} />}
size='small'
onClick={handleCopyAll}
theme='borderless'
>
{copied ? t('已复制') : t('复制全部')}
</Button>
</Tooltip>
<Tooltip content={expandedKeys.length === parsedSSEData.length ? t('全部收起') : t('全部展开')}>
<Button
icon={expandedKeys.length === parsedSSEData.length ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
size='small'
onClick={handleToggleAll}
theme='borderless'
>
{expandedKeys.length === parsedSSEData.length ? t('收起') : t('展开')}
</Button>
</Tooltip>
</div>
</div>
{/* SSE 数据列表 */}
<div className='flex-1 overflow-auto p-4'>
<Collapse
activeKey={expandedKeys}
onChange={setExpandedKeys}
accordion={false}
className='bg-white dark:bg-gray-800 rounded-lg'
>
{parsedSSEData.map((item) => (
<Collapse.Panel
key={item.key}
header={
<div className='flex items-center gap-2'>
<Badge count={`#${item.index + 1}`} type='tertiary' />
{item.isDone ? (
<span className='text-green-600 font-medium'>[DONE]</span>
) : item.error ? (
<span className='text-red-600'>{t('解析错误')}</span>
) : (
<>
<span className='text-gray-600'>
{item.parsed?.id || item.parsed?.object || t('SSE 事件')}
</span>
{item.parsed?.choices?.[0]?.delta && (
<span className='text-xs text-gray-400'>
{Object.keys(item.parsed.choices[0].delta).filter(k => item.parsed.choices[0].delta[k]).join(', ')}
</span>
)}
</>
)}
</div>
}
>
{renderSSEItem(item)}
</Collapse.Panel>
))}
</Collapse>
</div>
</div>
);
};
export default SSEViewer;

View File

@@ -122,7 +122,7 @@ const SettingsPanel = ({
</Typography.Text>
{customRequestMode && (
<Typography.Text className='text-xs text-orange-600'>
(已在自定义模式中忽略)
({t('已在自定义模式中忽略')})
</Typography.Text>
)}
</div>
@@ -154,7 +154,7 @@ const SettingsPanel = ({
</Typography.Text>
{customRequestMode && (
<Typography.Text className='text-xs text-orange-600'>
(已在自定义模式中忽略)
({t('已在自定义模式中忽略')})
</Typography.Text>
)}
</div>
@@ -206,19 +206,19 @@ const SettingsPanel = ({
<div className='flex items-center gap-2'>
<ToggleLeft size={16} className='text-gray-500' />
<Typography.Text strong className='text-sm'>
流式输出
{t('流式输出')}
</Typography.Text>
{customRequestMode && (
<Typography.Text className='text-xs text-orange-600'>
(已在自定义模式中忽略)
({t('已在自定义模式中忽略')})
</Typography.Text>
)}
</div>
<Switch
checked={inputs.stream}
onChange={(checked) => onInputChange('stream', checked)}
checkedText='开'
uncheckedText='关'
checkedText={t('开')}
uncheckedText={t('关')}
size='small'
disabled={customRequestMode}
/>

View File

@@ -23,6 +23,7 @@ export { default as DebugPanel } from './DebugPanel';
export { default as MessageContent } from './MessageContent';
export { default as MessageActions } from './MessageActions';
export { default as CustomInputRender } from './CustomInputRender';
export { default as SSEViewer } from './SSEViewer';
export { default as ParameterControl } from './ParameterControl';
export { default as ImageUrlInput } from './ImageUrlInput';
export { default as FloatingButtons } from './FloatingButtons';

View File

@@ -1188,6 +1188,13 @@ const EditChannelModal = (props) => {
settings.aws_key_type = localInputs.aws_key_type || 'ak_sk';
}
// type === 41 (Vertex): 始终保存 vertex_key_type 到 settings避免编辑时被重置
if (localInputs.type === 41) {
settings.vertex_key_type = localInputs.vertex_key_type || 'json';
} else if ('vertex_key_type' in settings) {
delete settings.vertex_key_type;
}
// type === 1 (OpenAI) 或 type === 14 (Claude): 设置字段透传控制(显式保存布尔值)
if (localInputs.type === 1 || localInputs.type === 14) {
settings.allow_service_tier = localInputs.allow_service_tier === true;

View File

@@ -363,12 +363,13 @@ export const getTaskLogsColumns = ({
const isSuccess = record.status === 'SUCCESS';
const isUrl = typeof text === 'string' && /^https?:\/\//.test(text);
if (isSuccess && isVideoTask && isUrl) {
const videoUrl = `/v1/videos/${record.task_id}/content`;
return (
<a
href='#'
onClick={(e) => {
e.preventDefault();
openVideoModal(text);
openVideoModal(videoUrl);
}}
>
{t('点击预览视频')}

View File

@@ -20,6 +20,7 @@ For commercial licensing, please contact support@quantumnous.com
import React, { useState, useEffect } from 'react';
import { Modal, Button, Typography, Spin } from '@douyinfe/semi-ui';
import { IconExternalOpen, IconCopy } from '@douyinfe/semi-icons';
import { useTranslation } from 'react-i18next';
const { Text } = Typography;
@@ -29,6 +30,7 @@ const ContentModal = ({
modalContent,
isVideo,
}) => {
const { t } = useTranslation();
const [videoError, setVideoError] = useState(false);
const [isLoading, setIsLoading] = useState(false);
@@ -64,25 +66,25 @@ const ContentModal = ({
type='tertiary'
style={{ display: 'block', marginBottom: '16px' }}
>
视频无法在当前浏览器中播放这可能是由于
{t('视频无法在当前浏览器中播放这可能是由于:')}
</Text>
<Text
type='tertiary'
style={{ display: 'block', marginBottom: '8px', fontSize: '12px' }}
>
视频服务商的跨域限制
{t('• 视频服务商的跨域限制')}
</Text>
<Text
type='tertiary'
style={{ display: 'block', marginBottom: '8px', fontSize: '12px' }}
>
需要特定的请求头或认证
{t('• 需要特定的请求头或认证')}
</Text>
<Text
type='tertiary'
style={{ display: 'block', marginBottom: '16px', fontSize: '12px' }}
>
防盗链保护机制
{t('• 防盗链保护机制')}
</Text>
<div style={{ marginTop: '20px' }}>
@@ -91,10 +93,10 @@ const ContentModal = ({
onClick={handleOpenInNewTab}
style={{ marginRight: '8px' }}
>
在新标签页中打开
{t('在新标签页中打开')}
</Button>
<Button icon={<IconCopy />} onClick={handleCopyUrl}>
复制链接
{t('复制链接')}
</Button>
</div>

View File

@@ -30,19 +30,37 @@ export const MESSAGE_ROLES = {
SYSTEM: 'system',
};
// 默认消息示例
export const DEFAULT_MESSAGES = [
// 默认消息示例 - 使用函数生成以支持 i18n
export const getDefaultMessages = (t) => [
{
role: MESSAGE_ROLES.USER,
id: '2',
createAt: 1715676751919,
content: '你好',
content: t('默认用户消息'),
},
{
role: MESSAGE_ROLES.ASSISTANT,
id: '3',
createAt: 1715676751919,
content: '你好,请问有什么可以帮助您的吗?',
content: t('默认助手消息'),
reasoningContent: '',
isReasoningExpanded: false,
},
];
// 保留旧的导出以保持向后兼容
export const DEFAULT_MESSAGES = [
{
role: MESSAGE_ROLES.USER,
id: '2',
createAt: 1715676751919,
content: 'Hello',
},
{
role: MESSAGE_ROLES.ASSISTANT,
id: '3',
createAt: 1715676751919,
content: 'Hello! How can I help you today?',
reasoningContent: '',
isReasoningExpanded: false,
},

View File

@@ -0,0 +1,60 @@
/*
Copyright (C) 2025 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import React, { createContext, useContext } from 'react';
/**
* Context for Playground component to share image handling functionality
*/
const PlaygroundContext = createContext(null);
/**
* Hook to access Playground context
* @returns {Object} Context value with onPasteImage, imageUrls, and imageEnabled
*/
export const usePlayground = () => {
const context = useContext(PlaygroundContext);
if (!context) {
return {
onPasteImage: () => {
console.warn('PlaygroundContext not provided');
},
imageUrls: [],
imageEnabled: false,
};
}
return context;
};
/**
* Provider component for Playground context
* @param {Object} props - Component props
* @param {React.ReactNode} props.children - Child components
* @param {Object} props.value - Context value to provide
* @returns {JSX.Element} Provider component
*/
export const PlaygroundProvider = ({ children, value }) => {
return (
<PlaygroundContext.Provider value={value}>
{children}
</PlaygroundContext.Provider>
);
};
export default PlaygroundContext;

View File

@@ -179,6 +179,8 @@ export const useApiRequest = (
request: payload,
timestamp: new Date().toISOString(),
response: null,
sseMessages: null, // 非流式请求清除 SSE 消息
isStreaming: false,
}));
setActiveDebugTab(DEBUG_TABS.REQUEST);
@@ -291,6 +293,8 @@ export const useApiRequest = (
request: payload,
timestamp: new Date().toISOString(),
response: null,
sseMessages: [], // 新增:存储 SSE 消息数组
isStreaming: true, // 新增:标记流式状态
}));
setActiveDebugTab(DEBUG_TABS.REQUEST);
@@ -314,7 +318,12 @@ export const useApiRequest = (
isStreamComplete = true; // 标记流正常完成
source.close();
sseSourceRef.current = null;
setDebugData((prev) => ({ ...prev, response: responseData }));
setDebugData((prev) => ({
...prev,
response: responseData,
sseMessages: [...(prev.sseMessages || []), '[DONE]'], // 添加 DONE 标记
isStreaming: false,
}));
completeMessage();
return;
}
@@ -328,6 +337,12 @@ export const useApiRequest = (
hasReceivedFirstResponse = true;
}
// 新增:将 SSE 消息添加到数组
setDebugData((prev) => ({
...prev,
sseMessages: [...(prev.sseMessages || []), e.data],
}));
const delta = payload.choices?.[0]?.delta;
if (delta) {
if (delta.reasoning_content) {
@@ -347,6 +362,8 @@ export const useApiRequest = (
setDebugData((prev) => ({
...prev,
response: responseData + `\n\nError: ${errorInfo}`,
sseMessages: [...(prev.sseMessages || []), e.data], // 即使解析失败也保存原始数据
isStreaming: false,
}));
setActiveDebugTab(DEBUG_TABS.RESPONSE);

View File

@@ -18,8 +18,10 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useCallback, useRef, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import {
DEFAULT_MESSAGES,
getDefaultMessages,
DEFAULT_CONFIG,
DEBUG_TABS,
MESSAGE_STATUS,
@@ -33,9 +35,27 @@ import {
import { processIncompleteThinkTags } from '../../helpers';
export const usePlaygroundState = () => {
const { t } = useTranslation();
// 使用惰性初始化,确保只在组件首次挂载时加载配置和消息
const [savedConfig] = useState(() => loadConfig());
const [initialMessages] = useState(() => loadMessages() || DEFAULT_MESSAGES);
const [initialMessages] = useState(() => {
const loaded = loadMessages();
// 检查是否是旧的中文默认消息,如果是则清除
if (loaded && loaded.length === 2 && loaded[0].id === '2' && loaded[1].id === '3') {
const hasOldChinese =
loaded[0].content === '你好' ||
loaded[1].content === '你好,请问有什么可以帮助您的吗?' ||
loaded[1].content === '你好!很高兴见到你。有什么我可以帮助你的吗?';
if (hasOldChinese) {
// 清除旧的默认消息
localStorage.removeItem('playground_messages');
return null;
}
}
return loaded;
});
// 基础配置状态
const [inputs, setInputs] = useState(
@@ -60,8 +80,16 @@ export const usePlaygroundState = () => {
const [groups, setGroups] = useState([]);
const [status, setStatus] = useState({});
// 消息相关状态 - 使用加载的消息初始化
const [message, setMessage] = useState(initialMessages);
// 消息相关状态 - 使用加载的消息或默认消息初始化
const [message, setMessage] = useState(() => initialMessages || getDefaultMessages(t));
// 当语言改变时,如果是默认消息则更新
useEffect(() => {
// 只在没有保存的消息时才更新默认消息
if (!initialMessages) {
setMessage(getDefaultMessages(t));
}
}, [t, initialMessages]); // 当语言改变时
// 调试状态
const [debugData, setDebugData] = useState({
@@ -168,7 +196,7 @@ export const usePlaygroundState = () => {
if (resetMessages) {
setMessage([]);
setTimeout(() => {
setMessage(DEFAULT_MESSAGES);
setMessage(getDefaultMessages(t));
}, 0);
}
}, []);

View File

@@ -18,7 +18,9 @@
"[最多请求次数]和[最多请求完成次数]的最大值为2147483647。": "The maximum value of [Maximum request count] and [Maximum request completion count] is 2147483647.",
"[最多请求次数]必须大于等于0[最多请求完成次数]必须大于等于1。": "[Maximum request count] must be greater than or equal to 0, [Maximum request completion count] must be greater than or equal to 1.",
"{\n \"default\": [200, 100],\n \"vip\": [0, 1000]\n}": "{\n \"default\": [200, 100],\n \"vip\": [0, 1000]\n}",
"{{breakdown}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "{{breakdown}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}": "{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}",
"{{ratioType}} {{ratio}}": "{{ratioType}} {{ratio}}",
"© {{currentYear}}": "© {{currentYear}}",
"| 基于": " | Based on ",
"$/1M tokens": "$/1M tokens",
@@ -26,15 +28,20 @@
"0.002-1之间的小数": "Decimal between 0.002-1",
"0.1以上的小数": "Decimal above 0.1",
"10 - 最高": "10 - Highest",
"1h缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "1h cache creation {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (ratio: {{ratio}})",
"1h缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (1h缓存创建倍率: {{cacheCreationRatio1h}})": "1h cache creation price: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (1h cache creation ratio: {{cacheCreationRatio1h}})",
"2 - 低": "2 - Low",
"2025年5月10日后添加的渠道不需要再在部署的时候移除模型名称中的\".\"": "After May 10, 2025, channels added do not need to remove the dot in the model name during deployment",
"360智脑": "360 AI Brain",
"5 - 正常(默认)": "5 - Normal (default)",
"5m缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "5m cache creation {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (ratio: {{ratio}})",
"5m缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (5m缓存创建倍率: {{cacheCreationRatio5m}})": "5m cache creation price: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (5m cache creation ratio: {{cacheCreationRatio5m}})",
"8 - 高": "8 - High",
"AGPL v3.0协议": "AGPL v3.0 License",
"AI 对话": "AI Chat",
"AI模型测试环境": "AI model testing environment",
"AI模型配置": "AI model configuration",
"AK/SK 模式:使用 AccessKey 和 SecretAccessKeyAPI Key 模式:使用 API Key": "AK/SK mode uses AccessKey and SecretAccessKey; API Key mode uses an API Key",
"API Key 模式下不支持批量创建": "Batch creation not supported in API Key mode",
"API 地址和相关配置": "API URL and related configuration",
"API 密钥": "API Key",
@@ -60,17 +67,25 @@
"Client ID": "Client ID",
"Client Secret": "Client Secret",
"common.changeLanguage": "Change Language",
"Creem API 密钥,敏感信息不显示": "Creem API key, sensitive information not displayed",
"Creem Setting Tips": "Creem only supports preset fixed-amount products. These products and their prices need to be created and configured in advance on the Creem website, so custom dynamic amount top-ups are not supported. Configure the product name and price on Creem, obtain the Product Id, and then fill it in for the product below. Set the top-up amount and display price for this product in the new API.",
"Creem 介绍": "Creem is the payment partner you always deserved, we strive for simplicity and straightforwardness on our APIs.",
"Creem 充值": "Creem Recharge",
"Creem 设置": "Creem Setting",
"default为默认设置可单独设置每个分类的安全等级": "\"default\" is the default setting, and each category can be set separately",
"default为默认设置可单独设置每个模型的版本": "\"default\" is the default setting, and each model can be set separately",
"Dify渠道只适配chatflow和agent并且agent不支持图片": "Dify channel only supports chatflow and agent, and agent does not support images!",
"Discord": "Discord",
"Discord Client ID": "Discord Client ID",
"Discord Client Secret": "Discord Client Secret",
"Discord ID": "Discord ID",
"EUR (欧元)": "EUR (Euro)",
"false": "false",
"Gemini安全设置": "Gemini safety settings",
"Gemini思考适配 BudgetTokens = MaxTokens * BudgetTokens 百分比": "Gemini thinking adaptation BudgetTokens = MaxTokens * BudgetTokens percentage",
"Gemini思考适配设置": "Gemini thinking adaptation settings",
"Gemini版本设置": "Gemini version settings",
"Gemini设置": "Gemini settings",
"启用FunctionCall思维签名填充": "Enable FunctionCall thoughtSignature fill",
"仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature": "Fill thoughtSignature only for Gemini/Vertex channels using the OpenAI format",
"GitHub": "GitHub",
"GitHub Client ID": "GitHub Client ID",
"GitHub Client Secret": "GitHub Client Secret",
@@ -110,6 +125,7 @@
"Ping间隔": "Ping Interval (seconds)",
"price_xxx 的商品价格 ID新建产品后可获得": "Product price ID for price_xxx, available after creating new product",
"Reasoning Effort": "Reasoning Effort",
"Recharge Quota": "Recharge Quota",
"safety_identifier 字段用于帮助 OpenAI 识别可能违反使用政策的应用程序用户。默认关闭以保护用户隐私": "The safety_identifier field helps OpenAI identify application users who may violate usage policies. Disabled by default to protect user privacy",
"service_tier 字段用于指定服务层级,允许透传可能导致实际计费高于预期。默认关闭以避免额外费用": "The service_tier field is used to specify service level. Allowing pass-through may result in higher billing than expected. Disabled by default to avoid extra charges",
"sk_xxx 或 rk_xxx 的 Stripe 密钥,敏感信息不显示": "Stripe key for sk_xxx or rk_xxx, sensitive information not displayed",
@@ -135,7 +151,9 @@
"Uptime Kuma地址": "Uptime Kuma Address",
"Uptime Kuma监控分类管理可以配置多个监控分类用于服务状态展示最多20个": "Uptime Kuma monitoring category management, you can configure multiple monitoring categories for service status display (maximum 20)",
"URL链接": "URL Link",
"USD (美元)": "USD (US Dollar)",
"User Info Endpoint": "User Info Endpoint",
"Webhook 密钥": "Webhook Secret",
"Webhook 签名密钥": "Webhook Signature Key",
"Webhook地址": "Webhook URL",
"Webhook地址必须以https://开头": "Webhook URL must start with https://",
@@ -160,6 +178,7 @@
"上一步": "Previous",
"上次保存: ": "Last saved: ",
"上游倍率同步": "Upstream ratio synchronization",
"上游返回": "Upstream response",
"下一个表单块": "Next form block",
"下一步": "Next",
"下午好": "Good afternoon",
@@ -208,6 +227,12 @@
"主页链接填": "Enter homepage link",
"之前的所有日志": "All previous logs",
"二步验证已重置": "Two-factor authentication has been reset",
"产品ID": "Product ID",
"产品ID已存在": "Product ID already exists",
"产品名称": "Product Name",
"产品配置": "Product Configuration",
"产品配置错误,请联系管理员": "Product configuration error, please contact the administrator",
"仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature": "Fill thoughtSignature only for Gemini/Vertex channels using the OpenAI format",
"仅会覆盖你勾选的字段,未勾选的字段保持本地不变。": "Only selected fields will be overwritten, unselected fields remain unchanged.",
"仅供参考,以实际扣费为准": "For reference only, actual deduction shall prevail",
"仅保存": "Save Only",
@@ -258,6 +283,8 @@
"余额": "Balance",
"余额充值管理": "Balance recharge management",
"你似乎并没有修改什么": "You seem to have not modified anything",
"你可以在“自定义模型名称”处手动添加它们,然后点击填入后再提交,或者直接使用下方操作自动处理。": "You can manually add them under “Custom model names”, click Fill and submit, or use the actions below to handle them automatically.",
"使用 Discord 继续": "Continue with Discord",
"使用 GitHub 继续": "Continue with GitHub",
"使用 JSON 对象格式,格式为:{\"组名\": [最多请求次数, 最多请求完成次数]}": "Use JSON object format, format: {\"group_name\": [max_requests, max_completions]}",
"使用 LinuxDO 继续": "Continue with LinuxDO",
@@ -280,12 +307,16 @@
"例如: socks5://user:pass@host:port": "e.g.: socks5://user:pass@host:port",
"例如0001": "e.g.: 0001",
"例如1000": "e.g.: 1000",
"例如100000": "e.g.: 100000",
"例如2就是最低充值2$": "e.g.: 2, means minimum top-up is $2",
"例如2000": "e.g.: 2000",
"例如4.99": "e.g.: 4.99",
"例如7就是7元/美金": "e.g.: 7, means 7 yuan per USD",
"例如example.com": "e.g.: example.com",
"例如https://yourdomain.com": "e.g.: https://yourdomain.com",
"例如preview": "e.g.: preview",
"例如prod_6I8rBerHpPxyoiU9WK4kot": "e.g.: prod_6I8rBerHpPxyoiU9WK4kot",
"例如:基础套餐": "e.g.: Basic Package",
"例如发卡网站的购买链接": "E.g., purchase link from card issuing website",
"供应商": "Provider",
"供应商介绍": "Provider introduction",
@@ -298,6 +329,7 @@
"侧边栏管理(全局控制)": "Sidebar Management (Global Control)",
"侧边栏设置保存成功": "Sidebar settings saved successfully",
"保存": "Save",
"保存 Discord OAuth 设置": "Save Discord OAuth Settings",
"保存 GitHub OAuth 设置": "Save GitHub OAuth Settings",
"保存 Linux DO OAuth 设置": "Save Linux DO OAuth Settings",
"保存 OIDC 设置": "Save OIDC Settings",
@@ -350,6 +382,7 @@
"允许的IP一行一个不填写则不限制": "Allowed IPs, one per line, not filled in means no restrictions",
"允许的端口": "Allowed Ports",
"允许访问私有IP地址127.0.0.1、192.168.x.x等内网地址": "Allow access to private IP addresses (127.0.0.1, 192.168.x.x and other internal addresses)",
"允许通过 Discord 账户登录 & 注册": "Allow login & registration via Discord account",
"允许通过 GitHub 账户登录 & 注册": "Allow login & registration via GitHub account",
"允许通过 Linux DO 账户登录 & 注册": "Allow login & registration via Linux DO account",
"允许通过 OIDC 进行登录": "Allow login via OIDC",
@@ -406,8 +439,10 @@
"共 {{count}} 个密钥_one": "{{count}} key",
"共 {{count}} 个密钥_other": "{{count}} keys",
"共 {{count}} 个模型": "{{count}} models",
"共 {{count}} 个模型_one": "{{count}} model",
"共 {{count}} 个模型_other": "{{count}} models",
"共 {{total}} 项,当前显示 {{start}}-{{end}} 项": "{{total}} items total, showing {{start}}-{{end}} items",
"关": "close",
"关": "Off",
"关于": "About",
"关于我们": "About Us",
"关于系统的详细信息": "Detailed information about the system",
@@ -422,6 +457,7 @@
"其他注册选项": "Other registration options",
"其他登录选项": "Other login options",
"其他设置": "Other Settings",
"其他详情": "Other details",
"内容": "Content",
"内容较大,已启用性能优化模式": "Content is large, performance optimization mode enabled",
"内容较大,部分功能可能受限": "Content is large, some features may be limited",
@@ -438,6 +474,7 @@
"分组倍率设置": "Group ratio settings",
"分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{\"vip\": 0.5, \"test\": 1},表示 vip 分组的倍率为 0.5test 分组的倍率为 1": "Group ratio settings, you can add new groups or modify existing group ratios here, format as JSON string, e.g.: {\"vip\": 0.5, \"test\": 1}, indicating vip group ratio is 0.5, test group ratio is 1",
"分组特殊倍率": "Group special ratio",
"分组特殊可用分组": "Available special groups",
"分组设置": "Group settings",
"分组速率配置优先级高于全局速率限制。": "Group rate configuration priority is higher than global rate limit.",
"分组速率限制": "Group rate limit",
@@ -450,6 +487,7 @@
"划转邀请额度": "Transfer invitation quota",
"划转金额最低为": "The minimum transfer amount is",
"划转额度": "Transfer amount",
"列出的模型将不会自动添加或移除-thinking/-nothinking 后缀": "Models in this list will not automatically add or remove the -thinking/-nothinking suffix.",
"列设置": "Column settings",
"创建令牌默认选择auto分组初始令牌也将设为auto否则留空为用户默认分组": "Create token with auto group by default, initial token will also be set to auto (otherwise leave blank for user default group)",
"创建失败": "Creation failed",
@@ -550,11 +588,13 @@
"启用 Prompt 检查": "Enable Prompt check",
"启用2FA失败": "Failed to enable Two-Factor Authentication",
"启用Claude思考适配-thinking后缀": "Enable Claude thinking adaptation (-thinking suffix)",
"启用FunctionCall思维签名填充": "Enable FunctionCall thoughtSignature fill",
"启用Gemini思考后缀适配": "Enable Gemini thinking suffix adaptation",
"启用Ping间隔": "Enable Ping interval",
"启用SMTP SSL": "Enable SMTP SSL",
"启用SSRF防护推荐开启以保护服务器安全": "Enable SSRF Protection (Recommended for server security)",
"启用全部": "Enable all",
"启用后将使用 Creem Test Mode": "Use Creem Test Mode after enabling",
"启用密钥失败": "Failed to enable key",
"启用屏蔽词过滤功能": "Enable sensitive word filtering function",
"启用所有密钥失败": "Failed to enable all keys",
@@ -563,9 +603,6 @@
"启用绘图功能": "Enable drawing function",
"启用请求体透传功能": "Enable request body pass-through functionality",
"启用请求透传": "Enable request pass-through",
"禁用思考处理的模型列表": "Models skipping thinking handling",
"列出的模型将不会自动添加或移除-thinking/-nothinking 后缀": "Models in this list will not automatically add or remove the -thinking/-nothinking suffix.",
"请输入JSON数组如 [\"model-a\",\"model-b\"]": "Enter a JSON array, e.g. [\"model-a\",\"model-b\"]",
"启用额度消费日志记录": "Enable quota consumption logging",
"启用验证": "Enable Authentication",
"周": "week",
@@ -638,6 +675,7 @@
"多密钥渠道操作项目组": "Multi-key channel operation project group",
"多密钥管理": "Multi-key management",
"多种充值方式,安全便捷": "Multiple recharge methods, safe and convenient",
"大模型接口网关": "LLM API Gateway",
"天": "day",
"天前": "days ago",
"失败": "Failed",
@@ -699,6 +737,7 @@
"密钥输入方式": "Key input method",
"密钥预览": "Key preview",
"对于官方渠道new-api已经内置地址除非是第三方代理站点或者Azure的特殊接入地址否则不需要填写": "For official channels, the new-api has a built-in address. Unless it is a third-party proxy site or a special Azure access address, there is no need to fill it in",
"对免费模型启用预消耗": "Enable pre-consumption for free models",
"对域名启用 IP 过滤(实验性)": "Enable IP filtering for domains (experimental)",
"对外运营模式": "Default mode",
"导入": "Import",
@@ -722,6 +761,7 @@
"屏蔽词过滤设置": "Sensitive word filtering settings",
"展开": "Expand",
"展开更多": "Expand more",
"展示价格": "Display Pricing",
"左侧边栏个人设置": "Personal settings in left sidebar",
"已为 {{count}} 个模型设置{{type}}_one": "Set {{type}} for {{count}} model",
"已为 {{count}} 个模型设置{{type}}_other": "Set {{type}} for {{count}} models",
@@ -734,6 +774,8 @@
"已切换至最优倍率视图,每个模型使用其最低倍率分组": "Switched to the optimal ratio view, each model uses its lowest ratio group",
"已初始化": "Initialized",
"已删除 {{count}} 个令牌!": "Deleted {{count}} tokens!",
"已删除 {{count}} 个令牌_one": "Deleted {{count}} token!",
"已删除 {{count}} 个令牌_other": "Deleted {{count}} tokens!",
"已删除 {{count}} 条失效兑换码_one": "Deleted {{count}} expired redemption code",
"已删除 {{count}} 条失效兑换码_other": "Deleted {{count}} expired redemption codes",
"已删除 ${data} 个通道!": "Deleted ${data} channels!",
@@ -771,6 +813,7 @@
"已绑定": "Bound",
"已绑定渠道": "Bound channels",
"已耗尽": "Exhausted",
"已解锁豆包自定义 API 地址编辑": "Custom Doubao API address editing unlocked",
"已过期": "Expired",
"已选择 {{count}} 个模型_one": "Selected {{count}} model",
"已选择 {{count}} 个模型_other": "Selected {{count}} models",
@@ -788,10 +831,11 @@
"应用覆盖": "Apply overwrite",
"建立连接时发生错误": "Error occurred while establishing connection",
"建议在生产环境中使用 MySQL 或 PostgreSQL 数据库,或确保 SQLite 数据库文件已映射到宿主机的持久化存储。": "It is recommended to use MySQL or PostgreSQL databases in production environments, or ensure that the SQLite database file is mapped to the persistent storage of the host machine.",
"开": "open",
"开": "On",
"开启之后会清除用户提示词中的": "After enabling, the user prompt will be cleared",
"开启之后将上游地址替换为服务器地址": "After enabling, the upstream address will be replaced with the server address",
"开启后,仅\"消费\"和\"错误\"日志将记录您的客户端IP地址": "After enabling, only \"consumption\" and \"error\" logs will record your client IP address",
"开启后对免费模型倍率为0或者价格为0的模型也会预消耗额度": "After enabling, free models (ratio 0 or price 0) will also pre-consume quota",
"开启后将定期发送ping数据保持连接活跃": "After enabling, ping data will be sent periodically to keep the connection active",
"开启后,所有请求将直接透传给上游,不会进行任何处理(重定向和渠道适配也将失效),请谨慎开启": "When enabled, all requests will be directly forwarded to the upstream without any processing (redirects and channel adaptation will also be disabled). Please enable with caution.",
"开启后不限制:必须设置模型倍率": "After enabling, no limit: must set model ratio",
@@ -891,6 +935,7 @@
"按倍率类型筛选": "Filter by ratio type",
"按倍率设置": "Set by ratio",
"按次计费": "Pay per view",
"按照如下格式输入AccessKey|SecretAccessKey|Region": "Enter in the format: AccessKey|SecretAccessKey|Region",
"按量计费": "Pay as you go",
"按顺序替换content中的变量占位符": "Replace variable placeholders in content in order",
"换脸": "Face swap",
@@ -910,6 +955,13 @@
"提交结果": "Results",
"提升": "Promote",
"提示": "Prompt",
"提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}}": "Prompt {{input}} tokens / 1M tokens * {{symbol}}{{price}}",
"视频无法在当前浏览器中播放,这可能是由于:": "The video cannot be played in this browser, possibly because:",
"• 视频服务商的跨域限制": "• Cross-origin limitations from the video provider",
"• 需要特定的请求头或认证": "• Specific headers or authentication are required",
"• 防盗链保护机制": "• Hotlink protection mechanisms",
"在新标签页中打开": "Open in new tab",
"复制链接": "Copy link",
"提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "Prompt {{input}} tokens / 1M tokens * {{symbol}}{{price}} + Completion {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"提示 {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * {{symbol}}{{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "Prompt {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + Cache {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + Cache creation {{cacheCreationInput}} tokens / 1M tokens * {{symbol}}{{cacheCreationPrice}} + Completion {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"提示:如需备份数据,只需复制上述目录即可": "Tip: To back up data, simply copy the directory above",
@@ -1018,6 +1070,7 @@
"是否为企业账户": "Is it an enterprise account?",
"是否同时重置对话消息?选择\"是\"将清空所有对话记录并恢复默认示例;选择\"否\"将保留当前对话记录。": "Reset conversation messages at the same time? Selecting \"Yes\" will clear all conversation records and restore default examples; selecting \"No\" will retain current conversation records.",
"是否将该订单标记为成功并为用户入账?": "Mark this order as successful and credit the user?",
"是否确认充值?": "Confirm the recharge?",
"是否自动禁用": "Whether to automatically disable",
"是否要求指纹/面容等生物识别": "Whether to require fingerprint/face recognition",
"显示倍率": "Show ratio",
@@ -1035,6 +1088,7 @@
"智能熔断": "Smart fallback",
"智谱": "Zhipu AI",
"暂无API信息": "No API information",
"暂无产品配置": "No product configuration",
"暂无保存的配置": "No saved configuration",
"暂无充值记录": "No recharge records",
"暂无公告": "No Notice",
@@ -1060,6 +1114,7 @@
"更多参数请参考": "For more parameters, please refer to",
"更好的价格,更好的稳定性,只需要将模型基址替换为:": "Better price, better stability, no subscription required, just replace the model BASE URL with: ",
"更新": "Update",
"更新 Creem 设置": "Update Creem Settings",
"更新 Stripe 设置": "Update Stripe settings",
"更新SSRF防护设置": "Update SSRF Protection Settings",
"更新Worker设置": "Update Worker Settings",
@@ -1106,6 +1161,7 @@
"未配置的模型列表": "Models not configured",
"本地": "Local",
"本地数据存储": "Local data storage",
"本地计费": "Local billing",
"本设备:手机指纹/面容外接USB安全密钥": "Built-in: phone fingerprint/face, External: USB security key",
"本设备内置": "Built-in device",
"本项目根据": "This project is licensed under the ",
@@ -1115,6 +1171,7 @@
"条 - 第": "to",
"条,共": "of",
"条日志已清理!": "logs have been cleared!",
"来自模型重定向,尚未加入模型列表": "From model redirect, not yet added to the model list",
"查看": "Check",
"查看图片": "View pictures",
"查看密钥": "View key",
@@ -1145,6 +1202,7 @@
"模型价格 {{symbol}}{{price}}{{ratioType}} {{ratio}}": "Model price {{symbol}}{{price}}, {{ratioType}} {{ratio}}",
"模型价格:{{symbol}}{{price}} * {{ratioType}}{{ratio}} = {{symbol}}{{total}}": "Model price: {{symbol}}{{price}} * {{ratioType}}: {{ratio}} = {{symbol}}{{total}}",
"模型倍率": "Model ratio",
"模型倍率 {{modelRatio}}": "Model ratio {{modelRatio}}",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}": "Model ratio {{modelRatio}}, cache ratio {{cacheRatio}}, completion ratio {{completionRatio}}, {{ratioType}} {{ratio}}",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}Web 搜索调用 {{webSearchCallCount}} 次": "Model ratio {{modelRatio}}, cache ratio {{cacheRatio}}, completion ratio {{completionRatio}}, {{ratioType}} {{ratio}}, Web search called {{webSearchCallCount}} times",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}},图片输入倍率 {{imageRatio}}{{ratioType}} {{ratio}}": "Model ratio {{modelRatio}}, cache ratio {{cacheRatio}}, completion ratio {{completionRatio}}, image input ratio {{imageRatio}}, {{ratioType}} {{ratio}}",
@@ -1167,6 +1225,7 @@
"模型数据分析": "Model Data Analysis",
"模型映射必须是合法的 JSON 格式!": "Model mapping must be in valid JSON format!",
"模型更新成功!": "Model updated successfully!",
"模型未加入列表,可能无法调用": "Model not in the list; requests may fail",
"模型消耗分布": "Model consumption distribution",
"模型消耗趋势": "Model consumption trend",
"模型版本": "Model version",
@@ -1182,15 +1241,18 @@
"模型选择和映射设置": "Model selection and mapping settings",
"模型配置": "Model Configuration",
"模型重定向": "Model mapping",
"模型重定向里的下列模型尚未添加到“模型”列表,调用时会因为缺少可用模型而失败:": "The following models from the redirect have not been added to the “Models” list and requests will fail due to no available model:",
"模型限制列表": "Model restrictions list",
"模板示例": "Template example",
"模糊搜索模型名称": "Fuzzy search model name",
"次": "times",
"欢迎使用,请完成以下设置以开始使用系统": "Welcome! Please complete the following settings to start using the system",
"欧元": "EUR",
"正在处理大内容...": "Processing large content...",
"正在提交": "Submitting",
"正在构造请求体预览...": "Constructing request body preview...",
"正在测试第 ${current} - ${end} 个模型 (共 ${total} 个)": "Testing model ${current} - ${end} (total ${total})",
"正在跳转 GitHub...": "Redirecting to GitHub...",
"正在跳转...": "Redirecting...",
"此代理仅用于图片请求转发Webhook通知发送等AI API请求仍然由服务器直接发出可在渠道设置中单独配置代理": "This proxy is only used for image request forwarding, webhook notification sending, etc. AI API requests are still sent directly by the server, and proxy can be configured separately in channel settings",
"此修改将不可逆": "This modification will be irreversible",
@@ -1242,6 +1304,7 @@
"测试失败": "Test failed",
"测试所有渠道的最长响应时间": "Maximum response time for testing all channels",
"测试所有通道": "Test all channels",
"测试模式": "Test Mode",
"测速": "Speed Test",
"消息优先级": "Message priority",
"消息优先级范围0-10默认为5": "Message priority, range 0-10, default is 5",
@@ -1257,10 +1320,12 @@
"深色模式": "Dark Mode",
"添加": "Add",
"添加API": "Add API",
"添加产品": "Add Product",
"添加令牌": "Create token",
"添加兑换码": "Add redemption code",
"添加公告": "Add Notice",
"添加分类": "Add Category",
"添加后提交": "Submit after adding",
"添加成功": "Added successfully",
"添加模型": "Add model",
"添加模型区域": "Add model region",
@@ -1318,9 +1383,11 @@
"生成音乐": "generate music",
"用于API调用的身份验证令牌请妥善保管": "Authentication token for API calls, please keep it safe",
"用于配置网络代理,支持 socks5 协议": "Used to configure network proxy, supports socks5 protocol",
"用于验证回调 new-api 的 webhook 请求的密钥,敏感信息不显示": "The key used to validate webhook requests for the callback new-api, sensitive information is not displayed.",
"用以支持基于 WebAuthn 的无密码登录注册": "Support WebAuthn-based passwordless login and registration",
"用以支持用户校验": "To support user verification",
"用以支持系统的邮件发送": "To support the system email sending",
"用以支持通过 Discord 进行登录注册": "Used to support login & registration through Discord",
"用以支持通过 GitHub 进行登录注册": "To support login & registration via GitHub",
"用以支持通过 Linux DO 进行登录注册": "To support login & registration via Linux DO",
"用以支持通过 OIDC 登录,例如 Okta、Auth0 等兼容 OIDC 协议的 IdP": "To support login via OIDC, such as Okta, Auth0 and other IdPs compatible with OIDC protocol",
@@ -1365,6 +1432,7 @@
"的前提下使用。": "for use under the following conditions:",
"监控设置": "Monitoring Settings",
"目标用户:{{username}}": "Target user: {{username}}",
"直接提交": "Submit directly",
"相关项目": "Related Projects",
"相当于删除用户,此修改将不可逆": "Equivalent to deleting the user, this modification is irreversible",
"矛盾": "Conflict",
@@ -1385,6 +1453,7 @@
"确定清除所有失效兑换码?": "Are you sure you want to clear all invalid redemption codes?",
"确定要修改所有子渠道优先级为 ": "Confirm to modify all sub-channel priorities to ",
"确定要修改所有子渠道权重为 ": "Confirm to modify all sub-channel weights to ",
"确定要充值 $": "Confirm to recharge $",
"确定要删除供应商 \"{{name}}\" 吗?此操作不可撤销。": "Are you sure you want to delete supplier \"{{name}}\"? This operation is irreversible.",
"确定要删除所有已自动禁用的密钥吗?": "Are you sure you want to delete all automatically disabled keys?",
"确定要删除所选的 {{count}} 个令牌吗_one": "Are you sure you want to delete the selected {{count}} token?",
@@ -1434,6 +1503,7 @@
"禁用原因": "Disable reason",
"禁用后的影响:": "Impact after disabling:",
"禁用密钥失败": "Failed to disable key",
"禁用思考处理的模型列表": "Models skipping thinking handling",
"禁用所有密钥失败": "Failed to disable all keys",
"禁用时间": "Disable time",
"私有IP访问详细说明": "⚠️ Security Warning: Enabling this allows access to internal network resources (localhost, private networks). Only enable if you need to access internal services and understand the security implications.",
@@ -1458,6 +1528,7 @@
"管理员": "Admin",
"管理员区域": "Administrator Area",
"管理员暂时未设置任何关于内容": "The administrator has not set any custom About content yet",
"管理员未开启 Creem 充值!": "The administrator has not enabled Creem recharge!",
"管理员未开启Stripe充值": "Administrator has not enabled Stripe recharge!",
"管理员未开启在线充值!": "The administrator has not enabled online recharge!",
"管理员未开启在线充值功能,请联系管理员开启或使用兑换码充值。": "The administrator has not enabled the online recharge function, please contact the administrator to enable it or recharge with a redemption code.",
@@ -1510,24 +1581,33 @@
"绘图任务记录": "Drawing task records",
"绘图日志": "Drawing Logs",
"绘图设置": "Drawing settings",
"统一的": "The Unified",
"统计Tokens": "Statistical Tokens",
"统计次数": "Statistical count",
"统计额度": "Statistical quota",
"继续": "Continue",
"缓存 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Cache {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (ratio: {{ratio}})",
"缓存 Tokens": "Cache Tokens",
"缓存: {{cacheRatio}}": "Cache: {{cacheRatio}}",
"缓存价格:{{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})": "Cache price: {{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (Cache ratio: {{cacheRatio}})",
"缓存价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})": "Cache price: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (Cache ratio: {{cacheRatio}})",
"缓存倍率": "Cache ratio",
"缓存倍率 {{cacheRatio}}": "Cache ratio {{cacheRatio}}",
"缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Cache creation {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (ratio: {{ratio}})",
"缓存创建 Tokens": "Cache Creation Tokens",
"缓存创建: {{cacheCreationRatio}}": "Cache creation: {{cacheCreationRatio}}",
"缓存创建: 5m {{cacheCreationRatio5m}}": "Cache creation: 5m {{cacheCreationRatio5m}}",
"缓存创建: 1h {{cacheCreationRatio1h}}": "Cache creation: 1h {{cacheCreationRatio1h}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}}": "Cache creation multiplier 5m {{cacheCreationRatio5m}}",
"缓存创建倍率 1h {{cacheCreationRatio1h}}": "Cache creation multiplier 1h {{cacheCreationRatio1h}}",
"缓存创建: 5m {{cacheCreationRatio5m}}": "Cache creation: 5m {{cacheCreationRatio5m}}",
"缓存创建: 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}": "Cache creation: 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}",
"缓存创建价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})": "Cache creation price: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (Cache creation ratio: {{cacheCreationRatio}})",
"缓存创建价格合计5m {{symbol}}{{five}} + 1h {{symbol}}{{one}} = {{symbol}}{{total}} / 1M tokens": "Cache creation price total: 5m {{symbol}}{{five}} + 1h {{symbol}}{{one}} = {{symbol}}{{total}} / 1M tokens",
"缓存创建倍率 {{cacheCreationRatio}}": "Cache creation ratio {{cacheCreationRatio}}",
"缓存创建倍率 1h {{cacheCreationRatio1h}}": "Cache creation multiplier 1h {{cacheCreationRatio1h}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}}": "Cache creation multiplier 5m {{cacheCreationRatio5m}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}": "Cache creation ratio 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}",
"编辑": "Edit",
"编辑API": "Edit API",
"编辑产品": "Edit Product",
"编辑供应商": "Edit Provider",
"编辑公告": "Edit Notice",
"编辑公告内容": "Edit announcement content",
@@ -1545,6 +1625,7 @@
"网站域名标识": "Website Domain ID",
"网络错误": "Network Error",
"置信度": "Confidence",
"美元": "US Dollar",
"聊天": "Chat",
"聊天会话管理": "Chat session management",
"聊天区域": "Chat Area",
@@ -1591,6 +1672,7 @@
"获取金额失败": "Failed to get amount",
"获取验证码": "Get Verification Code",
"补全": "Completion",
"补全 {{completion}} tokens / 1M tokens * {{symbol}}{{price}}": "Completion {{completion}} tokens / 1M tokens * {{symbol}}{{price}}",
"补全价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "Completion price: {{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (Completion ratio: {{completionRatio}})",
"补全价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens": "Completion price: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens",
"补全倍率": "Completion ratio",
@@ -1607,6 +1689,7 @@
"解析密钥文件失败: {{msg}}": "Failed to parse key file: {{msg}}",
"解绑 Passkey": "Remove Passkey",
"解绑后将无法使用 Passkey 登录,确定要继续吗?": "After unbinding, you will not be able to login with Passkey. Are you sure you want to continue?",
"计费模式": "Billing mode",
"计费类型": "Billing type",
"计费过程": "Billing process",
"订单号": "Order No.",
@@ -1670,6 +1753,7 @@
"请前往个人设置 → 安全设置进行配置。": "Please go to Personal Settings → Security Settings to configure.",
"请勿过度信任此功能IP可能被伪造": "Do not over-trust this feature, IP can be spoofed",
"请在系统设置页面编辑分组倍率以添加新的分组:": "Please edit Group ratios in system settings to add new groups:",
"请填写完整的产品信息": "Please fill in complete product information",
"请填写完整的管理员账号信息": "Please fill in the complete administrator account information",
"请填写密钥": "Please enter the key",
"请填写渠道名称和渠道密钥!": "Please enter channel name and key!",
@@ -1684,10 +1768,11 @@
"请求失败": "Request failed",
"请求头覆盖": "Request header override",
"请求并计费模型": "Request and charge model",
"请求路径": "Request path",
"请求时长: ${time}s": "Request time: ${time}s",
"请求次数": "Number of Requests",
"请求结束后多退少补": "Adjust after request completion",
"请求超时,请刷新页面后重新发起 GitHub 登录": "Request timed out, please refresh and restart GitHub login",
"请求路径": "Request path",
"请求预扣费额度": "Pre-deduction quota for requests",
"请点击我": "Please click me",
"请确认以下设置信息,点击\"初始化系统\"开始配置": "Please confirm the following settings information, click \"Initialize system\" to start configuration",
@@ -1704,6 +1789,8 @@
"请至少选择一个模型": "Please select at least one model",
"请至少选择一个模型!": "Please select at least one model!",
"请至少选择一个渠道": "Please select at least one channel",
"请输入 API Key一行一个格式APIKey|Region": "Enter API Key, one per line, format: APIKey|Region",
"请输入 API Key格式APIKey|Region": "Enter API Key, format: APIKey|Region",
"请输入 AZURE_OPENAI_ENDPOINT例如https://docs-test-001.openai.azure.com": "Please enter AZURE_OPENAI_ENDPOINT, e.g.: https://docs-test-001.openai.azure.com",
"请输入 JSON 格式的密钥内容,例如:\n{\n \"type\": \"service_account\",\n \"project_id\": \"your-project-id\",\n \"private_key_id\": \"...\",\n \"private_key\": \"...\",\n \"client_email\": \"...\",\n \"client_id\": \"...\",\n \"auth_uri\": \"...\",\n \"token_uri\": \"...\",\n \"auth_provider_x509_cert_url\": \"...\",\n \"client_x509_cert_url\": \"...\"\n}": "Please enter the key content in JSON format, for example:\n{\n \"type\": \"service_account\",\n \"project_id\": \"your-project-id\",\n \"private_key_id\": \"...\",\n \"private_key\": \"...\",\n \"client_email\": \"...\",\n \"client_id\": \"...\",\n \"auth_uri\": \"...\",\n \"token_uri\": \"...\",\n \"auth_provider_x509_cert_url\": \"...\",\n \"client_x509_cert_url\": \"...\"\n}",
"请输入 OIDC 的 Well-Known URL": "Please enter the Well-Known URL for OIDC",
@@ -1715,6 +1802,7 @@
"请输入Gotify应用令牌": "Please enter Gotify application token",
"请输入Gotify服务器地址": "Please enter Gotify server address",
"请输入Gotify服务器地址例如: https://gotify.example.com": "Please enter Gotify server address, e.g.: https://gotify.example.com",
"请输入JSON数组如 [\"model-a\",\"model-b\"]": "Enter a JSON array, e.g. [\"model-a\",\"model-b\"]",
"请输入Uptime Kuma地址": "Please enter the Uptime Kuma address",
"请输入Uptime Kuma服务地址https://status.example.com": "Please enter the Uptime Kuma service address, such as: https://status.example.com",
"请输入URL链接": "Please enter the URL link",
@@ -1745,6 +1833,7 @@
"请输入密码": "Please enter password",
"请输入密钥": "Please enter the key",
"请输入密钥,一行一个": "Please enter the key, one per line",
"请输入密钥一行一个格式AccessKey|SecretAccessKey|Region": "Enter keys one per line, format: AccessKey|SecretAccessKey|Region",
"请输入密钥!": "Please enter the key!",
"请输入您的密码": "Please enter your password",
"请输入您的用户名以确认删除": "Please enter your username to confirm deletion",
@@ -1799,6 +1888,7 @@
"请输入验证码或备用码": "Please enter verification code or backup code",
"请输入默认 API 版本例如2025-04-01-preview": "Please enter default API version, e.g.: 2025-04-01-preview.",
"请选择API地址": "Please select API address",
"请选择产品": "Select a product",
"请选择你的复制方式": "Please select your copy method",
"请选择使用模式": "Please select the usage mode",
"请选择分组": "Please select a group",
@@ -1839,6 +1929,7 @@
"账户绑定": "Account Binding",
"账户绑定、安全设置和身份验证": "Account binding, security settings and identity verification",
"账户统计": "Account statistics",
"货币": "Currency",
"货币单位": "Currency Unit",
"购买兑换码": "Buy redemption code",
"资源消耗": "Resource Consumption",
@@ -1880,15 +1971,17 @@
"输入验证码": "Enter Verification Code",
"输入验证码完成设置": "Enter verification code to complete setup",
"输出": "Output",
"输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}": "Output {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}",
"输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}": "Output {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}}",
"输出价格": "Output Price",
"输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "Output price: {{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (Completion ratio: {{completionRatio}})",
"输出倍率 {{completionRatio}}": "Output ratio {{completionRatio}}",
"边栏设置": "Sidebar Settings",
"过期时间": "Expiration time",
"过期时间不能早于当前时间!": "Expiration time cannot be earlier than the current time!",
"过期时间快捷设置": "Expiration time quick settings",
"过期时间格式错误!": "Expiration time format error!",
"运营设置": "Operation Settings",
"返回修改": "Go back and edit",
"返回登录": "Return to Login",
"这是重复键中的最后一个,其值将被使用": "This is the last one among duplicate keys, and its value will be used",
"进度": "Progress",
@@ -1904,6 +1997,7 @@
"适用于为多个用户提供服务的场景": "Suitable for scenarios where multiple users are provided.",
"适用于展示系统功能的场景,提供基础功能演示": "Suitable for scenarios where the system functions are displayed, providing basic feature demonstrations.",
"适配 -thinking、-thinking-预算数字 和 -nothinking 后缀": "Adapt to -thinking, -thinking-budget number, and -nothinking suffixes",
"选择充值套餐": "Choose a top-up package",
"选择充值额度": "Select recharge amount",
"选择分组": "Select group",
"选择同步来源": "Select sync source",
@@ -1966,6 +2060,7 @@
"部分渠道测试失败:": "Some channels failed to test: ",
"部署地区": "Deployment Region",
"配置": "Configure",
"配置 Discord OAuth": "Configure Discord OAuth",
"配置 GitHub OAuth App": "Configure GitHub OAuth App",
"配置 Linux DO OAuth": "Configure Linux DO OAuth",
"配置 OIDC": "Configure OIDC",
@@ -2004,9 +2099,10 @@
"重试": "Retry",
"钱包管理": "Wallet Management",
"链接中的{key}将自动替换为sk-xxxx{address}将自动替换为系统设置的服务器地址,末尾不带/和/v1": "The {key} in the link will be automatically replaced with sk-xxxx, the {address} will be automatically replaced with the server address in system settings, and the end will not have / and /v1",
"错误": "Error",
"错误": "errors",
"键为分组名称,值为另一个 JSON 对象,键为分组名称,值为该分组的用户的特殊分组倍率,例如:{\"vip\": {\"default\": 0.5, \"test\": 1}},表示 vip 分组的用户在使用default分组的令牌时倍率为0.5使用test分组时倍率为1": "The key is the group name, and the value is another JSON object. The key is the group name, and the value is the special group ratio for users in that group. For example: {\"vip\": {\"default\": 0.5, \"test\": 1}} means that users in the vip group have a ratio of 0.5 when using tokens from the default group, and a ratio of 1 when using tokens from the test group",
"键为原状态码,值为要复写的状态码,仅影响本地判断": "The key is the original status code, and the value is the status code to override, only affects local judgment",
"键为用户分组名称,值为操作映射对象。内层键以\"+:\"开头表示添加指定分组(键值为分组名称,值为描述),以\"-:\"开头表示移除指定分组(键值为分组名称),不带前缀的键直接添加该分组。例如:{\"vip\": {\"+:premium\": \"高级分组\", \"special\": \"特殊分组\", \"-:default\": \"默认分组\"}},表示 vip 分组的用户可以使用 premium 和 special 分组,同时移除 default 分组的访问权限": "Keys are user group names and values are operation mappings. Inner keys prefixed with \"+:\" add the specified group (key is the group name, value is the description); keys prefixed with \"-:\" remove the specified group; keys without a prefix add that group directly. Example: {\"vip\": {\"+:premium\": \"Advanced group\", \"special\": \"Special group\", \"-:default\": \"Default group\"}} means vip users can access the premium and special groups while removing access to the default group.",
"键为端点类型,值为路径和方法对象": "The key is the endpoint type, the value is the path and method object",
"键为请求中的模型名称,值为要替换的模型名称": "Key is the model name in the request, value is the model name to replace",
"键名": "Key name",
@@ -2080,39 +2176,6 @@
"默认区域,如: us-central1": "Default region, e.g.: us-central1",
"默认折叠侧边栏": "Default collapse sidebar",
"默认测试模型": "Default Test Model",
"默认补全倍率": "Default completion ratio",
"选择充值套餐": "Choose a top-up package",
"Creem 设置": "Creem Setting",
"Creem 充值": "Creem Recharge",
"Creem 介绍": "Creem is the payment partner you always deserved, we strive for simplicity and straightforwardness on our APIs.",
"Creem Setting Tips": "Creem only supports preset fixed-amount products. These products and their prices need to be created and configured in advance on the Creem website, so custom dynamic amount top-ups are not supported. Configure the product name and price on Creem, obtain the Product Id, and then fill it in for the product below. Set the top-up amount and display price for this product in the new API.",
"Webhook 密钥": "Webhook Secret",
"测试模式": "Test Mode",
"Creem API 密钥,敏感信息不显示": "Creem API key, sensitive information not displayed",
"用于验证回调 new-api 的 webhook 请求的密钥,敏感信息不显示": "The key used to validate webhook requests for the callback new-api, sensitive information is not displayed.",
"启用后将使用 Creem Test Mode": "",
"展示价格": "Display Pricing",
"Recharge Quota": "Recharge Quota",
"产品配置": "Product Configuration",
"产品名称": "Product Name",
"产品ID": "Product ID",
"暂无产品配置": "No product configuration",
"更新 Creem 设置": "Update Creem Settings",
"编辑产品": "Edit Product",
"添加产品": "Add Product",
"例如:基础套餐": "e.g.: Basic Package",
"例如prod_6I8rBerHpPxyoiU9WK4kot": "e.g.: prod_6I8rBerHpPxyoiU9WK4kot",
"货币": "Currency",
"欧元": "EUR",
"USD (美元)": "USD (US Dollar)",
"EUR (欧元)": "EUR (Euro)",
"例如4.99": "e.g.: 4.99",
"例如100000": "e.g.: 100000",
"请填写完整的产品信息": "Please fill in complete product information",
"产品ID已存在": "Product ID already exists",
"统一的": "The Unified",
"大模型接口网关": "LLM API Gateway",
"正在跳转 GitHub...": "Redirecting to GitHub...",
"请求超时,请刷新页面后重新发起 GitHub 登录": "Request timed out, please refresh and restart GitHub login"
"默认补全倍率": "Default completion ratio"
}
}
}

View File

@@ -20,7 +20,9 @@
"[最多请求次数]和[最多请求完成次数]的最大值为2147483647。": "La valeur maximale de [Nombre maximal de requêtes] et [Nombre maximal d'achèvements de requêtes] est 2147483647.",
"[最多请求次数]必须大于等于0[最多请求完成次数]必须大于等于1。": "[Nombre maximal de requêtes] doit être supérieur ou égal à 0, [Nombre maximal d'achèvements de requêtes] doit être supérieur ou égal à 1.",
"{\n \"default\": [200, 100],\n \"vip\": [0, 1000]\n}": "{\n \"default\": [200, 100],\n \"vip\": [0, 1000]\n}",
"{{breakdown}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "{{breakdown}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}": "{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}",
"{{ratioType}} {{ratio}}": "{{ratioType}} {{ratio}}",
"© {{currentYear}}": "© {{currentYear}}",
"| 基于": " | Basé sur ",
"$/1M tokens": "$/1M tokens",
@@ -28,15 +30,20 @@
"0.002-1之间的小数": "Décimal entre 0,002-1",
"0.1以上的小数": "Décimal supérieur à 0,1",
"10 - 最高": "10 - La plus haute",
"1h缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Création du cache 1h {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (ratio : {{ratio}})",
"1h缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (1h缓存创建倍率: {{cacheCreationRatio1h}})": "Prix de création de cache 1h : {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (ratio de création 1h : {{cacheCreationRatio1h}})",
"2 - 低": "2 - Basse",
"2025年5月10日后添加的渠道不需要再在部署的时候移除模型名称中的\".\"": "Après le 10 mai 2025, les canaux ajoutés n'ont plus besoin de supprimer le point dans le nom du modèle lors du déploiement",
"360智脑": "360 AI Brain",
"5 - 正常(默认)": "5 - Normale (par défaut)",
"5m缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Création du cache 5m {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (ratio : {{ratio}})",
"5m缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (5m缓存创建倍率: {{cacheCreationRatio5m}})": "Prix de création de cache 5m : {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (ratio de création 5m : {{cacheCreationRatio5m}})",
"8 - 高": "8 - Haute",
"AGPL v3.0协议": "Licence AGPL v3.0",
"AI 对话": "Conversation IA",
"AI模型测试环境": "Environnement de test de modèle d'IA",
"AI模型配置": "Configuration du modèle d'IA",
"AK/SK 模式:使用 AccessKey 和 SecretAccessKeyAPI Key 模式:使用 API Key": "Mode AK/SK : utiliser AccessKey et SecretAccessKey ; mode API Key : utiliser API Key",
"API Key 模式下不支持批量创建": "Création en lot non prise en charge en mode clé API",
"API 地址和相关配置": "URL de l'API et configuration associée",
"API 密钥": "Clé API",
@@ -62,17 +69,25 @@
"Client ID": "ID client",
"Client Secret": "Secret client",
"common.changeLanguage": "Changer de langue",
"Creem API 密钥,敏感信息不显示": "Clé API Creem, les informations sensibles ne sont pas affichées",
"Creem Setting Tips": "Creem ne prend en charge que des produits à montant fixe préconfigurés. Ces produits et leurs prix doivent être créés et configurés à l'avance sur le site Creem, les recharges à montant dynamique ne sont donc pas prises en charge. Configurez le nom et le prix du produit sur Creem, récupérez l'identifiant du produit, puis remplissez-le ci-dessous. Définissez enfin le montant et le prix affiché dans new-api.",
"Creem 介绍": "Présentation de Creem",
"Creem 充值": "Recharge Creem",
"Creem 设置": "Paramètres Creem",
"default为默认设置可单独设置每个分类的安全等级": "\"default\" est le paramètre par défaut, et chaque catégorie peut être définie séparément",
"default为默认设置可单独设置每个模型的版本": "\"default\" est le paramètre par défaut, et chaque modèle peut être défini séparément",
"Dify渠道只适配chatflow和agent并且agent不支持图片": "Le canal Dify ne prend en charge que chatflow et agent, et l'agent ne prend pas en charge les images !",
"Discord": "Discord",
"Discord Client ID": "ID client Discord",
"Discord Client Secret": "Secret client Discord",
"Discord ID": "ID Discord",
"EUR (欧元)": "EUR (Euro)",
"false": "faux",
"Gemini安全设置": "Paramètres de sécurité Gemini",
"Gemini思考适配 BudgetTokens = MaxTokens * BudgetTokens 百分比": "Adaptation de la pensée Gemini BudgetTokens = MaxTokens * BudgetTokens pourcentage",
"Gemini思考适配设置": "Paramètres d'adaptation de la pensée Gemini",
"Gemini版本设置": "Paramètres de version Gemini",
"Gemini设置": "Paramètres Gemini",
"启用FunctionCall思维签名填充": "Activer le remplissage de thoughtSignature pour FunctionCall",
"仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature": "Remplit thoughtSignature uniquement pour les canaux Gemini/Vertex utilisant le format OpenAI",
"GitHub": "GitHub",
"GitHub Client ID": "ID client GitHub",
"GitHub Client Secret": "Secret client GitHub",
@@ -137,7 +152,9 @@
"Uptime Kuma地址": "Adresse Uptime Kuma",
"Uptime Kuma监控分类管理可以配置多个监控分类用于服务状态展示最多20个": "Gestion des catégories de surveillance Uptime Kuma, vous pouvez configurer plusieurs catégories de surveillance pour l'affichage de l'état du service (maximum 20)",
"URL链接": "Lien URL",
"USD (美元)": "USD (Dollar US)",
"User Info Endpoint": "Point de terminaison des informations utilisateur",
"Webhook 密钥": "Clé Webhook",
"Webhook 签名密钥": "Clé de signature Webhook",
"Webhook地址": "URL du Webhook",
"Webhook地址必须以https://开头": "L'adresse Webhook doit commencer par https://",
@@ -162,6 +179,7 @@
"上一步": "Précédent",
"上次保存: ": "Dernier enregistrement : ",
"上游倍率同步": "Synchronisation du ratio en amont",
"上游返回": "Réponse amont",
"下一个表单块": "Bloc de formulaire suivant",
"下一步": "Suivant",
"下午好": "Bon après-midi",
@@ -210,6 +228,12 @@
"主页链接填": "Remplir le lien de la page d'accueil",
"之前的所有日志": "Tous les journaux précédents",
"二步验证已重置": "L'authentification à deux facteurs a été réinitialisée",
"产品ID": "ID du produit",
"产品ID已存在": "L'ID du produit existe déjà",
"产品名称": "Nom du produit",
"产品配置": "Configuration du produit",
"产品配置错误,请联系管理员": "Erreur de configuration du produit, veuillez contacter l'administrateur",
"仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature": "Remplit thoughtSignature uniquement pour les canaux Gemini/Vertex utilisant le format OpenAI",
"仅会覆盖你勾选的字段,未勾选的字段保持本地不变。": "Seuls les champs sélectionnés seront remplacés, les champs non sélectionnés restent inchangés.",
"仅供参考,以实际扣费为准": "Pour référence uniquement, la déduction réelle prévaudra",
"仅保存": "Enregistrer uniquement",
@@ -260,6 +284,8 @@
"余额": "Solde",
"余额充值管理": "Gestion de la recharge du solde",
"你似乎并没有修改什么": "Vous ne semblez rien avoir modifié",
"你可以在“自定义模型名称”处手动添加它们,然后点击填入后再提交,或者直接使用下方操作自动处理。": "Vous pouvez les ajouter manuellement dans « Noms de modèles personnalisés », cliquer sur Remplir puis soumettre, ou utiliser directement les actions ci-dessous pour les traiter automatiquement.",
"使用 Discord 继续": "Continuer avec Discord",
"使用 GitHub 继续": "Continuer avec GitHub",
"使用 JSON 对象格式,格式为:{\"组名\": [最多请求次数, 最多请求完成次数]}": "Utiliser le format d'objet JSON, au format : {\"nom du groupe\": [nombre maximal de requêtes, nombre maximal d'achèvements de requêtes]}",
"使用 LinuxDO 继续": "Continuer avec LinuxDO",
@@ -282,12 +308,16 @@
"例如: socks5://user:pass@host:port": "par exemple : socks5://user:pass@host:port",
"例如0001": "Par exemple : 0001",
"例如1000": "Par exemple : 1000",
"例如100000": "Ex. : 100000",
"例如2就是最低充值2$": "Par exemple : 2, c'est-à-dire un minimum de 2$ de recharge",
"例如2000": "Par exemple : 2000",
"例如4.99": "Ex. : 4.99",
"例如7就是7元/美金": "Par exemple : 7, c'est-à-dire 7 yuans/dollar",
"例如example.com": "ex: example.com",
"例如https://yourdomain.com": "Par exemple : https://yourdomain.com",
"例如preview": "Par exemple : preview",
"例如prod_6I8rBerHpPxyoiU9WK4kot": "Ex. : prod_6I8rBerHpPxyoiU9WK4kot",
"例如:基础套餐": "Ex. : forfait de base",
"例如发卡网站的购买链接": "Par exemple, lien d'achat sur un site d'émission de cartes",
"供应商": "Fournisseur",
"供应商介绍": "Présentation du fournisseur",
@@ -300,6 +330,7 @@
"侧边栏管理(全局控制)": "Gestion de la barre latérale (contrôle global)",
"侧边栏设置保存成功": "Paramètres de la barre latérale enregistrés avec succès",
"保存": "Enregistrer",
"保存 Discord OAuth 设置": "Enregistrer les paramètres OAuth Discord",
"保存 GitHub OAuth 设置": "Enregistrer les paramètres GitHub OAuth",
"保存 Linux DO OAuth 设置": "Enregistrer les paramètres Linux DO OAuth",
"保存 OIDC 设置": "Enregistrer les paramètres OIDC",
@@ -352,6 +383,7 @@
"允许的IP一行一个不填写则不限制": "Adresses IP autorisées, une par ligne, non remplies signifie aucune restriction",
"允许的端口": "Ports autorisés",
"允许访问私有IP地址127.0.0.1、192.168.x.x等内网地址": "Autoriser l'accès aux adresses IP privées (127.0.0.1, 192.168.x.x et autres adresses de réseau interne)",
"允许通过 Discord 账户登录 & 注册": "Autoriser la connexion et l'inscription via un compte Discord",
"允许通过 GitHub 账户登录 & 注册": "Autoriser la connexion & l'inscription via le compte GitHub",
"允许通过 Linux DO 账户登录 & 注册": "Autoriser la connexion & l'inscription via le compte Linux DO",
"允许通过 OIDC 进行登录": "Autoriser la connexion via OIDC",
@@ -409,6 +441,9 @@
"共 {{count}} 个密钥_many": "{{count}} clés au total",
"共 {{count}} 个密钥_other": "{{count}} clés au total",
"共 {{count}} 个模型": "{{count}} modèles",
"共 {{count}} 个模型_one": "{{count}} modèle",
"共 {{count}} 个模型_many": "{{count}} modèles",
"共 {{count}} 个模型_other": "{{count}} modèles",
"共 {{total}} 项,当前显示 {{start}}-{{end}} 项": "Total {{total}} éléments, affichage actuel {{start}}-{{end}} éléments",
"关": "Fermer",
"关于": "À propos",
@@ -425,6 +460,7 @@
"其他注册选项": "Autres options d'inscription",
"其他登录选项": "Autres options de connexion",
"其他设置": "Autres paramètres",
"其他详情": "Autres détails",
"内容": "Contenu",
"内容较大,已启用性能优化模式": "Le contenu est volumineux, le mode d'optimisation des performances a été activé",
"内容较大,部分功能可能受限": "Le contenu est volumineux, certaines fonctionnalités peuvent être limitées",
@@ -441,6 +477,7 @@
"分组倍率设置": "Paramètres de ratio de groupe",
"分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{\"vip\": 0.5, \"test\": 1},表示 vip 分组的倍率为 0.5test 分组的倍率为 1": "Paramètres de ratio de groupe, vous pouvez ajouter de nouveaux groupes ou modifier le ratio des groupes existants ici, au format de chaîne JSON, par exemple : {\"vip\": 0,5, \"test\": 1}, ce qui signifie que le ratio du groupe vip est 0,5 et celui du groupe test est 1",
"分组特殊倍率": "Ratio spécial de groupe",
"分组特殊可用分组": "Groupes spéciaux disponibles",
"分组设置": "Paramètres de groupe",
"分组速率配置优先级高于全局速率限制。": "La priorité de configuration du taux de groupe est supérieure à la limite de taux globale.",
"分组速率限制": "Limitation du taux de groupe",
@@ -453,6 +490,7 @@
"划转邀请额度": "Quota d'invitation de transfert",
"划转金额最低为": "Le montant minimum du virement est de",
"划转额度": "Montant du virement",
"列出的模型将不会自动添加或移除-thinking/-nothinking 后缀": "Les modèles listés ici n'ajouteront ni ne retireront automatiquement le suffixe -thinking/-nothinking.",
"列设置": "Paramètres de colonne",
"创建令牌默认选择auto分组初始令牌也将设为auto否则留空为用户默认分组": "Lors de la création d'un jeton, le groupe auto est sélectionné par défaut, et le jeton initial sera également défini sur auto (sinon laisser vide, pour le groupe par défaut de l'utilisateur)",
"创建失败": "Échec de la création",
@@ -553,11 +591,13 @@
"启用 Prompt 检查": "Activer la vérification de l'invite",
"启用2FA失败": "Échec de l'activation de 2FA",
"启用Claude思考适配-thinking后缀": "Activer l'adaptation de la pensée Claude (suffixe -thinking)",
"启用FunctionCall思维签名填充": "Activer le remplissage de thoughtSignature pour FunctionCall",
"启用Gemini思考后缀适配": "Activer l'adaptation du suffixe de la pensée Gemini",
"启用Ping间隔": "Activer l'intervalle de ping",
"启用SMTP SSL": "Activer SMTP SSL",
"启用SSRF防护推荐开启以保护服务器安全": "Activer la protection SSRF (recommandé pour la sécurité du serveur)",
"启用全部": "Activer tout",
"启用后将使用 Creem Test Mode": "Après activation, le mode test Creem sera utilisé",
"启用密钥失败": "Échec de l'activation de la clé",
"启用屏蔽词过滤功能": "Activer la fonction de filtrage des mots sensibles",
"启用所有密钥失败": "Échec de l'activation de toutes les clés",
@@ -566,9 +606,6 @@
"启用绘图功能": "Activer la fonction de dessin",
"启用请求体透传功能": "Activer la fonctionnalité de transmission du corps de la requête",
"启用请求透传": "Activer la transmission de la requête",
"禁用思考处理的模型列表": "Liste noire des modèles pour le traitement thinking",
"列出的模型将不会自动添加或移除-thinking/-nothinking 后缀": "Les modèles listés ici n'ajouteront ni ne retireront automatiquement le suffixe -thinking/-nothinking.",
"请输入JSON数组如 [\"model-a\",\"model-b\"]": "Saisissez un tableau JSON, par ex. [\"model-a\",\"model-b\"]",
"启用额度消费日志记录": "Activer la journalisation de la consommation de quota",
"启用验证": "Activer l'authentification",
"周": "semaine",
@@ -641,6 +678,7 @@
"多密钥渠道操作项目组": "Groupe d'opérations de canal multi-clés",
"多密钥管理": "Gestion multi-clés",
"多种充值方式,安全便捷": "Plusieurs méthodes de recharge, sûres et pratiques",
"大模型接口网关": "API LLM Unifiée",
"天": "Jour",
"天前": "il y a des jours",
"失败": "Échec",
@@ -702,6 +740,7 @@
"密钥输入方式": "Méthode de saisie de la clé",
"密钥预览": "Aperçu de la clé",
"对于官方渠道new-api已经内置地址除非是第三方代理站点或者Azure的特殊接入地址否则不需要填写": "Pour les canaux officiels, le new-api a une adresse intégrée. Sauf s'il s'agit d'un site proxy tiers ou d'une adresse d'accès Azure spéciale, il n'est pas nécessaire de la remplir",
"对免费模型启用预消耗": "Activer la préconsommation pour les modèles gratuits",
"对域名启用 IP 过滤(实验性)": "Activer le filtrage IP pour les domaines (expérimental)",
"对外运营模式": "Mode par défaut",
"导入": "Importer",
@@ -725,6 +764,7 @@
"屏蔽词过滤设置": "Paramètres de filtrage des mots sensibles",
"展开": "Développer",
"展开更多": "Développer plus",
"展示价格": "Prix affiché",
"左侧边栏个人设置": "Paramètres personnels de la barre latérale gauche",
"已为 {{count}} 个模型设置{{type}}_one": "{{type}} défini pour {{count}} modèle",
"已为 {{count}} 个模型设置{{type}}_many": "{{type}} défini pour {{count}} modèles",
@@ -738,6 +778,9 @@
"已切换至最优倍率视图,每个模型使用其最低倍率分组": "Passé à la vue de ratio optimal, chaque modèle utilise son groupe de ratio le plus bas",
"已初始化": "Initialisé",
"已删除 {{count}} 个令牌!": "Supprimé {{count}} jetons !",
"已删除 {{count}} 个令牌_one": "Supprimé {{count}} jeton !",
"已删除 {{count}} 个令牌_many": "Supprimé {{count}} jetons !",
"已删除 {{count}} 个令牌_other": "Supprimé {{count}} jetons !",
"已删除 {{count}} 条失效兑换码_one": "{{count}} code d'échange invalide supprimé",
"已删除 {{count}} 条失效兑换码_many": "{{count}} codes d'échange invalides supprimés",
"已删除 {{count}} 条失效兑换码_other": "{{count}} codes d'échange invalides supprimés",
@@ -777,6 +820,7 @@
"已绑定": "Lié",
"已绑定渠道": "Canaux liés",
"已耗尽": "Épuisé",
"已解锁豆包自定义 API 地址编辑": "L'édition de l'adresse API personnalisée Doubao est déverrouillée",
"已过期": "Expiré",
"已选择 {{count}} 个模型_one": "{{count}} modèle sélectionné",
"已选择 {{count}} 个模型_many": "{{count}} modèles sélectionnés",
@@ -799,6 +843,7 @@
"开启之后会清除用户提示词中的": "Après l'activation, l'invite de l'utilisateur sera effacée",
"开启之后将上游地址替换为服务器地址": "Après l'activation, l'adresse en amont sera remplacée par l'adresse du serveur",
"开启后,仅\"消费\"和\"错误\"日志将记录您的客户端IP地址": "Après l'activation, seuls les journaux \"consommation\" et \"erreur\" enregistreront votre adresse IP client",
"开启后对免费模型倍率为0或者价格为0的模型也会预消耗额度": "Après activation, les modèles gratuits (ratio 0 ou prix 0) préconsommeront également du quota",
"开启后将定期发送ping数据保持连接活跃": "Après activation, des données ping seront envoyées périodiquement pour maintenir la connexion active",
"开启后,所有请求将直接透传给上游,不会进行任何处理(重定向和渠道适配也将失效),请谨慎开启": "Après activation, toutes les requêtes seront directement transmises en amont sans aucun traitement (la redirection et l'adaptation de canal seront également désactivées), veuillez activer avec prudence",
"开启后不限制:必须设置模型倍率": "Après l'activation, aucune limite : le ratio de modèle doit être défini",
@@ -898,6 +943,7 @@
"按倍率类型筛选": "Filtrer par type de ratio",
"按倍率设置": "Définir par ratio",
"按次计费": "Paiement à la séance",
"按照如下格式输入AccessKey|SecretAccessKey|Region": "Entrez au format : AccessKey|SecretAccessKey|Region",
"按量计费": "Paiement à l'utilisation",
"按顺序替换content中的变量占位符": "Remplacer les espaces réservés de variable dans le contenu dans l'ordre",
"换脸": "Remplacement de visage",
@@ -917,6 +963,13 @@
"提交结果": "Résultats",
"提升": "Promouvoir",
"提示": "Invite",
"提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}}": "Invite {{input}} tokens / 1M tokens * {{symbol}}{{price}}",
"视频无法在当前浏览器中播放,这可能是由于:": "La vidéo ne peut pas être lue dans ce navigateur, cela peut être dû à :",
"• 视频服务商的跨域限制": "• Des restrictions cross-origin imposées par le fournisseur vidéo",
"• 需要特定的请求头或认证": "• Des en-têtes ou une authentification spécifiques sont requis",
"• 防盗链保护机制": "• Un mécanisme de protection anti-hotlink",
"在新标签页中打开": "Ouvrir dans un nouvel onglet",
"复制链接": "Copier le lien",
"提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "Invite {{input}} tokens / 1M tokens * {{symbol}}{{price}} + Complétion {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"提示 {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * {{symbol}}{{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "Invite {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + Cache {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + Création de cache {{cacheCreationInput}} tokens / 1M tokens * {{symbol}}{{cacheCreationPrice}} + Complétion {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"提示:如需备份数据,只需复制上述目录即可": "Astuce : pour sauvegarder les données, il suffit de copier le répertoire ci-dessus",
@@ -1025,6 +1078,7 @@
"是否为企业账户": "Est-ce un compte d'entreprise ?",
"是否同时重置对话消息?选择\"是\"将清空所有对话记录并恢复默认示例;选择\"否\"将保留当前对话记录。": "Voulez-vous également réinitialiser les messages de conversation ? Choisir \"Oui\" effacera tous les enregistrements de conversation et restaurera les exemples par défaut ; choisir \"Non\" conservera les enregistrements de conversation actuels.",
"是否将该订单标记为成功并为用户入账?": "Marquer cette commande comme réussie et créditer l'utilisateur ?",
"是否确认充值?": "Confirmer la recharge ?",
"是否自动禁用": "Désactiver automatiquement",
"是否要求指纹/面容等生物识别": "Exiger une reconnaissance biométrique par empreinte digitale/faciale",
"显示倍率": "Afficher le ratio",
@@ -1042,6 +1096,7 @@
"智能熔断": "Fallback intelligent",
"智谱": "Zhipu AI",
"暂无API信息": "Aucune information sur l'API",
"暂无产品配置": "Aucune configuration de produit pour le moment",
"暂无保存的配置": "Aucune configuration enregistrée",
"暂无充值记录": "Aucune recharge",
"暂无公告": "Pas d'avis",
@@ -1067,6 +1122,7 @@
"更多参数请参考": "Pour plus de paramètres, veuillez vous référer à",
"更好的价格,更好的稳定性,只需要将模型基址替换为:": "Meilleur prix, meilleure stabilité, aucun abonnement requis, il suffit de remplacer l'URL de BASE du modèle par : ",
"更新": "Mettre à jour",
"更新 Creem 设置": "Mettre à jour les paramètres Creem",
"更新 Stripe 设置": "Mettre à jour les paramètres Stripe",
"更新SSRF防护设置": "Mettre à jour les paramètres de protection SSRF",
"更新Worker设置": "Mettre à jour les paramètres du worker",
@@ -1113,6 +1169,7 @@
"未配置的模型列表": "Modèles non configurés",
"本地": "Local",
"本地数据存储": "Stockage de données locales",
"本地计费": "Facturation locale",
"本设备:手机指纹/面容外接USB安全密钥": "Intégré : empreinte digitale/visage du téléphone, Externe : clé de sécurité USB",
"本设备内置": "Intégré à cet appareil",
"本项目根据": "Ce projet est sous licence ",
@@ -1122,6 +1179,7 @@
"条 - 第": "à",
"条,共": "sur",
"条日志已清理!": "les journaux ont été effacés !",
"来自模型重定向,尚未加入模型列表": "Issu d'une redirection de modèle, pas encore ajouté à la liste des modèles",
"查看": "Voir",
"查看图片": "Voir les images",
"查看密钥": "Afficher la clé",
@@ -1152,6 +1210,7 @@
"模型价格 {{symbol}}{{price}}{{ratioType}} {{ratio}}": "Prix du modèle {{symbol}}{{price}}, {{ratioType}} {{ratio}}",
"模型价格:{{symbol}}{{price}} * {{ratioType}}{{ratio}} = {{symbol}}{{total}}": "Prix du modèle : {{symbol}}{{price}} * {{ratioType}} : {{ratio}} = {{symbol}}{{total}}",
"模型倍率": "Ratio",
"模型倍率 {{modelRatio}}": "Ratio du modèle {{modelRatio}}",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}": "Ratio du modèle {{modelRatio}}, ratio de cache {{cacheRatio}}, ratio de complétion {{completionRatio}}, {{ratioType}} {{ratio}}",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}Web 搜索调用 {{webSearchCallCount}} 次": "Ratio du modèle {{modelRatio}}, ratio de cache {{cacheRatio}}, ratio de complétion {{completionRatio}}, {{ratioType}} {{ratio}}, appels de recherche Web {{webSearchCallCount}} fois",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}},图片输入倍率 {{imageRatio}}{{ratioType}} {{ratio}}": "Ratio du modèle {{modelRatio}}, ratio de cache {{cacheRatio}}, ratio de complétion {{completionRatio}}, ratio d'entrée image {{imageRatio}}, {{ratioType}} {{ratio}}",
@@ -1174,6 +1233,7 @@
"模型数据分析": "Analyse des données du modèle",
"模型映射必须是合法的 JSON 格式!": "Le mappage de modèles doit être au format JSON valide !",
"模型更新成功!": "Modèle mis à jour avec succès !",
"模型未加入列表,可能无法调用": "Le modèle n'est pas dans la liste, il peut ne pas être disponible",
"模型消耗分布": "Distribution de la consommation des modèles",
"模型消耗趋势": "Tendance de la consommation des modèles",
"模型版本": "Version du modèle",
@@ -1189,15 +1249,18 @@
"模型选择和映射设置": "Sélection de modèle et paramètres de mappage",
"模型配置": "Configuration du modèle",
"模型重定向": "Redirection de modèle",
"模型重定向里的下列模型尚未添加到“模型”列表,调用时会因为缺少可用模型而失败:": "Les modèles suivants provenant de la redirection n'ont pas été ajoutés à la liste « Modèles », l'appel échouera faute de modèle disponible :",
"模型限制列表": "Liste des restrictions de modèle",
"模板示例": "Exemple de modèle",
"模糊搜索模型名称": "Recherche floue de nom de modèle",
"次": "Fois",
"欢迎使用,请完成以下设置以开始使用系统": "Bienvenue, veuillez compléter les paramètres suivants pour commencer à utiliser le système",
"欧元": "Euro",
"正在处理大内容...": "Traitement de contenu volumineux...",
"正在提交": "Envoi en cours",
"正在构造请求体预览...": "Construction de l'aperçu du corps de la requête...",
"正在测试第 ${current} - ${end} 个模型 (共 ${total} 个)": "Test des modèles ${current} - ${end} sur ${total} au total",
"正在跳转 GitHub...": "Redirection vers GitHub...",
"正在跳转...": "Redirection...",
"此代理仅用于图片请求转发Webhook通知发送等AI API请求仍然由服务器直接发出可在渠道设置中单独配置代理": "Ce proxy est utilisé uniquement pour le transfert des requêtes d'images, l'envoi de notifications Webhook, etc. Les requêtes d'API IA sont toujours émises directement par le serveur, le proxy peut être configuré séparément dans les paramètres du canal",
"此修改将不可逆": "Cette modification sera irréversible",
@@ -1249,6 +1312,7 @@
"测试失败": "Échec du test",
"测试所有渠道的最长响应时间": "Temps de réponse maximal pour tester tous les canaux",
"测试所有通道": "Tester tous les canaux",
"测试模式": "Mode test",
"测速": "Test de vitesse",
"消息优先级": "Priorité du message",
"消息优先级范围0-10默认为5": "Priorité du message, plage 0-10, par défaut 5",
@@ -1264,10 +1328,12 @@
"深色模式": "Mode sombre",
"添加": "Ajouter",
"添加API": "Ajouter une API",
"添加产品": "Ajouter un produit",
"添加令牌": "Créer un jeton",
"添加兑换码": "Ajouter un code d'échange",
"添加公告": "Ajouter un avis",
"添加分类": "Ajouter une catégorie",
"添加后提交": "Soumettre après ajout",
"添加成功": "Ajouté avec succès",
"添加模型": "Ajouter un modèle",
"添加模型区域": "Ajouter une zone de modèle",
@@ -1325,9 +1391,11 @@
"生成音乐": "générer de la musique",
"用于API调用的身份验证令牌请妥善保管": "Jeton d'authentification pour les appels d'API, veuillez le conserver en lieu sûr",
"用于配置网络代理,支持 socks5 协议": "Utilisé pour configurer le proxy réseau, prend en charge le protocole socks5",
"用于验证回调 new-api 的 webhook 请求的密钥,敏感信息不显示": "Clé utilisée pour vérifier les requêtes webhook de rappel de new-api, les informations sensibles ne sont pas affichées.",
"用以支持基于 WebAuthn 的无密码登录注册": "Prise en charge de la connexion et de l'enregistrement sans mot de passe basés sur WebAuthn",
"用以支持用户校验": "Pour prendre en charge la vérification des utilisateurs",
"用以支持系统的邮件发送": "Pour prendre en charge l'envoi d'e-mails système",
"用以支持通过 Discord 进行登录注册": "Utilisé pour prendre en charge la connexion/l'inscription via Discord",
"用以支持通过 GitHub 进行登录注册": "Pour prendre en charge la connexion & l'inscription via GitHub",
"用以支持通过 Linux DO 进行登录注册": "Pour prendre en charge la connexion & l'inscription via Linux DO",
"用以支持通过 OIDC 登录,例如 Okta、Auth0 等兼容 OIDC 协议的 IdP": "Pour prendre en charge la connexion via OIDC, par exemple Okta, Auth0 et autres IdP compatibles avec le protocole OIDC",
@@ -1372,6 +1440,7 @@
"的前提下使用。": "doit être utilisé conformément aux conditions.",
"监控设置": "Paramètres de surveillance",
"目标用户:{{username}}": "Utilisateur cible : {{username}}",
"直接提交": "Soumettre directement",
"相关项目": "Projets connexes",
"相当于删除用户,此修改将不可逆": "Équivalent à supprimer l'utilisateur, cette modification sera irréversible",
"矛盾": "Conflit",
@@ -1392,6 +1461,7 @@
"确定清除所有失效兑换码?": "Êtes-vous sûr de vouloir effacer tous les codes d'échange non valides ?",
"确定要修改所有子渠道优先级为 ": "Confirmer la modification de toutes les priorités des sous-canaux en ",
"确定要修改所有子渠道权重为 ": "Confirmer la modification de tous les poids des sous-canaux en ",
"确定要充值 $": "Confirmer la recharge de $",
"确定要删除供应商 \"{{name}}\" 吗?此操作不可撤销。": "Êtes-vous sûr de vouloir supprimer le fournisseur \"{{name}}\" ? Cette opération est irréversible.",
"确定要删除所有已自动禁用的密钥吗?": "Êtes-vous sûr de vouloir supprimer toutes les clés désactivées automatiquement ?",
"确定要删除所选的 {{count}} 个令牌吗_one": "Êtes-vous sûr de vouloir supprimer le jeton sélectionné ?",
@@ -1443,6 +1513,7 @@
"禁用原因": "Raison de la désactivation",
"禁用后的影响:": "Impact après la désactivation :",
"禁用密钥失败": "Échec de la désactivation de la clé",
"禁用思考处理的模型列表": "Liste noire des modèles pour le traitement thinking",
"禁用所有密钥失败": "Échec de la désactivation de toutes les clés",
"禁用时间": "Heure de désactivation",
"私有IP访问详细说明": "⚠️ Avertissement de sécurité : l'activation de cette option autorise l'accès aux ressources du réseau interne (localhost, réseaux privés). N'activez cette option que si vous devez accéder à des services internes et que vous comprenez les implications en matière de sécurité.",
@@ -1467,6 +1538,7 @@
"管理员": "Admin",
"管理员区域": "Zone administrateur",
"管理员暂时未设置任何关于内容": "L'administrateur n'a encore défini aucun contenu personnalisé \"À propos\".",
"管理员未开启 Creem 充值!": "L'administrateur n'a pas activé la recharge Creem !",
"管理员未开启Stripe充值": "L'administrateur n'a pas activé la recharge Stripe !",
"管理员未开启在线充值!": "L'administrateur n'a pas activé la recharge en ligne !",
"管理员未开启在线充值功能,请联系管理员开启或使用兑换码充值。": "L'administrateur n'a pas activé la fonction de recharge en ligne, veuillez contacter l'administrateur pour l'activer ou recharger avec un code d'échange.",
@@ -1519,24 +1591,33 @@
"绘图任务记录": "Enregistrements de tâches de dessin",
"绘图日志": "Journaux de dessin",
"绘图设置": "Paramètres de dessin",
"统一的": "La Passerelle",
"统计Tokens": "Jetons statistiques",
"统计次数": "Nombre de statistiques",
"统计额度": "Quota statistique",
"继续": "Continuer",
"缓存 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Cache {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (ratio : {{ratio}})",
"缓存 Tokens": "Jetons de cache",
"缓存: {{cacheRatio}}": "Cache : {{cacheRatio}}",
"缓存价格:{{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})": "Prix du cache : {{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (taux de cache : {{cacheRatio}})",
"缓存价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})": "Prix du cache : {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (taux de cache : {{cacheRatio}})",
"缓存倍率": "Ratio de cache",
"缓存倍率 {{cacheRatio}}": "Ratio de cache {{cacheRatio}}",
"缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Création de cache {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (ratio : {{ratio}})",
"缓存创建 Tokens": "Jetons de création de cache",
"缓存创建: {{cacheCreationRatio}}": "Création de cache : {{cacheCreationRatio}}",
"缓存创建: 5m {{cacheCreationRatio5m}}": "Création de cache : 5m {{cacheCreationRatio5m}}",
"缓存创建: 1h {{cacheCreationRatio1h}}": "Création de cache : 1h {{cacheCreationRatio1h}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}}": "Multiplicateur de création de cache 5m {{cacheCreationRatio5m}}",
"缓存创建倍率 1h {{cacheCreationRatio1h}}": "Multiplicateur de création de cache 1h {{cacheCreationRatio1h}}",
"缓存创建: 5m {{cacheCreationRatio5m}}": "Création de cache : 5m {{cacheCreationRatio5m}}",
"缓存创建: 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}": "Création de cache : 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}",
"缓存创建价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})": "Prix de création du cache : {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (taux de création de cache : {{cacheCreationRatio}})",
"缓存创建价格合计5m {{symbol}}{{five}} + 1h {{symbol}}{{one}} = {{symbol}}{{total}} / 1M tokens": "Total du prix de création de cache : 5m {{symbol}}{{five}} + 1h {{symbol}}{{one}} = {{symbol}}{{total}} / 1M tokens",
"缓存创建倍率 {{cacheCreationRatio}}": "Ratio de création de cache {{cacheCreationRatio}}",
"缓存创建倍率 1h {{cacheCreationRatio1h}}": "Multiplicateur de création de cache 1h {{cacheCreationRatio1h}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}}": "Multiplicateur de création de cache 5m {{cacheCreationRatio5m}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}": "Ratio de création de cache 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}",
"编辑": "Modifier",
"编辑API": "Modifier l'API",
"编辑产品": "Modifier le produit",
"编辑供应商": "Modifier le fournisseur",
"编辑公告": "Modifier l'avis",
"编辑公告内容": "Modifier le contenu de l'annonce",
@@ -1554,6 +1635,7 @@
"网站域名标识": "ID de domaine du site Web",
"网络错误": "Erreur réseau",
"置信度": "Confiance",
"美元": "Dollar américain",
"聊天": "Discuter",
"聊天会话管理": "Gestion des sessions de discussion",
"聊天区域": "Zone de discussion",
@@ -1600,6 +1682,7 @@
"获取金额失败": "Échec de l'obtention du montant",
"获取验证码": "Obtenir le code de vérification",
"补全": "Achèvement",
"补全 {{completion}} tokens / 1M tokens * {{symbol}}{{price}}": "Complétion {{completion}} tokens / 1M tokens * {{symbol}}{{price}}",
"补全价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "Prix de complétion : {{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (taux de complétion : {{completionRatio}})",
"补全价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens": "Prix de complétion : {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens",
"补全倍率": "Ratio de complétion",
@@ -1616,6 +1699,7 @@
"解析密钥文件失败: {{msg}}": "Échec de l'analyse du fichier de clés : {{msg}}",
"解绑 Passkey": "Supprimer le Passkey",
"解绑后将无法使用 Passkey 登录,确定要继续吗?": "Après la dissociation, vous ne pourrez plus vous connecter avec Passkey. Êtes-vous sûr de vouloir continuer ?",
"计费模式": "Mode de facturation",
"计费类型": "Type de facturation",
"计费过程": "Processus de mise en lots",
"订单号": "N° de commande",
@@ -1679,6 +1763,7 @@
"请前往个人设置 → 安全设置进行配置。": "Veuillez aller dans Paramètres personnels → Paramètres de sécurité pour configurer.",
"请勿过度信任此功能IP可能被伪造": "Ne faites pas trop confiance à cette fonctionnalité, l'IP peut être usurpée",
"请在系统设置页面编辑分组倍率以添加新的分组:": "Veuillez modifier les ratios de groupe dans les paramètres système pour ajouter de nouveaux groupes :",
"请填写完整的产品信息": "Veuillez renseigner l'ensemble des informations produit",
"请填写完整的管理员账号信息": "Veuillez remplir les informations complètes du compte administrateur",
"请填写密钥": "Veuillez saisir la clé",
"请填写渠道名称和渠道密钥!": "Veuillez saisir le nom et la clé du canal !",
@@ -1693,10 +1778,11 @@
"请求失败": "Échec de la demande",
"请求头覆盖": "Remplacement des en-têtes de demande",
"请求并计费模型": "Modèle de demande et de facturation",
"请求路径": "Chemin de requête",
"请求时长: ${time}s": "Durée de la requête : ${time}s",
"请求次数": "Nombre de demandes",
"请求结束后多退少补": "Ajuster après la fin de la demande",
"请求超时,请刷新页面后重新发起 GitHub 登录": "Délai dépassé, veuillez actualiser la page puis relancer la connexion GitHub",
"请求路径": "Chemin de requête",
"请求预扣费额度": "Quota de pré-déduction pour les demandes",
"请点击我": "Veuillez cliquer sur moi",
"请确认以下设置信息,点击\"初始化系统\"开始配置": "Veuillez confirmer les informations de configuration suivantes, cliquez sur \"Initialiser le système\" pour commencer la configuration",
@@ -1713,6 +1799,8 @@
"请至少选择一个模型": "Veuillez sélectionner au moins un modèle",
"请至少选择一个模型!": "Veuillez sélectionner au moins un modèle !",
"请至少选择一个渠道": "Veuillez sélectionner au moins un canal",
"请输入 API Key一行一个格式APIKey|Region": "Saisissez une API Key par ligne, format : APIKey|Region",
"请输入 API Key格式APIKey|Region": "Saisissez l'API Key au format : APIKey|Region",
"请输入 AZURE_OPENAI_ENDPOINT例如https://docs-test-001.openai.azure.com": "Veuillez saisir AZURE_OPENAI_ENDPOINT, par exemple : https://docs-test-001.openai.azure.com",
"请输入 JSON 格式的密钥内容,例如:\n{\n \"type\": \"service_account\",\n \"project_id\": \"your-project-id\",\n \"private_key_id\": \"...\",\n \"private_key\": \"...\",\n \"client_email\": \"...\",\n \"client_id\": \"...\",\n \"auth_uri\": \"...\",\n \"token_uri\": \"...\",\n \"auth_provider_x509_cert_url\": \"...\",\n \"client_x509_cert_url\": \"...\"\n}": "Veuillez saisir le contenu de la clé au format JSON, par exemple :\n{\n \"type\": \"service_account\",\n \"project_id\": \"your-project-id\",\n \"private_key_id\": \"...\",\n \"private_key\": \"...\",\n \"client_email\": \"...\",\n \"client_id\": \"...\",\n \"auth_uri\": \"...\",\n \"token_uri\": \"...\",\n \"auth_provider_x509_cert_url\": \"...\",\n \"client_x509_cert_url\": \"...\"\n}",
"请输入 OIDC 的 Well-Known URL": "Veuillez saisir l'URL Well-Known de l'OIDC",
@@ -1724,6 +1812,7 @@
"请输入Gotify应用令牌": "Veuillez saisir le jeton d'application Gotify",
"请输入Gotify服务器地址": "Veuillez saisir l'adresse du serveur Gotify",
"请输入Gotify服务器地址例如: https://gotify.example.com": "Veuillez saisir l'adresse du serveur Gotify, par exemple : https://gotify.example.com",
"请输入JSON数组如 [\"model-a\",\"model-b\"]": "Saisissez un tableau JSON, par ex. [\"model-a\",\"model-b\"]",
"请输入Uptime Kuma地址": "Veuillez saisir l'adresse Uptime Kuma",
"请输入Uptime Kuma服务地址https://status.example.com": "Veuillez saisir l'adresse du service Uptime Kuma, telle que : https://status.example.com",
"请输入URL链接": "Veuillez saisir le lien URL",
@@ -1754,6 +1843,7 @@
"请输入密码": "Veuillez saisir un mot de passe",
"请输入密钥": "Veuillez saisir la clé",
"请输入密钥,一行一个": "Veuillez saisir la clé, une par ligne",
"请输入密钥一行一个格式AccessKey|SecretAccessKey|Region": "Saisissez les clés une par ligne, format : AccessKey|SecretAccessKey|Region",
"请输入密钥!": "Veuillez saisir la clé !",
"请输入您的密码": "Veuillez saisir votre mot de passe",
"请输入您的用户名以确认删除": "Veuillez saisir votre nom d'utilisateur pour confirmer la suppression",
@@ -1808,6 +1898,7 @@
"请输入验证码或备用码": "Veuillez saisir le code de vérification ou le code de sauvegarde",
"请输入默认 API 版本例如2025-04-01-preview": "Veuillez saisir la version de l'API par défaut, par exemple : 2025-04-01-preview.",
"请选择API地址": "Veuillez sélectionner l'adresse de l'API",
"请选择产品": "Veuillez sélectionner un produit",
"请选择你的复制方式": "Veuillez sélectionner votre méthode de copie",
"请选择使用模式": "Veuillez sélectionner le mode d'utilisation",
"请选择分组": "Veuillez sélectionner un groupe",
@@ -1848,6 +1939,7 @@
"账户绑定": "Liaison de compte",
"账户绑定、安全设置和身份验证": "Liaison de compte, paramètres de sécurité et vérification d'identité",
"账户统计": "Statistiques du compte",
"货币": "Devise",
"货币单位": "Unité monétaire",
"购买兑换码": "Acheter un code d'échange",
"资源消耗": "Consommation de ressources",
@@ -1889,15 +1981,17 @@
"输入验证码": "Saisir le code de vérification",
"输入验证码完成设置": "Saisissez le code de vérification pour terminer la configuration",
"输出": "Sortie",
"输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}": "Sortie {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}",
"输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}": "Sortie {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}}",
"输出价格": "Prix de sortie",
"输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "Prix de sortie : {{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (ratio d'achèvement : {{completionRatio}})",
"输出倍率 {{completionRatio}}": "Ratio de sortie {{completionRatio}}",
"边栏设置": "Paramètres de la barre latérale",
"过期时间": "Date d'expiration",
"过期时间不能早于当前时间!": "La date d'expiration ne peut pas être antérieure à l'heure actuelle !",
"过期时间快捷设置": "Paramètres rapides de la date d'expiration",
"过期时间格式错误!": "Erreur de format de la date d'expiration !",
"运营设置": "Paramètres de fonctionnement",
"返回修改": "Revenir pour modifier",
"返回登录": "Retour à la connexion",
"这是重复键中的最后一个,其值将被使用": "Ceci est la dernière clé dupliquée, sa valeur sera utilisée",
"进度": "calendrier",
@@ -1975,6 +2069,7 @@
"部分渠道测试失败:": "Certains canaux n'ont pas réussi le test : ",
"部署地区": "Région de déploiement",
"配置": "Configurer",
"配置 Discord OAuth": "Configurer OAuth Discord",
"配置 GitHub OAuth App": "Configurer l'application GitHub OAuth",
"配置 Linux DO OAuth": "Configurer Linux DO OAuth",
"配置 OIDC": "Configurer OIDC",
@@ -2016,6 +2111,7 @@
"错误": "Erreur",
"键为分组名称,值为另一个 JSON 对象,键为分组名称,值为该分组的用户的特殊分组倍率,例如:{\"vip\": {\"default\": 0.5, \"test\": 1}},表示 vip 分组的用户在使用default分组的令牌时倍率为0.5使用test分组时倍率为1": "La clé est le nom du groupe, la valeur est un autre objet JSON, la clé est le nom du groupe, la valeur est le ratio de groupe spécial des utilisateurs de ce groupe, par exemple : {\"vip\": {\"default\": 0.5, \"test\": 1}}, ce qui signifie que les utilisateurs du groupe vip ont un ratio de 0.5 lors de l'utilisation de jetons du groupe default et un ratio de 1 lors de l'utilisation du groupe test",
"键为原状态码,值为要复写的状态码,仅影响本地判断": "La clé est le code d'état d'origine, la valeur est le code d'état à réécrire, n'affecte que le jugement local",
"键为用户分组名称,值为操作映射对象。内层键以\"+:\"开头表示添加指定分组(键值为分组名称,值为描述),以\"-:\"开头表示移除指定分组(键值为分组名称),不带前缀的键直接添加该分组。例如:{\"vip\": {\"+:premium\": \"高级分组\", \"special\": \"特殊分组\", \"-:default\": \"默认分组\"}},表示 vip 分组的用户可以使用 premium 和 special 分组,同时移除 default 分组的访问权限": "La clé correspond au nom du groupe d'utilisateurs et la valeur à un objet de mappage des opérations. Les clés internes commençant par \"+:\" ajoutent le groupe indiqué (clé = nom du groupe, valeur = description), celles commençant par \"-:\" retirent le groupe indiqué, et les clés sans préfixe ajoutent directement ce groupe. Exemple : {\"vip\": {\"+:premium\": \"Groupe avancé\", \"special\": \"Groupe spécial\", \"-:default\": \"Groupe par défaut\"}} signifie que les utilisateurs du groupe vip peuvent accéder aux groupes premium et special tout en perdant l'accès au groupe default.",
"键为端点类型,值为路径和方法对象": "La clé est le type de point de terminaison, la valeur est le chemin et l'objet de la méthode",
"键为请求中的模型名称,值为要替换的模型名称": "La clé est le nom du modèle dans la requête, la valeur est le nom du modèle à remplacer",
"键名": "Nom de clé",
@@ -2089,10 +2185,46 @@
"默认区域,如: us-central1": "Région par défaut, ex: us-central1",
"默认折叠侧边栏": "Réduire la barre latérale par défaut",
"默认测试模型": "Modèle de test par défaut",
"默认补全倍率": "Taux de complétion par défaut",
"统一的": "La Passerelle",
"大模型接口网关": "API LLM Unifiée",
"正在跳转 GitHub...": "Redirection vers GitHub...",
"请求超时,请刷新页面后重新发起 GitHub 登录": "Délai dépassé, veuillez actualiser la page puis relancer la connexion GitHub"
"请先在设置中启用图片功能": "Veuillez d'abord activer la fonction image dans les paramètres",
"图片已添加": "Image ajoutée",
"无法添加图片": "Impossible d'ajouter l'image",
"粘贴图片失败": "Échec du collage de l'image",
"支持 Ctrl+V 粘贴图片": "Supporte Ctrl+V pour coller l'image",
"已复制全部数据": "Toutes les données copiées",
"流式响应完成": "Flux terminé",
"图片地址": "URL de l'image",
"已在自定义模式中忽略": "Ignoré en mode personnalisé",
"停用": "Désactiver",
"图片功能在自定义请求体模式下不可用": "La fonction image n'est pas disponible en mode requête personnalisée",
"启用后可添加图片URL进行多模态对话": "Activer pour ajouter des URL d'images pour une conversation multimodale",
"点击 + 按钮添加图片URL进行多模态对话": "Cliquez sur + pour ajouter des URL d'images pour une conversation multimodale",
"已添加": "Ajouté",
"张图片": "images",
"自定义模式下不可用": "Non disponible en mode personnalisé",
"控制输出的随机性和创造性": "Contrôle l'aléatoire et la créativité de la sortie",
"核采样,控制词汇选择的多样性": "Échantillonnage nucléaire, contrôle la diversité de la sélection du vocabulaire",
"频率惩罚,减少重复词汇的出现": "Pénalité de fréquence, réduit la répétition des mots",
"存在惩罚,鼓励讨论新话题": "Pénalité de présence, encourage de nouveaux sujets",
"流式输出": "Sortie en flux",
"暂无SSE响应数据": "Aucune donnée de réponse SSE",
"SSE数据流": "Flux de données SSE",
"解析错误": "Erreur d'analyse",
"有 Reasoning": "A un raisonnement",
"全部收起": "Tout réduire",
"全部展开": "Tout développer",
"SSE 事件": "Événement SSE",
"JSON格式错误": "Erreur de format JSON",
"自定义请求体模式": "Mode de corps de requête personnalisé",
"启用此模式后将使用您自定义的请求体发送API请求模型配置面板的参数设置将被忽略。": "Lorsqu'il est activé, votre corps de requête personnalisé sera utilisé pour les requêtes API et les paramètres du panneau de configuration du modèle seront ignorés.",
"请求体 JSON": "Corps de requête JSON",
"格式正确": "Format valide",
"格式错误": "Format invalide",
"格式化": "Formater",
"请输入有效的JSON格式的请求体。您可以参考预览面板中的默认请求体格式。": "Veuillez entrer un corps de requête au format JSON valide. Vous pouvez vous référer au format de corps de requête par défaut dans le panneau d'aperçu.",
"默认用户消息": "Bonjour",
"默认助手消息": "Bonjour ! Comment puis-je vous aider aujourd'hui ?",
"可选,用于复现结果": "Optionnel, pour des résultats reproductibles",
"随机种子 (留空为随机)": "Graine aléatoire (laisser vide pour aléatoire)",
"默认补全倍率": "Taux de complétion par défaut"
}
}
}

View File

@@ -2084,6 +2084,46 @@
"统一的": "統合型",
"大模型接口网关": "LLM APIゲートウェイ",
"正在跳转 GitHub...": "GitHub にリダイレクトしています...",
"请求超时,请刷新页面后重新发起 GitHub 登录": "タイムアウトしました。ページをリロードして GitHub ログインをやり直してください"
"请求超时,请刷新页面后重新发起 GitHub 登录": "タイムアウトしました。ページをリロードして GitHub ログインをやり直してください",
"请先在设置中启用图片功能": "まず設定で画像機能を有効にしてください",
"图片已添加": "画像が追加されました",
"无法添加图片": "画像を追加できません",
"粘贴图片失败": "画像の貼り付けに失敗しました",
"支持 Ctrl+V 粘贴图片": "Ctrl+V で画像を貼り付け可能",
"已复制全部数据": "すべてのデータをコピーしました",
"流式响应完成": "ストリーム完了",
"图片地址": "画像URL",
"已在自定义模式中忽略": "カスタムモードで無視されました",
"停用": "無効",
"图片功能在自定义请求体模式下不可用": "カスタムリクエストモードでは画像機能は利用できません",
"启用后可添加图片URL进行多模态对话": "有効にすると画像URLを追加してマルチモーダル会話ができます",
"点击 + 按钮添加图片URL进行多模态对话": "+ ボタンをクリックして画像URLを追加し、マルチモーダル会話を行います",
"已添加": "追加済み",
"张图片": "枚の画像",
"自定义模式下不可用": "カスタムモードでは利用できません",
"控制输出的随机性和创造性": "出力のランダム性と創造性を制御",
"核采样,控制词汇选择的多样性": "ニュークリアスサンプリング、語彙選択の多様性を制御",
"频率惩罚,减少重复词汇的出现": "頻度ペナルティ、単語の繰り返しを減少",
"存在惩罚,鼓励讨论新话题": "存在ペナルティ、新しいトピックを促進",
"流式输出": "ストリーム出力",
"暂无SSE响应数据": "SSE応答データがありません",
"SSE数据流": "SSEデータストリーム",
"解析错误": "解析エラー",
"有 Reasoning": "推論あり",
"全部收起": "すべて折りたたむ",
"全部展开": "すべて展開",
"SSE 事件": "SSEイベント",
"JSON格式错误": "JSON形式エラー",
"自定义请求体模式": "カスタムリクエストボディモード",
"启用此模式后将使用您自定义的请求体发送API请求模型配置面板的参数设置将被忽略。": "このモードを有効にすると、カスタムリクエストボディがAPIリクエストに使用され、モデル設定パネルのパラメータ設定は無視されます。",
"请求体 JSON": "リクエストボディJSON",
"格式正确": "有効な形式",
"格式错误": "無効な形式",
"格式化": "フォーマット",
"请输入有效的JSON格式的请求体。您可以参考预览面板中的默认请求体格式。": "有効なJSON形式のリクエストボディを入力してください。プレビューパネルのデフォルトのリクエストボディ形式を参照できます。",
"默认用户消息": "こんにちは",
"默认助手消息": "こんにちは!何かお手伝いできることはありますか?",
"可选,用于复现结果": "オプション、結果の再現用",
"随机种子 (留空为随机)": "ランダムシード(空欄でランダム)"
}
}
}

View File

@@ -22,7 +22,9 @@
"[最多请求次数]和[最多请求完成次数]的最大值为2147483647。": "[Максимальное количество запросов] и [Максимальное количество выполненных запросов] имеют максимальное значение 2147483647.",
"[最多请求次数]必须大于等于0[最多请求完成次数]必须大于等于1。": "[Максимальное количество запросов] должно быть больше или равно 0, [Максимальное количество выполненных запросов] должно быть больше или равно 1.",
"{\n \"default\": [200, 100],\n \"vip\": [0, 1000]\n}": "{\n \"default\": [200, 100],\n \"vip\": [0, 1000]\n}",
"{{breakdown}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "{{breakdown}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}": "{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}",
"{{ratioType}} {{ratio}}": "{{ratioType}} {{ratio}}",
"© {{currentYear}}": "© {{currentYear}}",
"| 基于": "| Основано на",
"$/1M tokens": "$/1M токенов",
@@ -30,15 +32,20 @@
"0.002-1之间的小数": "Десятичное число между 0.002-1",
"0.1以上的小数": "Десятичное число выше 0.1",
"10 - 最高": "10 - Максимум",
"1h缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Создание кеша 1ч {{tokens}} токенов / 1M токенов * {{symbol}}{{price}} (множитель: {{ratio}})",
"1h缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (1h缓存创建倍率: {{cacheCreationRatio1h}})": "Цена создания кеша за 1ч: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M токенов (множитель создания 1ч: {{cacheCreationRatio1h}})",
"2 - 低": "2 - Низкий",
"2025年5月10日后添加的渠道不需要再在部署的时候移除模型名称中的\".\"": "Каналы, добавленные после 10 мая 2025 года, не требуют удаления \".\" из имен моделей при развертывании",
"360智脑": "360 ZhiNao",
"5 - 正常(默认)": "5 - Нормальный (по умолчанию)",
"5m缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Создание кеша 5м {{tokens}} токенов / 1M токенов * {{symbol}}{{price}} (множитель: {{ratio}})",
"5m缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (5m缓存创建倍率: {{cacheCreationRatio5m}})": "Цена создания кеша за 5м: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M токенов (множитель создания 5м: {{cacheCreationRatio5m}})",
"8 - 高": "8 - Высокий",
"AGPL v3.0协议": "Лицензия AGPL v3.0",
"AI 对话": "AI диалог",
"AI模型测试环境": "Среда тестирования AI моделей",
"AI模型配置": "Конфигурация AI моделей",
"AK/SK 模式:使用 AccessKey 和 SecretAccessKeyAPI Key 模式:使用 API Key": "Режим AK/SK: используйте AccessKey и SecretAccessKey; режим API Key: используйте API Key",
"API Key 模式下不支持批量创建": "Режим API Key не поддерживает массовое создание",
"API 地址和相关配置": "Адрес API и связанные настройки",
"API 密钥": "Ключ API",
@@ -64,17 +71,25 @@
"Client ID": "ID клиента",
"Client Secret": "Секрет клиента",
"common.changeLanguage": "common.changeLanguage",
"Creem API 密钥,敏感信息不显示": "API-ключ Creem, чувствительные данные не отображаются",
"Creem Setting Tips": "Creem поддерживает только преднастроенные товары с фиксированной суммой. Эти товары и их цены нужно заранее создать и настроить на сайте Creem, поэтому пополнения с произвольной суммой не поддерживаются. Настройте название и цену товара в Creem, получите идентификатор товара и укажите его ниже. Затем задайте сумму пополнения и отображаемую цену в new-api.",
"Creem 介绍": "О сервисе Creem",
"Creem 充值": "Пополнение через Creem",
"Creem 设置": "Настройки Creem",
"default为默认设置可单独设置每个分类的安全等级": "default - это настройка по умолчанию, можно отдельно установить уровень безопасности для каждой категории",
"default为默认设置可单独设置每个模型的版本": "default - это настройка по умолчанию, можно отдельно установить версию для каждой модели",
"Dify渠道只适配chatflow和agent并且agent不支持图片": "Канал Dify адаптирован только для chatflow и agent, и agent не поддерживает изображения!",
"Discord": "Discord",
"Discord Client ID": "ID клиента Discord",
"Discord Client Secret": "Секрет клиента Discord",
"Discord ID": "ID Discord",
"EUR (欧元)": "EUR (евро)",
"false": "false",
"Gemini安全设置": "Настройки безопасности Gemini",
"Gemini思考适配 BudgetTokens = MaxTokens * BudgetTokens 百分比": "Адаптация мышления Gemini BudgetTokens = MaxTokens * процент BudgetTokens",
"Gemini思考适配设置": "Настройки адаптации мышления Gemini",
"Gemini版本设置": "Настройки версии Gemini",
"Gemini设置": "Настройки Gemini",
"启用FunctionCall思维签名填充": "Включить автозаполнение thoughtSignature для FunctionCall",
"仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature": "Заполнять thoughtSignature только для каналов Gemini/Vertex, использующих формат OpenAI",
"GitHub": "GitHub",
"GitHub Client ID": "ID клиента GitHub",
"GitHub Client Secret": "Секрет клиента GitHub",
@@ -139,7 +154,9 @@
"Uptime Kuma地址": "Адрес Uptime Kuma",
"Uptime Kuma监控分类管理可以配置多个监控分类用于服务状态展示最多20个": "Управление категориями мониторинга Uptime Kuma, можно настроить несколько категорий мониторинга для отображения статуса сервисов (максимум 20)",
"URL链接": "URL ссылка",
"USD (美元)": "USD (доллар США)",
"User Info Endpoint": "Конечная точка информации о пользователе",
"Webhook 密钥": "Секрет вебхука",
"Webhook 签名密钥": "Ключ подписи Webhook",
"Webhook地址": "Адрес Webhook",
"Webhook地址必须以https://开头": "Адрес Webhook должен начинаться с https://",
@@ -164,6 +181,7 @@
"上一步": "Предыдущий шаг",
"上次保存: ": "Последнее сохранение: ",
"上游倍率同步": "Синхронизация множителей upstream",
"上游返回": "Ответ апстрима",
"下一个表单块": "Следующий блок формы",
"下一步": "Следующий шаг",
"下午好": "Добрый день",
@@ -212,6 +230,12 @@
"主页链接填": "Введите ссылку на главную страницу",
"之前的所有日志": "Все предыдущие журналы",
"二步验证已重置": "Двухфакторная аутентификация сброшена",
"产品ID": "ID продукта",
"产品ID已存在": "ID продукта уже существует",
"产品名称": "Название продукта",
"产品配置": "Конфигурация продукта",
"产品配置错误,请联系管理员": "Ошибка конфигурации продукта, обратитесь к администратору",
"仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature": "Заполнять thoughtSignature только для каналов Gemini/Vertex, использующих формат OpenAI",
"仅会覆盖你勾选的字段,未勾选的字段保持本地不变。": "Будут перезаписаны только отмеченные поля, неотмеченные поля останутся без изменений локально.",
"仅供参考,以实际扣费为准": "Только для справки, фактическое списание может отличаться",
"仅保存": "Только сохранить",
@@ -262,6 +286,8 @@
"余额": "Баланс",
"余额充值管理": "Управление пополнением баланса",
"你似乎并没有修改什么": "Похоже, вы ничего не изменили",
"你可以在“自定义模型名称”处手动添加它们,然后点击填入后再提交,或者直接使用下方操作自动处理。": "Вы можете добавить их вручную в разделе «Пользовательские названия моделей», нажать «Заполнить», затем отправить или воспользоваться действиями ниже для автоматической обработки.",
"使用 Discord 继续": "Продолжить через Discord",
"使用 GitHub 继续": "Продолжить с GitHub",
"使用 JSON 对象格式,格式为:{\"组名\": [最多请求次数, 最多请求完成次数]}": "Используйте формат объекта JSON, формат: {\"Имя группы\": [Максимальное количество запросов, Максимальное количество выполненных запросов]}",
"使用 LinuxDO 继续": "Продолжить с LinuxDO",
@@ -284,12 +310,16 @@
"例如: socks5://user:pass@host:port": "например: socks5://user:pass@host:port",
"例如0001": "например: 0001",
"例如1000": "например: 1000",
"例如100000": "Например: 100000",
"例如2就是最低充值2$": "например: 2, это минимальное пополнение 2$",
"例如2000": "например: 2000",
"例如4.99": "Например: 4.99",
"例如7就是7元/美金": "например: 7, это 7 юаней/доллар США",
"例如example.com": "например: example.com",
"例如https://yourdomain.com": "например: https://yourdomain.com",
"例如preview": "например: preview",
"例如prod_6I8rBerHpPxyoiU9WK4kot": "Например: prod_6I8rBerHpPxyoiU9WK4kot",
"例如:基础套餐": "Например: базовый пакет",
"例如发卡网站的购买链接": "например ссылка на покупку на сайте карт",
"供应商": "Поставщик",
"供应商介绍": "Описание поставщика",
@@ -302,6 +332,7 @@
"侧边栏管理(全局控制)": "Управление боковой панелью (глобальный контроль)",
"侧边栏设置保存成功": "Настройки боковой панели успешно сохранены",
"保存": "Сохранить",
"保存 Discord OAuth 设置": "Сохранить настройки Discord OAuth",
"保存 GitHub OAuth 设置": "Сохранить настройки GitHub OAuth",
"保存 Linux DO OAuth 设置": "Сохранить настройки LinuxDO OAuth",
"保存 OIDC 设置": "Сохранить настройки OIDC",
@@ -354,6 +385,7 @@
"允许的IP一行一个不填写则不限制": "Разрешенные IP, по одному на строку, если не заполнено - без ограничений",
"允许的端口": "Разрешенные порты",
"允许访问私有IP地址127.0.0.1、192.168.x.x等内网地址": "Разрешить доступ к частным IP-адресам (127.0.0.1, 192.168.x.x и другие внутренние адреса)",
"允许通过 Discord 账户登录 & 注册": "Разрешить вход и регистрацию через аккаунт Discord",
"允许通过 GitHub 账户登录 & 注册": "Разрешить вход и регистрацию через аккаунт GitHub",
"允许通过 Linux DO 账户登录 & 注册": "Разрешить вход и регистрацию через аккаунт LinuxDO",
"允许通过 OIDC 进行登录": "Разрешить вход через OIDC",
@@ -412,6 +444,10 @@
"共 {{count}} 个密钥_many": "Всего {{count}} ключей",
"共 {{count}} 个密钥_other": "Всего {{count}} ключей",
"共 {{count}} 个模型": "Всего {{count}} моделей",
"共 {{count}} 个模型_one": "{{count}} модель",
"共 {{count}} 个模型_few": "{{count}} модели",
"共 {{count}} 个模型_many": "{{count}} моделей",
"共 {{count}} 个模型_other": "{{count}} моделей",
"共 {{total}} 项,当前显示 {{start}}-{{end}} 项": "Всего {{total}} элементов, отображаются {{start}}-{{end}}",
"关": "Выкл",
"关于": "О",
@@ -428,6 +464,7 @@
"其他注册选项": "Другие варианты регистрации",
"其他登录选项": "Другие варианты входа",
"其他设置": "Другие настройки",
"其他详情": "Другие детали",
"内容": "Содержание",
"内容较大,已启用性能优化模式": "Содержание большое, включен режим оптимизации производительности",
"内容较大,部分功能可能受限": "Содержание большое, некоторые функции могут быть ограничены",
@@ -444,6 +481,7 @@
"分组倍率设置": "Настройки коэффициента группы",
"分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{\"vip\": 0.5, \"test\": 1},表示 vip 分组的倍率为 0.5test 分组的倍率为 1": "Настройки коэффициента группы, здесь можно добавить новые группы или изменить Коэффициенты существующих групп, формат - JSON строка, например: {\"vip\": 0.5, \"test\": 1}, что означает коэффициент группы vip равен 0.5, коэффициент группы test равен 1",
"分组特殊倍率": "Специальный коэффициент группы",
"分组特殊可用分组": "Доступные специальные группы",
"分组设置": "Настройки группы",
"分组速率配置优先级高于全局速率限制。": "Конфигурация скорости группы имеет более высокий приоритет, чем глобальные ограничения скорости.",
"分组速率限制": "Ограничение скорости группы",
@@ -456,6 +494,7 @@
"划转邀请额度": "Перевести пригласительную квоту",
"划转金额最低为": "Минимальная сумма перевода",
"划转额度": "Перевести квоту",
"列出的模型将不会自动添加或移除-thinking/-nothinking 后缀": "Для этих моделей суффиксы -thinking/-nothinking не будут добавляться или удаляться автоматически.",
"列设置": "Настройки столбцов",
"创建令牌默认选择auto分组初始令牌也将设为auto否则留空为用户默认分组": "При создании токена по умолчанию выбирается группа auto, начальный токен также будет установлен в auto (иначе оставить пустым для группы пользователя по умолчанию)",
"创建失败": "Не удалось создать",
@@ -556,11 +595,13 @@
"启用 Prompt 检查": "Включить проверку Prompt",
"启用2FA失败": "Не удалось включить 2FA",
"启用Claude思考适配-thinking后缀": "Включить адаптацию мышления Claude (суффикс -thinking)",
"启用FunctionCall思维签名填充": "Включить автозаполнение thoughtSignature для FunctionCall",
"启用Gemini思考后缀适配": "Включить адаптацию суффикса мышления Gemini",
"启用Ping间隔": "Включить интервал Ping",
"启用SMTP SSL": "Включить SMTP SSL",
"启用SSRF防护推荐开启以保护服务器安全": "Включить защиту SSRF (рекомендуется включить для защиты безопасности сервера)",
"启用全部": "Включить все",
"启用后将使用 Creem Test Mode": "После включения будет использован тестовый режим Creem",
"启用密钥失败": "Не удалось включить ключ",
"启用屏蔽词过滤功能": "Включить функцию фильтрации запрещённых слов",
"启用所有密钥失败": "Не удалось включить все ключи",
@@ -569,9 +610,6 @@
"启用绘图功能": "Включить функцию рисования",
"启用请求体透传功能": "Включить функцию прозрачной передачи тела запроса",
"启用请求透传": "Включить прозрачную передачу запросов",
"禁用思考处理的模型列表": "Список моделей без обработки thinking",
"列出的模型将不会自动添加或移除-thinking/-nothinking 后缀": "Для этих моделей суффиксы -thinking/-nothinking не будут добавляться или удаляться автоматически.",
"请输入JSON数组如 [\"model-a\",\"model-b\"]": "Введите JSON-массив, например [\"model-a\",\"model-b\"]",
"启用额度消费日志记录": "Включить журналирование потребления квоты",
"启用验证": "Включить проверку",
"周": "Неделя",
@@ -644,6 +682,7 @@
"多密钥渠道操作项目组": "Группа операций с многоключевыми каналами",
"多密钥管理": "Управление множественными ключами",
"多种充值方式,安全便捷": "Множество способов пополнения, безопасно и удобно",
"大模型接口网关": "Шлюз API LLM",
"天": "день",
"天前": "дней назад",
"失败": "Неудача",
@@ -705,6 +744,7 @@
"密钥输入方式": "Способ ввода ключа",
"密钥预览": "Предпросмотр ключа",
"对于官方渠道new-api已经内置地址除非是第三方代理站点或者Azure的特殊接入地址否则不需要填写": "Для официальных каналов new-api уже имеет встроенные адреса, если это не сторонние прокси-сайты или специальные адреса доступа Azure, заполнять не нужно",
"对免费模型启用预消耗": "Включить предварительное списание для бесплатных моделей",
"对域名启用 IP 过滤(实验性)": "Включить IP-фильтрацию для доменов (экспериментально)",
"对外运营模式": "Режим внешней эксплуатации",
"导入": "Импорт",
@@ -728,6 +768,7 @@
"屏蔽词过滤设置": "Настройки фильтрации заблокированных слов",
"展开": "Развернуть",
"展开更多": "Развернуть больше",
"展示价格": "Отображаемая цена",
"左侧边栏个人设置": "Персональные настройки левой боковой панели",
"已为 {{count}} 个模型设置{{type}}_one": "Установлено {{type}} для {{count}} модели",
"已为 {{count}} 个模型设置{{type}}_few": "Установлено {{type}} для {{count}} моделей",
@@ -742,6 +783,10 @@
"已切换至最优倍率视图,每个模型使用其最低倍率分组": "Переключено на оптимальный вид множителей, каждая модель использует свою группу с минимальным множителем",
"已初始化": "Инициализировано",
"已删除 {{count}} 个令牌!": "Удалено {{count}} токенов!",
"已删除 {{count}} 个令牌_one": "Удалён {{count}} токен!",
"已删除 {{count}} 个令牌_few": "Удалено {{count}} токена!",
"已删除 {{count}} 个令牌_many": "Удалено {{count}} токенов!",
"已删除 {{count}} 个令牌_other": "Удалено {{count}} токенов!",
"已删除 {{count}} 条失效兑换码_one": "Удален {{count}} недействительный код купона",
"已删除 {{count}} 条失效兑换码_few": "Удалено {{count}} недействительных кода купона",
"已删除 {{count}} 条失效兑换码_many": "Удалено {{count}} недействительных кодов купонов",
@@ -783,6 +828,7 @@
"已绑定": "Привязано",
"已绑定渠道": "Каналы привязаны",
"已耗尽": "Исчерпано",
"已解锁豆包自定义 API 地址编辑": "Редактирование пользовательского API-адреса Doubao разблокировано",
"已过期": "Просрочено",
"已选择 {{count}} 个模型_one": "Выбрана {{count}} модель",
"已选择 {{count}} 个模型_few": "Выбрано {{count}} модели",
@@ -806,6 +852,7 @@
"开启之后会清除用户提示词中的": "После включения будет очищено в промптах пользователя:",
"开启之后将上游地址替换为服务器地址": "После включения адреса восходящих каналов будут заменены на адрес сервера",
"开启后,仅\"消费\"和\"错误\"日志将记录您的客户端IP地址": "После включения, только логи \"потребление\" и \"ошибки\" будут записывать IP-адрес вашего клиента",
"开启后对免费模型倍率为0或者价格为0的模型也会预消耗额度": "После включения бесплатные модели (коэффициент 0 или цена 0) тоже будут предварительно расходовать квоту",
"开启后将定期发送ping数据保持连接活跃": "После включения будет периодически отправляться ping-данные для поддержания активности соединения",
"开启后,所有请求将直接透传给上游,不会进行任何处理(重定向和渠道适配也将失效),请谨慎开启": "После включения все запросы будут напрямую передаваться upstream без какой-либо обработки (перенаправление и адаптация каналов также будут отключены), включайте с осторожностью",
"开启后不限制:必须设置模型倍率": "После включения без ограничений: необходимо установить множители моделей",
@@ -905,6 +952,7 @@
"按倍率类型筛选": "Фильтровать по типу коэффициента",
"按倍率设置": "Настроить по множителю",
"按次计费": "Оплата за использование",
"按照如下格式输入AccessKey|SecretAccessKey|Region": "Введите в формате: AccessKey|SecretAccessKey|Region",
"按量计费": "Оплата по объему",
"按顺序替换content中的变量占位符": "Последовательно заменять переменные-заполнители в content",
"换脸": "Замена лица",
@@ -924,6 +972,13 @@
"提交结果": "Результат отправки",
"提升": "Повысить",
"提示": "Промпт",
"提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}}": "Промпт {{input}} токенов / 1M токенов * {{symbol}}{{price}}",
"视频无法在当前浏览器中播放,这可能是由于:": "Видео нельзя воспроизвести в этом браузере, возможные причины:",
"• 视频服务商的跨域限制": "• Ограничения кросс-доменных запросов со стороны видеосервиса",
"• 需要特定的请求头或认证": "• Требуются специальные заголовки или авторизация",
"• 防盗链保护机制": "• Защита от хотлинков",
"在新标签页中打开": "Открыть в новой вкладке",
"复制链接": "Скопировать ссылку",
"提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "Ввод {{input}} токенов / 1M токенов * {{symbol}}{{price}} + Вывод {{completion}} токенов / 1M токенов * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"提示 {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * {{symbol}}{{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "Ввод {{nonCacheInput}} токенов / 1M токенов * {{symbol}}{{price}} + Кэш {{cacheInput}} токенов / 1M токенов * {{symbol}}{{cachePrice}} + Создание кэша {{cacheCreationInput}} токенов / 1M токенов * {{symbol}}{{cacheCreationPrice}} + Вывод {{completion}} токенов / 1M токенов * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"提示:如需备份数据,只需复制上述目录即可": "Промпт: для резервного копирования данных просто скопируйте указанный выше каталог",
@@ -1032,6 +1087,7 @@
"是否为企业账户": "Является ли корпоративным аккаунтом",
"是否同时重置对话消息?选择\"是\"将清空所有对话记录并恢复默认示例;选择\"否\"将保留当前对话记录。": "Одновременно сбросить сообщения диалога? Выбор \"Да\" очистит все записи диалогов и восстановит примеры по умолчанию; выбор \"Нет\" сохранит текущие записи диалогов.",
"是否将该订单标记为成功并为用户入账?": "Отметить этот заказ как успешный и зачислить средства пользователю?",
"是否确认充值?": "Подтвердить пополнение?",
"是否自动禁用": "Автоматически отключать",
"是否要求指纹/面容等生物识别": "Требовать биометрическую аутентификацию (отпечаток пальца/лицо и т.д.)",
"显示倍率": "Отображать коэффициент",
@@ -1049,6 +1105,7 @@
"智能熔断": "Интеллектуальный предохранитель",
"智谱": "Zhipu",
"暂无API信息": "Временно нет информации об API",
"暂无产品配置": "Конфигурации продуктов пока нет",
"暂无保存的配置": "Нет сохраненных конфигураций",
"暂无充值记录": "Нет записей о пополнении",
"暂无公告": "Нет объявлений",
@@ -1074,6 +1131,7 @@
"更多参数请参考": "Для получения дополнительных параметров см.",
"更好的价格,更好的稳定性,只需要将模型基址替换为:": "Лучшая цена, лучшая стабильность, просто замените базовый адрес модели на:",
"更新": "Обновить",
"更新 Creem 设置": "Обновить настройки Creem",
"更新 Stripe 设置": "Обновить настройки Stripe",
"更新SSRF防护设置": "Обновить настройки защиты SSRF",
"更新Worker设置": "Обновить настройки Worker",
@@ -1120,6 +1178,7 @@
"未配置的模型列表": "Список ненастроенных моделей",
"本地": "Локальный",
"本地数据存储": "Локальное хранение данных",
"本地计费": "Локальная тарификация",
"本设备:手机指纹/面容外接USB安全密钥": "Это устройство: отпечаток пальца/лицо телефона, внешнее: USB-ключ безопасности",
"本设备内置": "Встроенное в это устройство",
"本项目根据": "Этот проект основан на",
@@ -1129,6 +1188,7 @@
"条 - 第": "запись -",
"条,共": "записей, всего",
"条日志已清理!": "записей журнала очищено!",
"来自模型重定向,尚未加入模型列表": "Из перенаправления модели, ещё не добавлен в список моделей",
"查看": "Просмотр",
"查看图片": "Просмотр изображения",
"查看密钥": "Просмотр ключа",
@@ -1159,6 +1219,7 @@
"模型价格 {{symbol}}{{price}}{{ratioType}} {{ratio}}": "Цена модели {{symbol}}{{price}}, {{ratioType}} {{ratio}}",
"模型价格:{{symbol}}{{price}} * {{ratioType}}{{ratio}} = {{symbol}}{{total}}": "Цена модели: {{symbol}}{{price}} * {{ratioType}}: {{ratio}} = {{symbol}}{{total}}",
"模型倍率": "Коэффициент модели",
"模型倍率 {{modelRatio}}": "Коэффициент модели {{modelRatio}}",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}": "Коэффициент модели {{modelRatio}}, коэффициент кэша {{cacheRatio}}, коэффициент вывода {{completionRatio}}, {{ratioType}} {{ratio}}",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}Web 搜索调用 {{webSearchCallCount}} 次": "Коэффициент модели {{modelRatio}}, коэффициент кэша {{cacheRatio}}, коэффициент вывода {{completionRatio}}, {{ratioType}} {{ratio}}, вызовы веб-поиска {{webSearchCallCount}} раз",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}},图片输入倍率 {{imageRatio}}{{ratioType}} {{ratio}}": "Коэффициент модели {{modelRatio}}, коэффициент кэша {{cacheRatio}}, коэффициент вывода {{completionRatio}}, коэффициент ввода изображений {{imageRatio}}, {{ratioType}} {{ratio}}",
@@ -1181,6 +1242,7 @@
"模型数据分析": "Анализ данных моделей",
"模型映射必须是合法的 JSON 格式!": "Сопоставление моделей должно быть в допустимом формате JSON!",
"模型更新成功!": "Модель успешно обновлена!",
"模型未加入列表,可能无法调用": "Модель не добавлена в список, вызовы могут не работать",
"模型消耗分布": "Распределение потребления моделей",
"模型消耗趋势": "Тенденции потребления моделей",
"模型版本": "Версия модели",
@@ -1196,15 +1258,18 @@
"模型选择和映射设置": "Настройки выбора и сопоставления моделей",
"模型配置": "Конфигурация модели",
"模型重定向": "Перенаправление модели",
"模型重定向里的下列模型尚未添加到“模型”列表,调用时会因为缺少可用模型而失败:": "Следующие модели из перенаправления ещё не добавлены в список «Модели», из-за отсутствия доступных моделей вызовы завершатся ошибкой:",
"模型限制列表": "Список ограничений модели",
"模板示例": "Пример шаблона",
"模糊搜索模型名称": "Нечеткий поиск по названию модели",
"次": "раз",
"欢迎使用,请完成以下设置以开始使用系统": "Добро пожаловать, пожалуйста, выполните следующие настройки, чтобы начать использовать систему",
"欧元": "Евро",
"正在处理大内容...": "Обработка большого содержимого...",
"正在提交": "Отправка...",
"正在构造请求体预览...": "Создание предварительного просмотра тела запроса...",
"正在测试第 ${current} - ${end} 个模型 (共 ${total} 个)": "Тестирование моделей с ${current} по ${end} (всего ${total})",
"正在跳转 GitHub...": "Перенаправление на GitHub...",
"正在跳转...": "Переход...",
"此代理仅用于图片请求转发Webhook通知发送等AI API请求仍然由服务器直接发出可在渠道设置中单独配置代理": "Этот прокси используется только для пересылки изображений, отправки уведомлений Webhook и т.д., AI API запросы по-прежнему отправляются напрямую сервером, прокси можно настроить отдельно в настройках канала",
"此修改将不可逆": "Это изменение будет необратимым",
@@ -1256,6 +1321,7 @@
"测试失败": "Тест не удался",
"测试所有渠道的最长响应时间": "Максимальное время отклика для тестирования всех каналов",
"测试所有通道": "Тестировать все каналы",
"测试模式": "Тестовый режим",
"测速": "Измерение скорости",
"消息优先级": "Приоритет сообщения",
"消息优先级范围0-10默认为5": "Приоритет сообщения, диапазон 0-10, по умолчанию 5",
@@ -1271,10 +1337,12 @@
"深色模式": "Тёмный режим",
"添加": "Добавить",
"添加API": "Добавить API",
"添加产品": "Добавить продукт",
"添加令牌": "Добавить токен",
"添加兑换码": "Добавить код купона",
"添加公告": "Добавить объявление",
"添加分类": "Добавить категорию",
"添加后提交": "Отправить после добавления",
"添加成功": "Добавлено успешно",
"添加模型": "Добавить модель",
"添加模型区域": "Добавить область модели",
@@ -1332,9 +1400,11 @@
"生成音乐": "Сгенерировать музыку",
"用于API调用的身份验证令牌请妥善保管": "Токен аутентификации для API вызовов, пожалуйста, храните его надёжно",
"用于配置网络代理,支持 socks5 协议": "Используется для настройки сетевого прокси, поддерживает протокол socks5",
"用于验证回调 new-api 的 webhook 请求的密钥,敏感信息不显示": "Ключ для проверки обратных запросов new-api по webhook, чувствительные данные не показываются.",
"用以支持基于 WebAuthn 的无密码登录注册": "Используется для поддержки входа и регистрации без пароля на основе WebAuthn",
"用以支持用户校验": "Используется для поддержки проверки пользователей",
"用以支持系统的邮件发送": "Используется для поддержки отправки электронной почты системой",
"用以支持通过 Discord 进行登录注册": "Используется для поддержки входа и регистрации через Discord",
"用以支持通过 GitHub 进行登录注册": "Используется для поддержки входа и регистрации через GitHub",
"用以支持通过 Linux DO 进行登录注册": "Используется для поддержки входа и регистрации через Linux DO",
"用以支持通过 OIDC 登录,例如 Okta、Auth0 等兼容 OIDC 协议的 IdP": "Используется для поддержки входа через OIDC, например Okta, Auth0 и другие IdP, совместимые с протоколом OIDC",
@@ -1379,6 +1449,7 @@
"的前提下使用。": "использовать при условии.",
"监控设置": "Настройки мониторинга",
"目标用户:{{username}}": "Целевой пользователь: {{username}}",
"直接提交": "Отправить напрямую",
"相关项目": "Связанные проекты",
"相当于删除用户,此修改将不可逆": "Эквивалентно удалению пользователя, это изменение будет необратимым",
"矛盾": "Противоречие",
@@ -1399,6 +1470,7 @@
"确定清除所有失效兑换码?": "Подтвердить очистку всех недействительных кодов купонов?",
"确定要修改所有子渠道优先级为 ": "Подтвердить изменение приоритета всех дочерних каналов на ",
"确定要修改所有子渠道权重为 ": "Подтвердить изменение веса всех дочерних каналов на ",
"确定要充值 $": "Подтвердить пополнение на $",
"确定要删除供应商 \"{{name}}\" 吗?此操作不可撤销。": "Подтвердить удаление поставщика \"{{name}}\"? Это действие нельзя отменить.",
"确定要删除所有已自动禁用的密钥吗?": "Подтвердить удаление всех автоматически отключенных ключей?",
"确定要删除所选的 {{count}} 个令牌吗_one": "Подтвердить удаление выбранного {{count}} токена?",
@@ -1452,6 +1524,7 @@
"禁用原因": "Причина отключения",
"禁用后的影响:": "Последствия отключения:",
"禁用密钥失败": "Ошибка отключения ключа",
"禁用思考处理的模型列表": "Список моделей без обработки thinking",
"禁用所有密钥失败": "Ошибка отключения всех ключей",
"禁用时间": "Время отключения",
"私有IP访问详细说明": "⚠️ Предупреждение безопасности: включение этой опции позволит доступ к ресурсам внутренней сети (localhost, частные сети). Включайте только при необходимости доступа к внутренним службам и понимании рисков безопасности.",
@@ -1476,6 +1549,7 @@
"管理员": "Администратор",
"管理员区域": "Область администратора",
"管理员暂时未设置任何关于内容": "Администратор пока не установил никакой информации о проекте",
"管理员未开启 Creem 充值!": "Администратор не включил пополнение через Creem!",
"管理员未开启Stripe充值": "Администратор не включил пополнение через Stripe!",
"管理员未开启在线充值!": "Администратор не включил онлайн пополнение!",
"管理员未开启在线充值功能,请联系管理员开启或使用兑换码充值。": "Администратор не включил функцию онлайн пополнения, свяжитесь с администратором для включения или используйте коды купонов для пополнения.",
@@ -1528,24 +1602,33 @@
"绘图任务记录": "Записи задач рисования",
"绘图日志": "Журнал рисования",
"绘图设置": "Настройки рисования",
"统一的": "Единый",
"统计Tokens": "Статистика токенов",
"统计次数": "Статистика количества",
"统计额度": "Статистика лимитов",
"继续": "Продолжить",
"缓存 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Кэш {{tokens}} токенов / 1M токенов * {{symbol}}{{price}} (множитель: {{ratio}})",
"缓存 Tokens": "Кэширование токенов",
"缓存: {{cacheRatio}}": "Кэш: {{cacheRatio}}",
"缓存价格:{{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})": "Цена кэша: {{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M токенов (коэффициент кэширования: {{cacheRatio}})",
"缓存价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})": "Цена кэша: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M токенов (коэффициент кэширования: {{cacheRatio}})",
"缓存倍率": "Коэффициент кэширования",
"缓存倍率 {{cacheRatio}}": "Коэффициент кэша {{cacheRatio}}",
"缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "Создание кэша {{tokens}} токенов / 1M токенов * {{symbol}}{{price}} (множитель: {{ratio}})",
"缓存创建 Tokens": "Создание кэша токенов",
"缓存创建: {{cacheCreationRatio}}": "Создание кэша: {{cacheCreationRatio}}",
"缓存创建: 5m {{cacheCreationRatio5m}}": "Создание кэша: 5m {{cacheCreationRatio5m}}",
"缓存创建: 1h {{cacheCreationRatio1h}}": "Создание кэша: 1h {{cacheCreationRatio1h}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}}": "Множитель создания кэша 5m {{cacheCreationRatio5m}}",
"缓存创建倍率 1h {{cacheCreationRatio1h}}": "Множитель создания кэша 1h {{cacheCreationRatio1h}}",
"缓存创建: 5m {{cacheCreationRatio5m}}": "Создание кэша: 5m {{cacheCreationRatio5m}}",
"缓存创建: 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}": "Создание кэша: 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}",
"缓存创建价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})": "Цена создания кэша: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M токенов (коэффициент создания кэша: {{cacheCreationRatio}})",
"缓存创建价格合计5m {{symbol}}{{five}} + 1h {{symbol}}{{one}} = {{symbol}}{{total}} / 1M tokens": "Итого цена создания кэша: 5m {{symbol}}{{five}} + 1h {{symbol}}{{one}} = {{symbol}}{{total}} / 1M токенов",
"缓存创建倍率 {{cacheCreationRatio}}": "Коэффициент создания кэша {{cacheCreationRatio}}",
"缓存创建倍率 1h {{cacheCreationRatio1h}}": "Множитель создания кэша 1h {{cacheCreationRatio1h}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}}": "Множитель создания кэша 5m {{cacheCreationRatio5m}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}": "Коэффициент создания кэша 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}",
"编辑": "Редактировать",
"编辑API": "Редактировать API",
"编辑产品": "Редактировать продукт",
"编辑供应商": "Редактировать поставщика",
"编辑公告": "Редактировать объявление",
"编辑公告内容": "Редактировать содержимое объявления",
@@ -1563,6 +1646,7 @@
"网站域名标识": "Идентификатор домена веб-сайта",
"网络错误": "Сетевая ошибка",
"置信度": "Уровень доверия",
"美元": "Доллар США",
"聊天": "Чат",
"聊天会话管理": "Управление сессиями чата",
"聊天区域": "Область чата",
@@ -1609,6 +1693,7 @@
"获取金额失败": "Не удалось получить сумму",
"获取验证码": "Получить код подтверждения",
"补全": "Вывод",
"补全 {{completion}} tokens / 1M tokens * {{symbol}}{{price}}": "Дополнение {{completion}} токенов / 1M токенов * {{symbol}}{{price}}",
"补全价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "Цена вывода: {{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M токенов (коэффициент вывода: {{completionRatio}})",
"补全价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens": "Цена вывода: {{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M токенов",
"补全倍率": "Коэффициент вывода",
@@ -1625,6 +1710,7 @@
"解析密钥文件失败: {{msg}}": "Не удалось разобрать файл ключа: {{msg}}",
"解绑 Passkey": "Отвязать Passkey",
"解绑后将无法使用 Passkey 登录,确定要继续吗?": "После отвязки невозможно будет использовать Passkey для входа, продолжить?",
"计费模式": "Режим тарификации",
"计费类型": "Тип выставления счёта",
"计费过程": "Процесс выставления счёта",
"订单号": "Номер заказа",
@@ -1688,6 +1774,7 @@
"请前往个人设置 → 安全设置进行配置。": "Пожалуйста, перейдите в Личные настройки → Настройки безопасности для конфигурации.",
"请勿过度信任此功能IP可能被伪造": "Не доверяйте этой функции чрезмерно, IP может быть подделан",
"请在系统设置页面编辑分组倍率以添加新的分组:": "Пожалуйста, отредактируйте коэффициенты групп на странице системных настроек для добавления новой группы:",
"请填写完整的产品信息": "Пожалуйста, заполните всю информацию о продукте",
"请填写完整的管理员账号信息": "Пожалуйста, заполните полную информацию об учётной записи администратора",
"请填写密钥": "Пожалуйста, заполните ключ",
"请填写渠道名称和渠道密钥!": "Пожалуйста, заполните имя канала и ключ канала!",
@@ -1702,10 +1789,11 @@
"请求失败": "Запрос не удался",
"请求头覆盖": "Переопределение заголовков запроса",
"请求并计费模型": "Запрос и выставление счёта модели",
"请求路径": "Путь запроса",
"请求时长: ${time}s": "Время запроса: ${time}s",
"请求次数": "Количество запросов",
"请求结束后多退少补": "После вывода запроса возврат излишков и доплата недостатка",
"请求超时,请刷新页面后重新发起 GitHub 登录": "Время ожидания истекло, обновите страницу и снова запустите вход через GitHub",
"请求路径": "Путь запроса",
"请求预扣费额度": "Запрос суммы предварительного удержания",
"请点击我": "Пожалуйста, нажмите на меня",
"请确认以下设置信息,点击\"初始化系统\"开始配置": "Пожалуйста, подтвердите следующую информацию о настройках, нажмите \"Инициализация системы\" для начала конфигурации",
@@ -1722,6 +1810,8 @@
"请至少选择一个模型": "Пожалуйста, выберите хотя бы одну модель",
"请至少选择一个模型!": "Пожалуйста, выберите хотя бы одну модель!",
"请至少选择一个渠道": "Пожалуйста, выберите хотя бы один канал",
"请输入 API Key一行一个格式APIKey|Region": "Введите API Key, по одному в строке, формат: APIKey|Region",
"请输入 API Key格式APIKey|Region": "Введите API Key в формате: APIKey|Region",
"请输入 AZURE_OPENAI_ENDPOINT例如https://docs-test-001.openai.azure.com": "Пожалуйста, введите AZURE_OPENAI_ENDPOINT, например: https://docs-test-001.openai.azure.com",
"请输入 JSON 格式的密钥内容,例如:\n{\n \"type\": \"service_account\",\n \"project_id\": \"your-project-id\",\n \"private_key_id\": \"...\",\n \"private_key\": \"...\",\n \"client_email\": \"...\",\n \"client_id\": \"...\",\n \"auth_uri\": \"...\",\n \"token_uri\": \"...\",\n \"auth_provider_x509_cert_url\": \"...\",\n \"client_x509_cert_url\": \"...\"\n}": "Пожалуйста, введите содержимое ключа в формате JSON, например:\n{\n \"type\": \"service_account\",\n \"project_id\": \"your-project-id\",\n \"private_key_id\": \"...\",\n \"private_key\": \"...\",\n \"client_email\": \"...\",\n \"client_id\": \"...\",\n \"auth_uri\": \"...\",\n \"token_uri\": \"...\",\n \"auth_provider_x509_cert_url\": \"...\",\n \"client_x509_cert_url\": \"...\"\n}",
"请输入 OIDC 的 Well-Known URL": "Пожалуйста, введите Well-Known URL OIDC",
@@ -1733,6 +1823,7 @@
"请输入Gotify应用令牌": "Пожалуйста, введите токен приложения Gotify",
"请输入Gotify服务器地址": "Пожалуйста, введите адрес сервера Gotify",
"请输入Gotify服务器地址例如: https://gotify.example.com": "Пожалуйста, введите адрес сервера Gotify, например: https://gotify.example.com",
"请输入JSON数组如 [\"model-a\",\"model-b\"]": "Введите JSON-массив, например [\"model-a\",\"model-b\"]",
"请输入Uptime Kuma地址": "Пожалуйста, введите адрес Uptime Kuma",
"请输入Uptime Kuma服务地址https://status.example.com": "Пожалуйста, введите адрес службы Uptime Kuma, например: https://status.example.com",
"请输入URL链接": "Пожалуйста, введите URL-ссылку",
@@ -1763,6 +1854,7 @@
"请输入密码": "Пожалуйста, введите пароль",
"请输入密钥": "Пожалуйста, введите ключ",
"请输入密钥,一行一个": "Пожалуйста, введите ключи, по одному в строке",
"请输入密钥一行一个格式AccessKey|SecretAccessKey|Region": "Введите ключи по одному в строке в формате: AccessKey|SecretAccessKey|Region",
"请输入密钥!": "Пожалуйста, введите ключ!",
"请输入您的密码": "Пожалуйста, введите ваш пароль",
"请输入您的用户名以确认删除": "Пожалуйста, введите ваше имя пользователя для подтверждения удаления",
@@ -1817,6 +1909,7 @@
"请输入验证码或备用码": "Пожалуйста, введите код подтверждения или резервный код",
"请输入默认 API 版本例如2025-04-01-preview": "Пожалуйста, введите версию API по умолчанию, например: 2025-04-01-preview",
"请选择API地址": "Пожалуйста, выберите адрес API",
"请选择产品": "Выберите продукт",
"请选择你的复制方式": "Пожалуйста, выберите ваш способ копирования",
"请选择使用模式": "Пожалуйста, выберите режим использования",
"请选择分组": "Пожалуйста, выберите группу",
@@ -1857,6 +1950,7 @@
"账户绑定": "Привязка учётной записи",
"账户绑定、安全设置和身份验证": "Привязка учётной записи, настройки безопасности и аутентификация",
"账户统计": "Статистика учётной записи",
"货币": "Валюта",
"货币单位": "Валюта",
"购买兑换码": "Покупка кодов купонов",
"资源消耗": "Потребление ресурсов",
@@ -1901,12 +1995,14 @@
"输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}": "Вывод {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}",
"输出价格": "Цена вывода",
"输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "Цена вывода: {{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M токенов (коэффициент вывода: {{completionRatio}})",
"输出倍率 {{completionRatio}}": "Коэффициент вывода {{completionRatio}}",
"边栏设置": "Настройки боковой панели",
"过期时间": "Время истечения",
"过期时间不能早于当前时间!": "Время истечения не может быть раньше текущего времени!",
"过期时间快捷设置": "Быстрая настройка времени истечения",
"过期时间格式错误!": "Ошибка формата времени истечения!",
"运营设置": "Операционные настройки",
"返回修改": "Вернуться и исправить",
"返回登录": "Вернуться к входу",
"这是重复键中的最后一个,其值将被使用": "Это последний ключ в повторяющихся, его значение будет использовано",
"进度": "Прогресс",
@@ -1984,6 +2080,7 @@
"部分渠道测试失败:": "Частичный сбой тестирования каналов:",
"部署地区": "Регион развертывания",
"配置": "Конфигурация",
"配置 Discord OAuth": "Настроить Discord OAuth",
"配置 GitHub OAuth App": "Настроить GitHub OAuth App",
"配置 Linux DO OAuth": "Настроить Linux DO OAuth",
"配置 OIDC": "Настроить OIDC",
@@ -2025,6 +2122,7 @@
"错误": "Ошибка",
"键为分组名称,值为另一个 JSON 对象,键为分组名称,值为该分组的用户的特殊分组倍率,例如:{\"vip\": {\"default\": 0.5, \"test\": 1}},表示 vip 分组的用户在使用default分组的令牌时倍率为0.5使用test分组时倍率为1": "Ключ - это имя группы, значение - другой JSON объект, ключ - имя группы, значение - специальный групповой коэффициент для пользователей этой группы, например: {\"vip\": {\"default\": 0.5, \"test\": 1}}, означает, что пользователи группы vip при использовании токенов группы default имеют коэффициент 0.5, при использовании группы test - коэффициент 1",
"键为原状态码,值为要复写的状态码,仅影响本地判断": "Ключ - исходный код состояния, значение - код состояния для перезаписи, влияет только на локальную проверку",
"键为用户分组名称,值为操作映射对象。内层键以\"+:\"开头表示添加指定分组(键值为分组名称,值为描述),以\"-:\"开头表示移除指定分组(键值为分组名称),不带前缀的键直接添加该分组。例如:{\"vip\": {\"+:premium\": \"高级分组\", \"special\": \"特殊分组\", \"-:default\": \"默认分组\"}},表示 vip 分组的用户可以使用 premium 和 special 分组,同时移除 default 分组的访问权限": "Ключ — это название группы пользователей, значение — объект сопоставления операций. Внутренние ключи с префиксом \"+:\" добавляют указанные группы (ключ — название группы, значение — описание), с префиксом \"-:\" удаляют указанные группы, без префикса — сразу добавляют эту группу. Пример: {\"vip\": {\"+:premium\": \"Продвинутая группа\", \"special\": \"Особая группа\", \"-:default\": \"Группа по умолчанию\"}} означает, что пользователи группы vip могут использовать группы premium и special, одновременно теряя доступ к группе default.",
"键为端点类型,值为路径和方法对象": "Ключ - тип конечной точки, значение - объект пути и метода",
"键为请求中的模型名称,值为要替换的模型名称": "Ключ - имя модели в запросе, значение - имя модели для замены",
"键名": "Имя ключа",
@@ -2098,10 +2196,45 @@
"默认区域,如: us-central1": "Регион по умолчанию, например: us-central1",
"默认折叠侧边栏": "Сворачивать боковую панель по умолчанию",
"默认测试模型": "Модель для тестирования по умолчанию",
"默认补全倍率": "Коэффициент вывода по умолчанию",
"统一的": "Единый",
"大模型接口网关": "Шлюз API LLM",
"正在跳转 GitHub...": "Перенаправление на GitHub...",
"请求超时,请刷新页面后重新发起 GitHub 登录": "Время ожидания истекло, обновите страницу и снова запустите вход через GitHub"
"请先在设置中启用图片功能": "Сначала включите функцию изображений в настройках",
"图片已添加": "Изображение добавлено",
"无法添加图片": "Невозможно добавить изображение",
"粘贴图片失败": "Ошибка вставки изображения",
"支持 Ctrl+V 粘贴图片": "Поддержка Ctrl+V для вставки изображения",
"已复制全部数据": "Все данные скопированы",
"流式响应完成": "Поток завершён",
"图片地址": "URL изображения",
"已在自定义模式中忽略": "Игнорируется в пользовательском режиме",
"停用": "Отключить",
"图片功能在自定义请求体模式下不可用": "Функция изображений недоступна в режиме пользовательского запроса",
"启用后可添加图片URL进行多模态对话": "Включите для добавления URL изображений для мультимодального диалога",
"点击 + 按钮添加图片URL进行多模态对话": "Нажмите + для добавления URL изображений для мультимодального диалога",
"已添加": "Добавлено",
"张图片": "изображений",
"自定义模式下不可用": "Недоступно в пользовательском режиме",
"控制输出的随机性和创造性": "Управляет случайностью и креативностью вывода",
"核采样,控制词汇选择的多样性": "Ядерная выборка, управляет разнообразием выбора слов",
"频率惩罚,减少重复词汇的出现": "Штраф за частоту, уменьшает повторение слов",
"存在惩罚,鼓励讨论新话题": "Штраф за присутствие, поощряет новые темы",
"流式输出": "Потоковый вывод",
"暂无SSE响应数据": "Нет данных ответа SSE",
"SSE数据流": "Поток данных SSE",
"解析错误": "Ошибка разбора",
"有 Reasoning": "Есть рассуждение",
"全部收起": "Свернуть всё",
"全部展开": "Развернуть всё",
"SSE 事件": "Событие SSE",
"JSON格式错误": "Ошибка формата JSON",
"自定义请求体模式": "Режим пользовательского тела запроса",
"启用此模式后将使用您自定义的请求体发送API请求模型配置面板的参数设置将被忽略。": "При включении ваше пользовательское тело запроса будет использоваться для API-запросов, а настройки параметров на панели конфигурации модели будут игнорироваться.",
"请求体 JSON": "Тело запроса JSON",
"格式正确": "Действительный формат",
"格式错误": "Недействительный формат",
"格式化": "Форматировать",
"请输入有效的JSON格式的请求体。您可以参考预览面板中的默认请求体格式。": "Пожалуйста, введите тело запроса в действительном формате JSON. Вы можете обратиться к формату тела запроса по умолчанию на панели предварительного просмотра.",
"默认用户消息": "Здравствуйте",
"默认助手消息": "Здравствуйте! Чем я могу вам помочь?",
"可选,用于复现结果": "Необязательно, для воспроизводимых результатов",
"随机种子 (留空为随机)": "Случайное зерно (оставьте пустым для случайного)"
}
}
}

View File

@@ -2387,10 +2387,10 @@
"例如100000": "Ví dụ: 100000",
"请填写完整的产品信息": "Vui lòng điền đầy đủ thông tin sản phẩm",
"产品ID已存在": "ID sản phẩm đã tồn tại",
"统一的": "Thống nhất",
"统一的": "Cổng thống nhất",
"大模型接口网关": "Cổng API LLM",
"正在跳转 GitHub...": "Đang chuyển hướng đến GitHub...",
"请求超时,请刷新页面后重新发起 GitHub 登录": "Yêu cầu đã hết thời gian, vui lòng làm mới trang và thử đăng nhập lại GitHub",
"请求超时,请刷新页面后重新发起 GitHub 登录": "Hết thời gian chờ, vui lòng làm mới trang và đăng nhập GitHub lại",
"模型: {{ratio}}": "Mô hình: {{ratio}}",
"模型专用区域": "Khu vực dành riêng cho mô hình",
"模型价格": "Giá mô hình",
@@ -2695,6 +2695,46 @@
"线路描述": "Mô tả tuyến",
"组列表": "Danh sách nhóm",
"组名": "Tên nhóm",
"组织,不填则为默认组织": "Tổ chức, mặc định nếu để trống"
"组织,不填则为默认组织": "Tổ chức, mặc định nếu để trống",
"请先在设置中启用图片功能": "Vui lòng bật chức năng hình ảnh trong cài đặt trước",
"图片已添加": "Hình ảnh đã được thêm",
"无法添加图片": "Không thể thêm hình ảnh",
"粘贴图片失败": "Dán hình ảnh thất bại",
"支持 Ctrl+V 粘贴图片": "Hỗ trợ Ctrl+V để dán hình ảnh",
"已复制全部数据": "Tất cả dữ liệu đã được sao chép",
"流式响应完成": "Luồng hoàn tất",
"图片地址": "URL hình ảnh",
"已在自定义模式中忽略": "Bị bỏ qua trong chế độ tùy chỉnh",
"停用": "Vô hiệu hóa",
"图片功能在自定义请求体模式下不可用": "Chức năng hình ảnh không khả dụng trong chế độ yêu cầu tùy chỉnh",
"启用后可添加图片URL进行多模态对话": "Bật để thêm URL hình ảnh cho cuộc trò chuyện đa phương thức",
"点击 + 按钮添加图片URL进行多模态对话": "Nhấp + để thêm URL hình ảnh cho cuộc trò chuyện đa phương thức",
"已添加": "Đã thêm",
"张图片": "hình ảnh",
"自定义模式下不可用": "Không khả dụng trong chế độ tùy chỉnh",
"控制输出的随机性和创造性": "Kiểm soát tính ngẫu nhiên và sáng tạo của đầu ra",
"核采样,控制词汇选择的多样性": "Lấy mẫu hạt nhân, kiểm soát sự đa dạng của lựa chọn từ vựng",
"频率惩罚,减少重复词汇的出现": "Phạt tần suất, giảm sự lặp lại của từ",
"存在惩罚,鼓励讨论新话题": "Phạt sự hiện diện, khuyến khích chủ đề mới",
"流式输出": "Đầu ra luồng",
"暂无SSE响应数据": "Không có dữ liệu phản hồi SSE",
"SSE数据流": "Luồng dữ liệu SSE",
"解析错误": "Lỗi phân tích",
"有 Reasoning": "Có lập luận",
"全部收起": "Thu gọn tất cả",
"全部展开": "Mở rộng tất cả",
"SSE 事件": "Sự kiện SSE",
"JSON格式错误": "Lỗi định dạng JSON",
"自定义请求体模式": "Chế độ nội dung yêu cầu tùy chỉnh",
"启用此模式后将使用您自定义的请求体发送API请求模型配置面板的参数设置将被忽略。": "Khi được bật, nội dung yêu cầu tùy chỉnh của bạn sẽ được sử dụng cho các yêu cầu API và cài đặt tham số trong bảng cấu hình mô hình sẽ bị bỏ qua.",
"请求体 JSON": "Nội dung yêu cầu JSON",
"格式正确": "Định dạng hợp lệ",
"格式错误": "Định dạng không hợp lệ",
"格式化": "Định dạng",
"请输入有效的JSON格式的请求体。您可以参考预览面板中的默认请求体格式。": "Vui lòng nhập nội dung yêu cầu có định dạng JSON hợp lệ. Bạn có thể tham khảo định dạng nội dung yêu cầu mặc định trong bảng xem trước.",
"默认用户消息": "Xin chào",
"默认助手消息": "Xin chào! Tôi có thể giúp gì cho bạn?",
"可选,用于复现结果": "Tùy chọn, để tái tạo kết quả",
"随机种子 (留空为随机)": "Hạt giống ngẫu nhiên (để trống cho ngẫu nhiên)"
}
}

View File

@@ -16,7 +16,9 @@
"[最多请求次数]和[最多请求完成次数]的最大值为2147483647。": "[最多请求次数]和[最多请求完成次数]的最大值为2147483647。",
"[最多请求次数]必须大于等于0[最多请求完成次数]必须大于等于1。": "[最多请求次数]必须大于等于0[最多请求完成次数]必须大于等于1。",
"{\n \"default\": [200, 100],\n \"vip\": [0, 1000]\n}": "{\n \"default\": [200, 100],\n \"vip\": [0, 1000]\n}",
"{{breakdown}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "{{breakdown}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}": "{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}",
"{{ratioType}} {{ratio}}": "{{ratioType}} {{ratio}}",
"© {{currentYear}}": "© {{currentYear}}",
"| 基于": "| 基于",
"$/1M tokens": "$/1M tokens",
@@ -24,15 +26,20 @@
"0.002-1之间的小数": "0.002-1之间的小数",
"0.1以上的小数": "0.1以上的小数",
"10 - 最高": "10 - 最高",
"1h缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "1h缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})",
"1h缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (1h缓存创建倍率: {{cacheCreationRatio1h}})": "1h缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (1h缓存创建倍率: {{cacheCreationRatio1h}})",
"2 - 低": "2 - 低",
"2025年5月10日后添加的渠道不需要再在部署的时候移除模型名称中的\".\"": "2025年5月10日后添加的渠道不需要再在部署的时候移除模型名称中的\".\"",
"360智脑": "360智脑",
"5 - 正常(默认)": "5 - 正常(默认)",
"5m缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "5m缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})",
"5m缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (5m缓存创建倍率: {{cacheCreationRatio5m}})": "5m缓存创建价格{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (5m缓存创建倍率: {{cacheCreationRatio5m}})",
"8 - 高": "8 - 高",
"AGPL v3.0协议": "AGPL v3.0协议",
"AI 对话": "AI 对话",
"AI模型测试环境": "AI模型测试环境",
"AI模型配置": "AI模型配置",
"AK/SK 模式:使用 AccessKey 和 SecretAccessKeyAPI Key 模式:使用 API Key": "AK/SK 模式:使用 AccessKey 和 SecretAccessKeyAPI Key 模式:使用 API Key",
"API Key 模式下不支持批量创建": "API Key 模式下不支持批量创建",
"API 地址和相关配置": "API 地址和相关配置",
"API 密钥": "API 密钥",
@@ -58,17 +65,25 @@
"Client ID": "Client ID",
"Client Secret": "Client Secret",
"common.changeLanguage": "common.changeLanguage",
"Creem API 密钥,敏感信息不显示": "Creem API 密钥,敏感信息不显示",
"Creem Setting Tips": "Creem 只支持预设的固定金额产品这产品以及价格需要提前在Creem网站内创建配置所以不支持自定义动态金额充值。在Creem端配置产品的名字以及价格获取Product Id 后填到下面的产品在new-api为该产品设置充值额度以及展示价格。",
"Creem 介绍": "Creem 是一个简单的支付处理平台,支持固定金额产品销售,以及订阅销售。",
"Creem 充值": "Creem 充值",
"Creem 设置": "Creem 设置",
"default为默认设置可单独设置每个分类的安全等级": "default为默认设置可单独设置每个分类的安全等级",
"default为默认设置可单独设置每个模型的版本": "default为默认设置可单独设置每个模型的版本",
"Dify渠道只适配chatflow和agent并且agent不支持图片": "Dify渠道只适配chatflow和agent并且agent不支持图片",
"Discord": "Discord",
"Discord Client ID": "Discord Client ID",
"Discord Client Secret": "Discord Client Secret",
"Discord ID": "Discord ID",
"EUR (欧元)": "EUR (欧元)",
"false": "false",
"Gemini安全设置": "Gemini安全设置",
"Gemini思考适配 BudgetTokens = MaxTokens * BudgetTokens 百分比": "Gemini思考适配 BudgetTokens = MaxTokens * BudgetTokens 百分比",
"Gemini思考适配设置": "Gemini思考适配设置",
"Gemini版本设置": "Gemini版本设置",
"Gemini设置": "Gemini设置",
"启用FunctionCall思维签名填充": "启用FunctionCall思维签名填充",
"仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature": "仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature",
"GitHub": "GitHub",
"GitHub Client ID": "GitHub Client ID",
"GitHub Client Secret": "GitHub Client Secret",
@@ -133,7 +148,9 @@
"Uptime Kuma地址": "Uptime Kuma地址",
"Uptime Kuma监控分类管理可以配置多个监控分类用于服务状态展示最多20个": "Uptime Kuma监控分类管理可以配置多个监控分类用于服务状态展示最多20个",
"URL链接": "URL链接",
"USD (美元)": "USD (美元)",
"User Info Endpoint": "User Info Endpoint",
"Webhook 密钥": "Webhook 密钥",
"Webhook 签名密钥": "Webhook 签名密钥",
"Webhook地址": "Webhook地址",
"Webhook地址必须以https://开头": "Webhook地址必须以https://开头",
@@ -158,6 +175,7 @@
"上一步": "上一步",
"上次保存: ": "上次保存: ",
"上游倍率同步": "上游倍率同步",
"上游返回": "上游返回",
"下一个表单块": "下一个表单块",
"下一步": "下一步",
"下午好": "下午好",
@@ -206,6 +224,12 @@
"主页链接填": "主页链接填",
"之前的所有日志": "之前的所有日志",
"二步验证已重置": "二步验证已重置",
"产品ID": "产品ID",
"产品ID已存在": "产品ID已存在",
"产品名称": "产品名称",
"产品配置": "产品配置",
"产品配置错误,请联系管理员": "产品配置错误,请联系管理员",
"仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature": "仅为使用OpenAI格式的Gemini/Vertex渠道填充thoughtSignature",
"仅会覆盖你勾选的字段,未勾选的字段保持本地不变。": "仅会覆盖你勾选的字段,未勾选的字段保持本地不变。",
"仅供参考,以实际扣费为准": "仅供参考,以实际扣费为准",
"仅保存": "仅保存",
@@ -256,8 +280,9 @@
"余额": "余额",
"余额充值管理": "余额充值管理",
"你似乎并没有修改什么": "你似乎并没有修改什么",
"使用 GitHub 继续": "使用 GitHub 继续",
"你可以在“自定义模型名称”处手动添加它们,然后点击填入后再提交,或者直接使用下方操作自动处理。": "你可以在“自定义模型名称”处手动添加它们,然后点击填入后再提交,或者直接使用下方操作自动处理。",
"使用 Discord 继续": "使用 Discord 继续",
"使用 GitHub 继续": "使用 GitHub 继续",
"使用 JSON 对象格式,格式为:{\"组名\": [最多请求次数, 最多请求完成次数]}": "使用 JSON 对象格式,格式为:{\"组名\": [最多请求次数, 最多请求完成次数]}",
"使用 LinuxDO 继续": "使用 LinuxDO 继续",
"使用 OIDC 继续": "使用 OIDC 继续",
@@ -279,12 +304,16 @@
"例如: socks5://user:pass@host:port": "例如: socks5://user:pass@host:port",
"例如0001": "例如0001",
"例如1000": "例如1000",
"例如100000": "例如100000",
"例如2就是最低充值2$": "例如2就是最低充值2$",
"例如2000": "例如2000",
"例如4.99": "例如4.99",
"例如7就是7元/美金": "例如7就是7元/美金",
"例如example.com": "例如example.com",
"例如https://yourdomain.com": "例如https://yourdomain.com",
"例如preview": "例如preview",
"例如prod_6I8rBerHpPxyoiU9WK4kot": "例如prod_6I8rBerHpPxyoiU9WK4kot",
"例如:基础套餐": "例如:基础套餐",
"例如发卡网站的购买链接": "例如发卡网站的购买链接",
"供应商": "供应商",
"供应商介绍": "供应商介绍",
@@ -297,6 +326,7 @@
"侧边栏管理(全局控制)": "侧边栏管理(全局控制)",
"侧边栏设置保存成功": "侧边栏设置保存成功",
"保存": "保存",
"保存 Discord OAuth 设置": "保存 Discord OAuth 设置",
"保存 GitHub OAuth 设置": "保存 GitHub OAuth 设置",
"保存 Linux DO OAuth 设置": "保存 Linux DO OAuth 设置",
"保存 OIDC 设置": "保存 OIDC 设置",
@@ -349,6 +379,7 @@
"允许的IP一行一个不填写则不限制": "允许的IP一行一个不填写则不限制",
"允许的端口": "允许的端口",
"允许访问私有IP地址127.0.0.1、192.168.x.x等内网地址": "允许访问私有IP地址127.0.0.1、192.168.x.x等内网地址",
"允许通过 Discord 账户登录 & 注册": "允许通过 Discord 账户登录 & 注册",
"允许通过 GitHub 账户登录 & 注册": "允许通过 GitHub 账户登录 & 注册",
"允许通过 Linux DO 账户登录 & 注册": "允许通过 Linux DO 账户登录 & 注册",
"允许通过 OIDC 进行登录": "允许通过 OIDC 进行登录",
@@ -404,6 +435,7 @@
"共": "共",
"共 {{count}} 个密钥_other": "共 {{count}} 个密钥",
"共 {{count}} 个模型": "共 {{count}} 个模型",
"共 {{count}} 个模型_other": "共 {{count}} 个模型",
"共 {{total}} 项,当前显示 {{start}}-{{end}} 项": "共 {{total}} 项,当前显示 {{start}}-{{end}} 项",
"关": "关",
"关于": "关于",
@@ -420,6 +452,7 @@
"其他注册选项": "其他注册选项",
"其他登录选项": "其他登录选项",
"其他设置": "其他设置",
"其他详情": "其他详情",
"内容": "内容",
"内容较大,已启用性能优化模式": "内容较大,已启用性能优化模式",
"内容较大,部分功能可能受限": "内容较大,部分功能可能受限",
@@ -436,6 +469,7 @@
"分组倍率设置": "分组倍率设置",
"分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{\"vip\": 0.5, \"test\": 1},表示 vip 分组的倍率为 0.5test 分组的倍率为 1": "分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{\"vip\": 0.5, \"test\": 1},表示 vip 分组的倍率为 0.5test 分组的倍率为 1",
"分组特殊倍率": "分组特殊倍率",
"分组特殊可用分组": "分组特殊可用分组",
"分组设置": "分组设置",
"分组速率配置优先级高于全局速率限制。": "分组速率配置优先级高于全局速率限制。",
"分组速率限制": "分组速率限制",
@@ -448,6 +482,7 @@
"划转邀请额度": "划转邀请额度",
"划转金额最低为": "划转金额最低为",
"划转额度": "划转额度",
"列出的模型将不会自动添加或移除-thinking/-nothinking 后缀": "列出的模型将不会自动添加或移除-thinking/-nothinking 后缀",
"列设置": "列设置",
"创建令牌默认选择auto分组初始令牌也将设为auto否则留空为用户默认分组": "创建令牌默认选择auto分组初始令牌也将设为auto否则留空为用户默认分组",
"创建失败": "创建失败",
@@ -548,11 +583,13 @@
"启用 Prompt 检查": "启用 Prompt 检查",
"启用2FA失败": "启用2FA失败",
"启用Claude思考适配-thinking后缀": "启用Claude思考适配-thinking后缀",
"启用FunctionCall思维签名填充": "启用FunctionCall思维签名填充",
"启用Gemini思考后缀适配": "启用Gemini思考后缀适配",
"启用Ping间隔": "启用Ping间隔",
"启用SMTP SSL": "启用SMTP SSL",
"启用SSRF防护推荐开启以保护服务器安全": "启用SSRF防护推荐开启以保护服务器安全",
"启用全部": "启用全部",
"启用后将使用 Creem Test Mode": "启用后将使用 Creem Test Mode",
"启用密钥失败": "启用密钥失败",
"启用屏蔽词过滤功能": "启用屏蔽词过滤功能",
"启用所有密钥失败": "启用所有密钥失败",
@@ -561,9 +598,6 @@
"启用绘图功能": "启用绘图功能",
"启用请求体透传功能": "启用请求体透传功能",
"启用请求透传": "启用请求透传",
"禁用思考处理的模型列表": "禁用思考处理的模型列表",
"列出的模型将不会自动添加或移除-thinking/-nothinking 后缀": "列出的模型将不会自动添加或移除-thinking/-nothinking 后缀",
"请输入JSON数组如 [\"model-a\",\"model-b\"]": "请输入JSON数组如 [\"model-a\",\"model-b\"]",
"启用额度消费日志记录": "启用额度消费日志记录",
"启用验证": "启用验证",
"周": "周",
@@ -636,6 +670,7 @@
"多密钥渠道操作项目组": "多密钥渠道操作项目组",
"多密钥管理": "多密钥管理",
"多种充值方式,安全便捷": "多种充值方式,安全便捷",
"大模型接口网关": "大模型接口网关",
"天": "天",
"天前": "天前",
"失败": "失败",
@@ -697,6 +732,7 @@
"密钥输入方式": "密钥输入方式",
"密钥预览": "密钥预览",
"对于官方渠道new-api已经内置地址除非是第三方代理站点或者Azure的特殊接入地址否则不需要填写": "对于官方渠道new-api已经内置地址除非是第三方代理站点或者Azure的特殊接入地址否则不需要填写",
"对免费模型启用预消耗": "对免费模型启用预消耗",
"对域名启用 IP 过滤(实验性)": "对域名启用 IP 过滤(实验性)",
"对外运营模式": "对外运营模式",
"导入": "导入",
@@ -720,6 +756,7 @@
"屏蔽词过滤设置": "屏蔽词过滤设置",
"展开": "展开",
"展开更多": "展开更多",
"展示价格": "展示价格",
"左侧边栏个人设置": "左侧边栏个人设置",
"已为 {{count}} 个模型设置{{type}}_other": "已为 {{count}} 个模型设置{{type}}",
"已为 ${count} 个渠道设置标签!": "已为 ${count} 个渠道设置标签!",
@@ -731,6 +768,7 @@
"已切换至最优倍率视图,每个模型使用其最低倍率分组": "已切换至最优倍率视图,每个模型使用其最低倍率分组",
"已初始化": "已初始化",
"已删除 {{count}} 个令牌!": "已删除 {{count}} 个令牌!",
"已删除 {{count}} 个令牌_other": "已删除 {{count}} 个令牌!",
"已删除 {{count}} 条失效兑换码_other": "已删除 {{count}} 条失效兑换码",
"已删除 ${data} 个通道!": "已删除 ${data} 个通道!",
"已删除所有禁用渠道,共计 ${data} 个": "已删除所有禁用渠道,共计 ${data} 个",
@@ -766,6 +804,7 @@
"已绑定": "已绑定",
"已绑定渠道": "已绑定渠道",
"已耗尽": "已耗尽",
"已解锁豆包自定义 API 地址编辑": "已解锁豆包自定义 API 地址编辑",
"已过期": "已过期",
"已选择 {{count}} 个模型_other": "已选择 {{count}} 个模型",
"已选择 {{selected}} / {{total}}": "已选择 {{selected}} / {{total}}",
@@ -786,6 +825,7 @@
"开启之后会清除用户提示词中的": "开启之后会清除用户提示词中的",
"开启之后将上游地址替换为服务器地址": "开启之后将上游地址替换为服务器地址",
"开启后,仅\"消费\"和\"错误\"日志将记录您的客户端IP地址": "开启后,仅\"消费\"和\"错误\"日志将记录您的客户端IP地址",
"开启后对免费模型倍率为0或者价格为0的模型也会预消耗额度": "开启后对免费模型倍率为0或者价格为0的模型也会预消耗额度",
"开启后将定期发送ping数据保持连接活跃": "开启后将定期发送ping数据保持连接活跃",
"开启后,所有请求将直接透传给上游,不会进行任何处理(重定向和渠道适配也将失效),请谨慎开启": "开启后,所有请求将直接透传给上游,不会进行任何处理(重定向和渠道适配也将失效),请谨慎开启",
"开启后不限制:必须设置模型倍率": "开启后不限制:必须设置模型倍率",
@@ -885,6 +925,7 @@
"按倍率类型筛选": "按倍率类型筛选",
"按倍率设置": "按倍率设置",
"按次计费": "按次计费",
"按照如下格式输入AccessKey|SecretAccessKey|Region": "按照如下格式输入AccessKey|SecretAccessKey|Region",
"按量计费": "按量计费",
"按顺序替换content中的变量占位符": "按顺序替换content中的变量占位符",
"换脸": "换脸",
@@ -904,6 +945,13 @@
"提交结果": "提交结果",
"提升": "提升",
"提示": "提示",
"提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}}": "提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}}",
"视频无法在当前浏览器中播放,这可能是由于:": "视频无法在当前浏览器中播放,这可能是由于:",
"• 视频服务商的跨域限制": "• 视频服务商的跨域限制",
"• 需要特定的请求头或认证": "• 需要特定的请求头或认证",
"• 防盗链保护机制": "• 防盗链保护机制",
"在新标签页中打开": "在新标签页中打开",
"复制链接": "复制链接",
"提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"提示 {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * {{symbol}}{{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}": "提示 {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * {{symbol}}{{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}",
"提示:如需备份数据,只需复制上述目录即可": "提示:如需备份数据,只需复制上述目录即可",
@@ -1012,6 +1060,7 @@
"是否为企业账户": "是否为企业账户",
"是否同时重置对话消息?选择\"是\"将清空所有对话记录并恢复默认示例;选择\"否\"将保留当前对话记录。": "是否同时重置对话消息?选择\"是\"将清空所有对话记录并恢复默认示例;选择\"否\"将保留当前对话记录。",
"是否将该订单标记为成功并为用户入账?": "是否将该订单标记为成功并为用户入账?",
"是否确认充值?": "是否确认充值?",
"是否自动禁用": "是否自动禁用",
"是否要求指纹/面容等生物识别": "是否要求指纹/面容等生物识别",
"显示倍率": "显示倍率",
@@ -1029,6 +1078,7 @@
"智能熔断": "智能熔断",
"智谱": "智谱",
"暂无API信息": "暂无API信息",
"暂无产品配置": "暂无产品配置",
"暂无保存的配置": "暂无保存的配置",
"暂无充值记录": "暂无充值记录",
"暂无公告": "暂无公告",
@@ -1054,6 +1104,7 @@
"更多参数请参考": "更多参数请参考",
"更好的价格,更好的稳定性,只需要将模型基址替换为:": "更好的价格,更好的稳定性,只需要将模型基址替换为:",
"更新": "更新",
"更新 Creem 设置": "更新 Creem 设置",
"更新 Stripe 设置": "更新 Stripe 设置",
"更新SSRF防护设置": "更新SSRF防护设置",
"更新Worker设置": "更新Worker设置",
@@ -1100,6 +1151,7 @@
"未配置的模型列表": "未配置的模型列表",
"本地": "本地",
"本地数据存储": "本地数据存储",
"本地计费": "本地计费",
"本设备:手机指纹/面容外接USB安全密钥": "本设备:手机指纹/面容外接USB安全密钥",
"本设备内置": "本设备内置",
"本项目根据": "本项目根据",
@@ -1109,6 +1161,7 @@
"条 - 第": "条 - 第",
"条,共": "条,共",
"条日志已清理!": "条日志已清理!",
"来自模型重定向,尚未加入模型列表": "来自模型重定向,尚未加入模型列表",
"查看": "查看",
"查看图片": "查看图片",
"查看密钥": "查看密钥",
@@ -1139,6 +1192,7 @@
"模型价格 {{symbol}}{{price}}{{ratioType}} {{ratio}}": "模型价格 {{symbol}}{{price}}{{ratioType}} {{ratio}}",
"模型价格:{{symbol}}{{price}} * {{ratioType}}{{ratio}} = {{symbol}}{{total}}": "模型价格:{{symbol}}{{price}} * {{ratioType}}{{ratio}} = {{symbol}}{{total}}",
"模型倍率": "模型倍率",
"模型倍率 {{modelRatio}}": "模型倍率 {{modelRatio}}",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}": "模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}Web 搜索调用 {{webSearchCallCount}} 次": "模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}Web 搜索调用 {{webSearchCallCount}} 次",
"模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}},图片输入倍率 {{imageRatio}}{{ratioType}} {{ratio}}": "模型倍率 {{modelRatio}},缓存倍率 {{cacheRatio}},输出倍率 {{completionRatio}},图片输入倍率 {{imageRatio}}{{ratioType}} {{ratio}}",
@@ -1161,6 +1215,7 @@
"模型数据分析": "模型数据分析",
"模型映射必须是合法的 JSON 格式!": "模型映射必须是合法的 JSON 格式!",
"模型更新成功!": "模型更新成功!",
"模型未加入列表,可能无法调用": "模型未加入列表,可能无法调用",
"模型消耗分布": "模型消耗分布",
"模型消耗趋势": "模型消耗趋势",
"模型版本": "模型版本",
@@ -1176,15 +1231,18 @@
"模型选择和映射设置": "模型选择和映射设置",
"模型配置": "模型配置",
"模型重定向": "模型重定向",
"模型重定向里的下列模型尚未添加到“模型”列表,调用时会因为缺少可用模型而失败:": "模型重定向里的下列模型尚未添加到“模型”列表,调用时会因为缺少可用模型而失败:",
"模型限制列表": "模型限制列表",
"模板示例": "模板示例",
"模糊搜索模型名称": "模糊搜索模型名称",
"次": "次",
"欢迎使用,请完成以下设置以开始使用系统": "欢迎使用,请完成以下设置以开始使用系统",
"欧元": "欧元",
"正在处理大内容...": "正在处理大内容...",
"正在提交": "正在提交",
"正在构造请求体预览...": "正在构造请求体预览...",
"正在测试第 ${current} - ${end} 个模型 (共 ${total} 个)": "正在测试第 ${current} - ${end} 个模型 (共 ${total} 个)",
"正在跳转 GitHub...": "正在跳转 GitHub...",
"正在跳转...": "正在跳转...",
"此代理仅用于图片请求转发Webhook通知发送等AI API请求仍然由服务器直接发出可在渠道设置中单独配置代理": "此代理仅用于图片请求转发Webhook通知发送等AI API请求仍然由服务器直接发出可在渠道设置中单独配置代理",
"此修改将不可逆": "此修改将不可逆",
@@ -1236,6 +1294,7 @@
"测试失败": "测试失败",
"测试所有渠道的最长响应时间": "测试所有渠道的最长响应时间",
"测试所有通道": "测试所有通道",
"测试模式": "测试模式",
"测速": "测速",
"消息优先级": "消息优先级",
"消息优先级范围0-10默认为5": "消息优先级范围0-10默认为5",
@@ -1251,10 +1310,12 @@
"深色模式": "深色模式",
"添加": "添加",
"添加API": "添加API",
"添加产品": "添加产品",
"添加令牌": "添加令牌",
"添加兑换码": "添加兑换码",
"添加公告": "添加公告",
"添加分类": "添加分类",
"添加后提交": "添加后提交",
"添加成功": "添加成功",
"添加模型": "添加模型",
"添加模型区域": "添加模型区域",
@@ -1312,9 +1373,11 @@
"生成音乐": "生成音乐",
"用于API调用的身份验证令牌请妥善保管": "用于API调用的身份验证令牌请妥善保管",
"用于配置网络代理,支持 socks5 协议": "用于配置网络代理,支持 socks5 协议",
"用于验证回调 new-api 的 webhook 请求的密钥,敏感信息不显示": "用于验证回调 new-api 的 webhook 请求的密钥,敏感信息不显示",
"用以支持基于 WebAuthn 的无密码登录注册": "用以支持基于 WebAuthn 的无密码登录注册",
"用以支持用户校验": "用以支持用户校验",
"用以支持系统的邮件发送": "用以支持系统的邮件发送",
"用以支持通过 Discord 进行登录注册": "用以支持通过 Discord 进行登录注册",
"用以支持通过 GitHub 进行登录注册": "用以支持通过 GitHub 进行登录注册",
"用以支持通过 Linux DO 进行登录注册": "用以支持通过 Linux DO 进行登录注册",
"用以支持通过 OIDC 登录,例如 Okta、Auth0 等兼容 OIDC 协议的 IdP": "用以支持通过 OIDC 登录,例如 Okta、Auth0 等兼容 OIDC 协议的 IdP",
@@ -1359,6 +1422,7 @@
"的前提下使用。": "的前提下使用。",
"监控设置": "监控设置",
"目标用户:{{username}}": "目标用户:{{username}}",
"直接提交": "直接提交",
"相关项目": "相关项目",
"相当于删除用户,此修改将不可逆": "相当于删除用户,此修改将不可逆",
"矛盾": "矛盾",
@@ -1379,6 +1443,7 @@
"确定清除所有失效兑换码?": "确定清除所有失效兑换码?",
"确定要修改所有子渠道优先级为 ": "确定要修改所有子渠道优先级为 ",
"确定要修改所有子渠道权重为 ": "确定要修改所有子渠道权重为 ",
"确定要充值 $": "确定要充值 $",
"确定要删除供应商 \"{{name}}\" 吗?此操作不可撤销。": "确定要删除供应商 \"{{name}}\" 吗?此操作不可撤销。",
"确定要删除所有已自动禁用的密钥吗?": "确定要删除所有已自动禁用的密钥吗?",
"确定要删除所选的 {{count}} 个令牌吗_other": "确定要删除所选的 {{count}} 个令牌吗?",
@@ -1426,6 +1491,7 @@
"禁用原因": "禁用原因",
"禁用后的影响:": "禁用后的影响:",
"禁用密钥失败": "禁用密钥失败",
"禁用思考处理的模型列表": "禁用思考处理的模型列表",
"禁用所有密钥失败": "禁用所有密钥失败",
"禁用时间": "禁用时间",
"私有IP访问详细说明": "⚠️ 安全警告:启用此选项将允许访问内网资源(本地主机、私有网络)。仅在需要访问内部服务且了解安全风险的情况下启用。",
@@ -1450,6 +1516,7 @@
"管理员": "管理员",
"管理员区域": "管理员区域",
"管理员暂时未设置任何关于内容": "管理员暂时未设置任何关于内容",
"管理员未开启 Creem 充值!": "管理员未开启 Creem 充值!",
"管理员未开启Stripe充值": "管理员未开启Stripe充值",
"管理员未开启在线充值!": "管理员未开启在线充值!",
"管理员未开启在线充值功能,请联系管理员开启或使用兑换码充值。": "管理员未开启在线充值功能,请联系管理员开启或使用兑换码充值。",
@@ -1502,24 +1569,33 @@
"绘图任务记录": "绘图任务记录",
"绘图日志": "绘图日志",
"绘图设置": "绘图设置",
"统一的": "统一的",
"统计Tokens": "统计Tokens",
"统计次数": "统计次数",
"统计额度": "统计额度",
"继续": "继续",
"缓存 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "缓存 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})",
"缓存 Tokens": "缓存 Tokens",
"缓存: {{cacheRatio}}": "缓存: {{cacheRatio}}",
"缓存价格:{{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})": "缓存价格:{{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})",
"缓存价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})": "缓存价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})",
"缓存倍率": "缓存倍率",
"缓存倍率 {{cacheRatio}}": "缓存倍率 {{cacheRatio}}",
"缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})": "缓存创建 {{tokens}} tokens / 1M tokens * {{symbol}}{{price}} (倍率: {{ratio}})",
"缓存创建 Tokens": "缓存创建 Tokens",
"缓存创建: {{cacheCreationRatio}}": "缓存创建: {{cacheCreationRatio}}",
"缓存创建: 5m {{cacheCreationRatio5m}}": "缓存创建: 5m {{cacheCreationRatio5m}}",
"缓存创建: 1h {{cacheCreationRatio1h}}": "缓存创建: 1h {{cacheCreationRatio1h}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}}": "缓存创建倍率 5m {{cacheCreationRatio5m}}",
"缓存创建倍率 1h {{cacheCreationRatio1h}}": "缓存创建倍率 1h {{cacheCreationRatio1h}}",
"缓存创建: 5m {{cacheCreationRatio5m}}": "缓存创建: 5m {{cacheCreationRatio5m}}",
"缓存创建: 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}": "缓存创建: 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}",
"缓存创建价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})": "缓存创建价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})",
"缓存创建价格合计5m {{symbol}}{{five}} + 1h {{symbol}}{{one}} = {{symbol}}{{total}} / 1M tokens": "缓存创建价格合计5m {{symbol}}{{five}} + 1h {{symbol}}{{one}} = {{symbol}}{{total}} / 1M tokens",
"缓存创建倍率 {{cacheCreationRatio}}": "缓存创建倍率 {{cacheCreationRatio}}",
"缓存创建倍率 1h {{cacheCreationRatio1h}}": "缓存创建倍率 1h {{cacheCreationRatio1h}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}}": "缓存创建倍率 5m {{cacheCreationRatio5m}}",
"缓存创建倍率 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}": "缓存创建倍率 5m {{cacheCreationRatio5m}} / 1h {{cacheCreationRatio1h}}",
"编辑": "编辑",
"编辑API": "编辑API",
"编辑产品": "编辑产品",
"编辑供应商": "编辑供应商",
"编辑公告": "编辑公告",
"编辑公告内容": "编辑公告内容",
@@ -1537,6 +1613,7 @@
"网站域名标识": "网站域名标识",
"网络错误": "网络错误",
"置信度": "置信度",
"美元": "美元",
"聊天": "聊天",
"聊天会话管理": "聊天会话管理",
"聊天区域": "聊天区域",
@@ -1583,6 +1660,7 @@
"获取金额失败": "获取金额失败",
"获取验证码": "获取验证码",
"补全": "补全",
"补全 {{completion}} tokens / 1M tokens * {{symbol}}{{price}}": "补全 {{completion}} tokens / 1M tokens * {{symbol}}{{price}}",
"补全价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "补全价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})",
"补全价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens": "补全价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens",
"补全倍率": "补全倍率",
@@ -1599,6 +1677,7 @@
"解析密钥文件失败: {{msg}}": "解析密钥文件失败: {{msg}}",
"解绑 Passkey": "解绑 Passkey",
"解绑后将无法使用 Passkey 登录,确定要继续吗?": "解绑后将无法使用 Passkey 登录,确定要继续吗?",
"计费模式": "计费模式",
"计费类型": "计费类型",
"计费过程": "计费过程",
"订单号": "订单号",
@@ -1662,6 +1741,7 @@
"请前往个人设置 → 安全设置进行配置。": "请前往个人设置 → 安全设置进行配置。",
"请勿过度信任此功能IP可能被伪造": "请勿过度信任此功能IP可能被伪造",
"请在系统设置页面编辑分组倍率以添加新的分组:": "请在系统设置页面编辑分组倍率以添加新的分组:",
"请填写完整的产品信息": "请填写完整的产品信息",
"请填写完整的管理员账号信息": "请填写完整的管理员账号信息",
"请填写密钥": "请填写密钥",
"请填写渠道名称和渠道密钥!": "请填写渠道名称和渠道密钥!",
@@ -1676,10 +1756,11 @@
"请求失败": "请求失败",
"请求头覆盖": "请求头覆盖",
"请求并计费模型": "请求并计费模型",
"请求路径": "请求路径",
"请求时长: ${time}s": "请求时长: ${time}s",
"请求次数": "请求次数",
"请求结束后多退少补": "请求结束后多退少补",
"请求超时,请刷新页面后重新发起 GitHub 登录": "请求超时,请刷新页面后重新发起 GitHub 登录",
"请求路径": "请求路径",
"请求预扣费额度": "请求预扣费额度",
"请点击我": "请点击我",
"请确认以下设置信息,点击\"初始化系统\"开始配置": "请确认以下设置信息,点击\"初始化系统\"开始配置",
@@ -1696,6 +1777,8 @@
"请至少选择一个模型": "请至少选择一个模型",
"请至少选择一个模型!": "请至少选择一个模型!",
"请至少选择一个渠道": "请至少选择一个渠道",
"请输入 API Key一行一个格式APIKey|Region": "请输入 API Key一行一个格式APIKey|Region",
"请输入 API Key格式APIKey|Region": "请输入 API Key格式APIKey|Region",
"请输入 AZURE_OPENAI_ENDPOINT例如https://docs-test-001.openai.azure.com": "请输入 AZURE_OPENAI_ENDPOINT例如https://docs-test-001.openai.azure.com",
"请输入 JSON 格式的密钥内容,例如:\n{\n \"type\": \"service_account\",\n \"project_id\": \"your-project-id\",\n \"private_key_id\": \"...\",\n \"private_key\": \"...\",\n \"client_email\": \"...\",\n \"client_id\": \"...\",\n \"auth_uri\": \"...\",\n \"token_uri\": \"...\",\n \"auth_provider_x509_cert_url\": \"...\",\n \"client_x509_cert_url\": \"...\"\n}": "请输入 JSON 格式的密钥内容,例如:\n{\n \"type\": \"service_account\",\n \"project_id\": \"your-project-id\",\n \"private_key_id\": \"...\",\n \"private_key\": \"...\",\n \"client_email\": \"...\",\n \"client_id\": \"...\",\n \"auth_uri\": \"...\",\n \"token_uri\": \"...\",\n \"auth_provider_x509_cert_url\": \"...\",\n \"client_x509_cert_url\": \"...\"\n}",
"请输入 OIDC 的 Well-Known URL": "请输入 OIDC 的 Well-Known URL",
@@ -1707,6 +1790,7 @@
"请输入Gotify应用令牌": "请输入Gotify应用令牌",
"请输入Gotify服务器地址": "请输入Gotify服务器地址",
"请输入Gotify服务器地址例如: https://gotify.example.com": "请输入Gotify服务器地址例如: https://gotify.example.com",
"请输入JSON数组如 [\"model-a\",\"model-b\"]": "请输入JSON数组如 [\"model-a\",\"model-b\"]",
"请输入Uptime Kuma地址": "请输入Uptime Kuma地址",
"请输入Uptime Kuma服务地址https://status.example.com": "请输入Uptime Kuma服务地址https://status.example.com",
"请输入URL链接": "请输入URL链接",
@@ -1737,6 +1821,7 @@
"请输入密码": "请输入密码",
"请输入密钥": "请输入密钥",
"请输入密钥,一行一个": "请输入密钥,一行一个",
"请输入密钥一行一个格式AccessKey|SecretAccessKey|Region": "请输入密钥一行一个格式AccessKey|SecretAccessKey|Region",
"请输入密钥!": "请输入密钥!",
"请输入您的密码": "请输入您的密码",
"请输入您的用户名以确认删除": "请输入您的用户名以确认删除",
@@ -1791,6 +1876,7 @@
"请输入验证码或备用码": "请输入验证码或备用码",
"请输入默认 API 版本例如2025-04-01-preview": "请输入默认 API 版本例如2025-04-01-preview",
"请选择API地址": "请选择API地址",
"请选择产品": "请选择产品",
"请选择你的复制方式": "请选择你的复制方式",
"请选择使用模式": "请选择使用模式",
"请选择分组": "请选择分组",
@@ -1831,6 +1917,7 @@
"账户绑定": "账户绑定",
"账户绑定、安全设置和身份验证": "账户绑定、安全设置和身份验证",
"账户统计": "账户统计",
"货币": "货币",
"货币单位": "货币单位",
"购买兑换码": "购买兑换码",
"资源消耗": "资源消耗",
@@ -1875,12 +1962,14 @@
"输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}": "输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}",
"输出价格": "输出价格",
"输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})",
"输出倍率 {{completionRatio}}": "输出倍率 {{completionRatio}}",
"边栏设置": "边栏设置",
"过期时间": "过期时间",
"过期时间不能早于当前时间!": "过期时间不能早于当前时间!",
"过期时间快捷设置": "过期时间快捷设置",
"过期时间格式错误!": "过期时间格式错误!",
"运营设置": "运营设置",
"返回修改": "返回修改",
"返回登录": "返回登录",
"这是重复键中的最后一个,其值将被使用": "这是重复键中的最后一个,其值将被使用",
"进度": "进度",
@@ -1958,6 +2047,7 @@
"部分渠道测试失败:": "部分渠道测试失败:",
"部署地区": "部署地区",
"配置": "配置",
"配置 Discord OAuth": "配置 Discord OAuth",
"配置 GitHub OAuth App": "配置 GitHub OAuth App",
"配置 Linux DO OAuth": "配置 Linux DO OAuth",
"配置 OIDC": "配置 OIDC",
@@ -1999,6 +2089,7 @@
"错误": "错误",
"键为分组名称,值为另一个 JSON 对象,键为分组名称,值为该分组的用户的特殊分组倍率,例如:{\"vip\": {\"default\": 0.5, \"test\": 1}},表示 vip 分组的用户在使用default分组的令牌时倍率为0.5使用test分组时倍率为1": "键为分组名称,值为另一个 JSON 对象,键为分组名称,值为该分组的用户的特殊分组倍率,例如:{\"vip\": {\"default\": 0.5, \"test\": 1}},表示 vip 分组的用户在使用default分组的令牌时倍率为0.5使用test分组时倍率为1",
"键为原状态码,值为要复写的状态码,仅影响本地判断": "键为原状态码,值为要复写的状态码,仅影响本地判断",
"键为用户分组名称,值为操作映射对象。内层键以\"+:\"开头表示添加指定分组(键值为分组名称,值为描述),以\"-:\"开头表示移除指定分组(键值为分组名称),不带前缀的键直接添加该分组。例如:{\"vip\": {\"+:premium\": \"高级分组\", \"special\": \"特殊分组\", \"-:default\": \"默认分组\"}},表示 vip 分组的用户可以使用 premium 和 special 分组,同时移除 default 分组的访问权限": "键为用户分组名称,值为操作映射对象。内层键以\"+:\"开头表示添加指定分组(键值为分组名称,值为描述),以\"-:\"开头表示移除指定分组(键值为分组名称),不带前缀的键直接添加该分组。例如:{\"vip\": {\"+:premium\": \"高级分组\", \"special\": \"特殊分组\", \"-:default\": \"默认分组\"}},表示 vip 分组的用户可以使用 premium 和 special 分组,同时移除 default 分组的访问权限",
"键为端点类型,值为路径和方法对象": "键为端点类型,值为路径和方法对象",
"键为请求中的模型名称,值为要替换的模型名称": "键为请求中的模型名称,值为要替换的模型名称",
"键名": "键名",
@@ -2072,10 +2163,45 @@
"默认区域,如: us-central1": "默认区域,如: us-central1",
"默认折叠侧边栏": "默认折叠侧边栏",
"默认测试模型": "默认测试模型",
"默认补全倍率": "默认补全倍率",
"Creem 介绍": "Creem 是一个简单的支付处理平台,支持固定金额产品销售,以及订阅销售。",
"Creem Setting Tips": "Creem 只支持预设的固定金额产品这产品以及价格需要提前在Creem网站内创建配置所以不支持自定义动态金额充值。在Creem端配置产品的名字以及价格获取Product Id 后填到下面的产品在new-api为该产品设置充值额度以及展示价格。",
"正在跳转 GitHub...": "正在跳转 GitHub...",
"请求超时,请刷新页面后重新发起 GitHub 登录": "请求超时,请刷新页面后重新发起 GitHub 登录"
"请先在设置中启用图片功能": "请先在设置中启用图片功能",
"图片已添加": "图片已添加",
"无法添加图片": "无法添加图片",
"粘贴图片失败": "粘贴图片失败",
"支持 Ctrl+V 粘贴图片": "支持 Ctrl+V 粘贴图片",
"已复制全部数据": "已复制全部数据",
"流式响应完成": "流式响应完成",
"图片地址": "图片地址",
"已在自定义模式中忽略": "已在自定义模式中忽略",
"停用": "停用",
"图片功能在自定义请求体模式下不可用": "图片功能在自定义请求体模式下不可用",
"启用后可添加图片URL进行多模态对话": "启用后可添加图片URL进行多模态对话",
"点击 + 按钮添加图片URL进行多模态对话": "点击 + 按钮添加图片URL进行多模态对话",
"已添加": "已添加",
"张图片": "张图片",
"自定义模式下不可用": "自定义模式下不可用",
"控制输出的随机性和创造性": "控制输出的随机性和创造性",
"核采样,控制词汇选择的多样性": "核采样,控制词汇选择的多样性",
"频率惩罚,减少重复词汇的出现": "频率惩罚,减少重复词汇的出现",
"存在惩罚,鼓励讨论新话题": "存在惩罚,鼓励讨论新话题",
"流式输出": "流式输出",
"暂无SSE响应数据": "暂无SSE响应数据",
"SSE数据流": "SSE数据流",
"解析错误": "解析错误",
"有 Reasoning": "有 Reasoning",
"全部收起": "全部收起",
"全部展开": "全部展开",
"SSE 事件": "SSE 事件",
"JSON格式错误": "JSON格式错误",
"自定义请求体模式": "自定义请求体模式",
"启用此模式后将使用您自定义的请求体发送API请求模型配置面板的参数设置将被忽略。": "启用此模式后将使用您自定义的请求体发送API请求模型配置面板的参数设置将被忽略。",
"请求体 JSON": "请求体 JSON",
"格式正确": "格式正确",
"格式错误": "格式错误",
"格式化": "格式化",
"请输入有效的JSON格式的请求体。您可以参考预览面板中的默认请求体格式。": "请输入有效的JSON格式的请求体。您可以参考预览面板中的默认请求体格式。",
"默认用户消息": "你好",
"默认助手消息": "你好!有什么我可以帮助你的吗?",
"可选,用于复现结果": "可选,用于复现结果",
"随机种子 (留空为随机)": "随机种子 (留空为随机)"
}
}
}

View File

@@ -59,6 +59,7 @@ import {
} from '../../components/playground/OptimizedComponents';
import ChatArea from '../../components/playground/ChatArea';
import FloatingButtons from '../../components/playground/FloatingButtons';
import { PlaygroundProvider } from '../../contexts/PlaygroundContext';
// 生成头像
const generateAvatarDataUrl = (username) => {
@@ -436,8 +437,26 @@ const Playground = () => {
setTimeout(() => saveMessagesImmediately([]), 0);
}, [setMessage, saveMessagesImmediately]);
// 处理粘贴图片
const handlePasteImage = useCallback((base64Data) => {
if (!inputs.imageEnabled) {
return;
}
// 添加图片到 imageUrls 数组
const newUrls = [...(inputs.imageUrls || []), base64Data];
handleInputChange('imageUrls', newUrls);
}, [inputs.imageEnabled, inputs.imageUrls, handleInputChange]);
// Playground Context 值
const playgroundContextValue = {
onPasteImage: handlePasteImage,
imageUrls: inputs.imageUrls || [],
imageEnabled: inputs.imageEnabled || false,
};
return (
<div className='h-full'>
<PlaygroundProvider value={playgroundContextValue}>
<div className='h-full'>
<Layout className='h-full bg-transparent flex flex-col md:flex-row'>
{(showSettings || !isMobile) && (
<Layout.Sider
@@ -536,6 +555,7 @@ const Playground = () => {
</Layout.Content>
</Layout>
</div>
</PlaygroundProvider>
);
};