Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7124bf6
docs: design cost-optimized model routing
Allenllii Aug 17, 2026
792364d
docs: plan cost routing core implementation
Allenllii Aug 17, 2026
ce7fd7d
chore: ignore local worktrees
Allenllii Aug 17, 2026
9e84d63
docs: design cost optimized intelligent routing
Allenllii Aug 17, 2026
7a20d6c
docs: plan intelligent routing shadow core
Allenllii Aug 17, 2026
9f23fb6
test: isolate channel affinity cache stats
Allenllii Aug 17, 2026
9f0ed11
feat: add intelligent routing configuration
Allenllii Aug 17, 2026
4399bc9
feat: extract intelligent routing features
Allenllii Aug 17, 2026
ad782c1
feat: build intelligent routing candidate catalog
Allenllii Aug 17, 2026
5ffa233
feat: plan constrained low cost routes
Allenllii Aug 17, 2026
e82d28b
feat: add shadow intelligent route planning
Allenllii Aug 17, 2026
f0c6add
feat: audit shadow routing decisions
Allenllii Aug 17, 2026
87e2720
docs: add intelligent routing shadow rollout
Allenllii Aug 17, 2026
087d0a1
test: stabilize HTTP2 retry fixtures on Windows
Allenllii Aug 17, 2026
b9a215b
feat: execute live cost optimized routes
Allenllii Aug 17, 2026
d8d4fb0
feat: add routing health circuit breaker
Allenllii Aug 17, 2026
084054e
feat: complete bounded intelligent route execution
Allenllii Aug 17, 2026
0a3167a
docs: document live intelligent routing operations
Allenllii Aug 17, 2026
0acd5eb
fix: bind subscription billing to execution model
Allenllii Aug 17, 2026
6ed21e8
fix: enforce routing quality and fallback invariants
Allenllii Aug 17, 2026
f097923
docs: design multi-instance routing admin backend
Allenllii Aug 20, 2026
faab9bc
docs: plan intelligent routing policy control
Allenllii Aug 20, 2026
7df1d75
feat: persist intelligent routing policies
Allenllii Aug 20, 2026
3ad0676
feat: validate intelligent routing policies
Allenllii Aug 20, 2026
f900f7a
feat: control intelligent routing policy lifecycle
Allenllii Aug 20, 2026
548dd8b
feat: resolve intelligent routing rollouts
Allenllii Aug 20, 2026
7a94c10
feat: expose intelligent routing policy admin api
Allenllii Aug 20, 2026
8839f1e
feat: apply scoped intelligent routing rollouts
Allenllii Aug 20, 2026
a725709
feat: refresh intelligent routing policy snapshots
Allenllii Aug 20, 2026
1a59941
test: verify intelligent routing policy control
Allenllii Aug 20, 2026
d1cd6fe
docs: plan intelligent routing shared runtime
Allenllii Aug 20, 2026
2b85dbb
feat: gate shared intelligent routing runtime
Allenllii Aug 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,5 @@ LINUX_DO_USER_ENDPOINT=https://connect.linux.do/api/user
# 用于验证支付成功/取消回调URL的域名安全性
# 示例: example.com,myapp.io 将允许 example.com, sub.example.com, myapp.io 等
# TRUSTED_REDIRECT_DOMAINS=example.com,myapp.io
# Intelligent routing is configured through versioned system options under
# intelligent_routing_setting.* and starts disabled in shadow-only mode.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ electron/dist
token_estimator_test.go
skills-lock.json
.playwright-mcp
.worktrees/

