feat: 算力引擎 Go 后端核心(new-api)

- 统一 OpenAI 兼容 /v1 中继 + 渠道/额度/令牌/流水
- 各领域包:relay 模型网关、model 数据层、controller 管理 API
This commit is contained in:
2026-08-23 22:38:46 +08:00
commit 28e53d90fc
836 changed files with 165403 additions and 0 deletions
@@ -0,0 +1,9 @@
package claude
func NormalizeCacheCreationSplit(totalTokens int, tokens5m int, tokens1h int) (int, int) {
remainder := totalTokens - tokens5m - tokens1h
if remainder < 0 {
remainder = 0
}
return tokens5m + remainder, tokens1h
}
@@ -0,0 +1,10 @@
package claude
import "errors"
// ErrMissingMaxTokens is returned when an OpenAI-format request carries no
// usable max_tokens and no Options.Claude.DefaultMaxTokens hook is
// configured. The Claude Messages API rejects requests without max_tokens
// (400 "max_tokens: Field required"), so conversion fails loudly instead of
// emitting a request the upstream is guaranteed to refuse.
var ErrMissingMaxTokens = errors.New("claude messages request requires max_tokens: set max_tokens on the request or configure Options.Claude.DefaultMaxTokens")
@@ -0,0 +1,16 @@
package claude
func FunctionParametersToInputSchema(parameters any) map[string]any {
params, _ := parameters.(map[string]any)
schema := make(map[string]any, len(params)+2)
for key, value := range params {
schema[key] = value
}
if schema["type"] == nil {
schema["type"] = "object"
}
if schema["properties"] == nil {
schema["properties"] = map[string]any{}
}
return schema
}
@@ -0,0 +1,46 @@
package claude
import "github.com/QuantumNous/new-api/relaykit/dto"
func MapOpenAIToolChoice(toolChoice any, parallelToolCalls *bool) *dto.ClaudeToolChoice {
var claudeToolChoice *dto.ClaudeToolChoice
if toolChoiceStr, ok := toolChoice.(string); ok {
switch toolChoiceStr {
case "auto":
claudeToolChoice = &dto.ClaudeToolChoice{
Type: "auto",
}
case "required":
claudeToolChoice = &dto.ClaudeToolChoice{
Type: "any",
}
case "none":
claudeToolChoice = &dto.ClaudeToolChoice{
Type: "none",
}
}
} else if toolChoiceMap, ok := toolChoice.(map[string]interface{}); ok {
if function, ok := toolChoiceMap["function"].(map[string]interface{}); ok {
if toolName, ok := function["name"].(string); ok {
claudeToolChoice = &dto.ClaudeToolChoice{
Type: "tool",
Name: toolName,
}
}
}
}
if parallelToolCalls != nil {
if claudeToolChoice == nil {
claudeToolChoice = &dto.ClaudeToolChoice{
Type: "auto",
}
}
if claudeToolChoice.Type != "none" {
claudeToolChoice.DisableParallelToolUse = !*parallelToolCalls
}
}
return claudeToolChoice
}