# Local-only live probes and scratch test workspaces.
.local-tests/
Expand Down
31 changes: 18 additions & 13 deletions controller/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,24 @@ import (
// action 的 params 填充。本地化展示文案在前端 i18n 模板中维护,本表是语言中立的
// 英文基线——调用方因此无需在每个埋点处手写句子(避免与 params 重复书写同一份值)。
var auditContentTemplates = map[string]string{
"user.create": "Created user ${username} (role ${role})",
"user.update": "Updated user ${username} (ID: ${id})",
"user.delete": "Deleted user ${username} (ID: ${id})",
"user.manage": "Performed ${action} on user ${username} (ID: ${id})",
"user.quota_add": "Increased user quota by ${quota}",
"user.quota_subtract": "Decreased user quota by ${quota}",
"user.quota_override": "Overrode user quota from ${from} to ${to}",
"user.binding_clear": "Cleared ${bindingType} binding for user ${username}",
"user.2fa_disable": "Force-disabled two-factor authentication for the user",
"user.passkey_register": "Registered a passkey",
"user.passkey_delete": "Deleted a passkey",
"user.reset_passkey": "Reset the user passkey",
"option.update": "Updated system setting ${key}",
"user.create": "Created user ${username} (role ${role})",
"user.update": "Updated user ${username} (ID: ${id})",
"user.delete": "Deleted user ${username} (ID: ${id})",
"user.manage": "Performed ${action} on user ${username} (ID: ${id})",
"user.quota_add": "Increased user quota by ${quota}",
"user.quota_subtract": "Decreased user quota by ${quota}",
"user.quota_override": "Overrode user quota from ${from} to ${to}",
"user.binding_clear": "Cleared ${bindingType} binding for user ${username}",
"user.2fa_disable": "Force-disabled two-factor authentication for the user",
"user.passkey_register": "Registered a passkey",
"user.passkey_delete": "Deleted a passkey",
"user.reset_passkey": "Reset the user passkey",
"option.update": "Updated system setting ${key}",
"intelligent_routing.policy.create": "Created intelligent routing policy ${id}",
"intelligent_routing.policy.update": "Updated intelligent routing policy ${id}",
"intelligent_routing.policy.publish": "Published intelligent routing policy ${version}",
"intelligent_routing.policy.rollback": "Rolled back intelligent routing policy to ${source_version} as ${version}",
"intelligent_routing.rollout.update": "Updated intelligent routing rollout revision ${revision}",

"channel.create": "Created channel ${name} (type ${type}, count ${count})",
"channel.update": "Updated channel ${name} (ID: ${id})",
Expand Down
207 changes: 207 additions & 0 deletions controller/intelligent_routing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
package controller

import (
"errors"
"net/http"
"strconv"

"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/model"
intelligentrouting "github.com/QuantumNous/new-api/service/intelligent_routing"
"github.com/gin-gonic/gin"
)

func ListIntelligentRoutingPolicies(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
if page < 1 {
page = 1
}
if pageSize < 1 {
pageSize = 20
}
if pageSize > 100 {
pageSize = 100
}
policies, total, err := model.ListIntelligentRoutingPolicies((page-1)*pageSize, pageSize)
if err != nil {
intelligentRoutingError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": policies, "total": total, "page": page, "page_size": pageSize})
}

func GetIntelligentRoutingPolicy(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil || id < 1 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid policy id"})
return
}
policy, err := model.GetIntelligentRoutingPolicy(id)
if err != nil {
intelligentRoutingError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": policy})
}

func CreateIntelligentRoutingPolicy(c *gin.Context) {
var request dto.IntelligentRoutingDraftRequest
if err := common.DecodeJson(c.Request.Body, &request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid request"})
return
}
policy, issues, err := intelligentrouting.DefaultPolicyControl.CreateDraft(c, request.Config, c.GetInt("id"))
if err != nil {
intelligentRoutingError(c, err)
return
}
if len(issues) > 0 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "issues": issues})
return
}
recordManageAudit(c, "intelligent_routing.policy.create", map[string]interface{}{"id": policy.Id})
c.JSON(http.StatusCreated, gin.H{"success": true, "data": policy})
}

func UpdateIntelligentRoutingPolicy(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil || id < 1 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid policy id"})
return
}
var request dto.IntelligentRoutingDraftUpdateRequest
if err := common.DecodeJson(c.Request.Body, &request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid request"})
return
}
policy, issues, err := intelligentrouting.DefaultPolicyControl.UpdateDraft(c, id, request.UpdatedAt, request.Config)
if err != nil {
intelligentRoutingError(c, err)
return
}
if len(issues) > 0 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "issues": issues})
return
}
recordManageAudit(c, "intelligent_routing.policy.update", map[string]interface{}{"id": policy.Id})
c.JSON(http.StatusOK, gin.H{"success": true, "data": policy})
}

func ValidateIntelligentRoutingPolicy(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil || id < 1 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid policy id"})
return
}
policy, err := model.GetIntelligentRoutingPolicy(id)
if err != nil {
intelligentRoutingError(c, err)
return
}
validated, issues := intelligentrouting.ValidatePolicyDocument(policy.Config)
c.JSON(http.StatusOK, gin.H{"success": len(issues) == 0, "data": gin.H{"checksum": validated.Checksum, "issues": issues}})
}

func PublishIntelligentRoutingPolicy(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil || id < 1 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid policy id"})
return
}
var request dto.IntelligentRoutingPublishRequest
if err := common.DecodeJson(c.Request.Body, &request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid request"})
return
}
policy, issues, err := intelligentrouting.DefaultPolicyControl.Publish(c, id, c.GetInt("id"), request.ChangeNote)
if err != nil {
intelligentRoutingError(c, err)
return
}
if len(issues) > 0 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "issues": issues})
return
}
recordManageAudit(c, "intelligent_routing.policy.publish", map[string]interface{}{"id": policy.Id, "version": policy.Version})
c.JSON(http.StatusOK, gin.H{"success": true, "data": policy})
}

func RollbackIntelligentRoutingPolicy(c *gin.Context) {
version, err := strconv.Atoi(c.Param("version"))
if err != nil || version < 1 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid policy version"})
return
}
var request dto.IntelligentRoutingPublishRequest
if err := common.DecodeJson(c.Request.Body, &request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid request"})
return
}
policy, issues, err := intelligentrouting.DefaultPolicyControl.Rollback(c, version, c.GetInt("id"), request.ChangeNote)
if err != nil {
intelligentRoutingError(c, err)
return
}
if len(issues) > 0 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "issues": issues})
return
}
recordManageAudit(c, "intelligent_routing.policy.rollback", map[string]interface{}{"source_version": version, "version": policy.Version})
c.JSON(http.StatusOK, gin.H{"success": true, "data": policy})
}

func GetIntelligentRoutingRollout(c *gin.Context) {
rollout, err := model.GetIntelligentRoutingRollout()
if err != nil {
intelligentRoutingError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": rollout})
}

func UpdateIntelligentRoutingRollout(c *gin.Context) {
var request dto.IntelligentRoutingRolloutUpdateRequest
if err := common.DecodeJson(c.Request.Body, &request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid request"})
return
}
userGroups, err := common.Marshal(request.UserGroups)
if err != nil {
intelligentRoutingError(c, err)
return
}
tokenGroups, err := common.Marshal(request.TokenGroups)
if err != nil {
intelligentRoutingError(c, err)
return
}
rollout, issues, err := intelligentrouting.DefaultPolicyControl.UpdateRollout(c, request.Revision, model.IntelligentRoutingRollout{
PolicyVersion: request.PolicyVersion, Enabled: request.Enabled, Mode: request.Mode, TrafficPercent: request.TrafficPercent,
UserGroups: string(userGroups), TokenGroups: string(tokenGroups), UpdatedBy: c.GetInt("id"),
})
if err != nil {
intelligentRoutingError(c, err)
return
}
if len(issues) > 0 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "issues": issues})
return
}
recordManageAudit(c, "intelligent_routing.rollout.update", map[string]interface{}{"revision": rollout.Revision, "policy_version": rollout.PolicyVersion, "mode": rollout.Mode, "traffic_percent": rollout.TrafficPercent})
c.JSON(http.StatusOK, gin.H{"success": true, "data": rollout})
}

func intelligentRoutingError(c *gin.Context, err error) {
switch {
case errors.Is(err, model.ErrIntelligentRoutingPolicyNotFound), errors.Is(err, model.ErrIntelligentRoutingRolloutNotFound):
c.JSON(http.StatusNotFound, gin.H{"success": false, "message": "resource not found"})
case errors.Is(err, model.ErrIntelligentRoutingRevisionConflict):
c.JSON(http.StatusConflict, gin.H{"success": false, "message": "revision conflict"})
case errors.Is(err, model.ErrIntelligentRoutingPolicyImmutable):
c.JSON(http.StatusConflict, gin.H{"success": false, "message": "published policy is immutable"})
default:
c.JSON(http.StatusServiceUnavailable, gin.H{"success": false, "message": "intelligent routing service unavailable"})
}
}
Loading