Skip to content

Commit 6c7722a

Browse files
committed
升级托管后端内核到 CLIProxyAPI v7.0.3
- 将 resources/backend/source 同步到 CLIProxyAPI v7.0.3 /v7,合入 Home、Redis、协议复用与响应翻译更新。 - 迁移并保留 CodexCliPlus 的 GPT-only 路由、Secret Broker、prompt_cache_retention、用量日志、管理 API、原子写入和镜像存储改装。 - 更新 Go 依赖覆盖、示例配置、backend/windows fallback 资源与 source/windows manifest,继续以 ccp-core.exe 作为托管可执行文件。 - 更新 .NET 后端发布元数据、构建日期、包内可执行文件 SHA 和 BuildTool 资产流程断言。 - 补充和更新 Go 与 .NET 测试断言以覆盖 v7 module path、Home 请求日志、禁用文件存储、WebSocket 复用和版本解析。
1 parent c1588af commit 6c7722a

353 files changed

Lines changed: 4682 additions & 1308 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

resources/backend/backend-source-manifest.json

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,69 @@
11
{
22
"component": "CLIProxyAPI",
33
"sourceUrl": "https://github.com/router-for-me/CLIProxyAPI",
4-
"version": "6.10.9",
5-
"releaseTag": "v6.10.9",
6-
"sourceCommit": "785b00c3127eea6aa207f1207ead8a2aa93690a3",
4+
"version": "7.0.3",
5+
"releaseTag": "v7.0.3",
6+
"releaseUrl": "https://github.com/router-for-me/CLIProxyAPI/releases/tag/v7.0.3",
7+
"archiveUrl": "https://github.com/router-for-me/CLIProxyAPI/releases/download/v7.0.3/CLIProxyAPI_7.0.3_windows_amd64.zip",
8+
"archiveSha256": "65f1657a900b50cbcbe14526b4a59753141b18e3b8f09a691648fc50ca601660",
9+
"archiveAssetName": "CLIProxyAPI_7.0.3_windows_amd64.zip",
10+
"sourceCommit": "bd8c05a830a36b2e5181bb5c8596a2c8d85c3dbc",
711
"sourceRoot": "resources/backend/source",
812
"buildKind": "repo-source",
9-
"compatibilityPatchVersion": "codexcliplus-2026.05.07",
13+
"compatibilityPatchVersion": "codexcliplus-2026.05.12",
1014
"goVersion": "go1.26.2",
15+
"managedExecutableSha256": "711a79280e415e9b1d8d131b1388c2861bb2f3587b8a4ba22b51fb0f9fbde72c",
1116
"generatedArtifact": {
1217
"fileName": "ccp-core.exe",
1318
"runtime": "win-x64",
14-
"sha256": "f17d22d4fb7df11c84b06b1fe2123e45561bdc6f14226a3f3cffa344491d4023",
15-
"size": 25098240
19+
"sha256": "711a79280e415e9b1d8d131b1388c2861bb2f3587b8a4ba22b51fb0f9fbde72c",
20+
"size": 28566016
1621
},
17-
"upgradedAtUtc": "2026-05-07T06:21:00Z",
22+
"upgradedAtUtc": "2026-05-12T14:02:00Z",
23+
"dependencyOverrides": [
24+
{
25+
"module": "github.com/jackc/pgx/v5",
26+
"from": "5.7.6",
27+
"to": "5.9.2",
28+
"reason": "preserve CodexCliPlus vulnerability remediation floor"
29+
},
30+
{
31+
"module": "github.com/cloudflare/circl",
32+
"from": "1.6.1",
33+
"to": "1.6.3",
34+
"reason": "preserve CodexCliPlus vulnerability remediation floor"
35+
},
36+
{
37+
"module": "github.com/go-git/go-git/v6",
38+
"from": "6.0.0-20251009132922-75a182125145",
39+
"to": "6.0.0-alpha.2",
40+
"reason": "preserve CodexCliPlus vulnerability remediation floor"
41+
},
42+
{
43+
"module": "golang.org/x/crypto",
44+
"from": "0.45.0",
45+
"to": "0.50.0",
46+
"reason": "preserve CodexCliPlus vulnerability remediation floor"
47+
},
48+
{
49+
"module": "golang.org/x/net",
50+
"from": "0.47.0",
51+
"to": "0.53.0",
52+
"reason": "preserve CodexCliPlus vulnerability remediation floor"
53+
},
54+
{
55+
"module": "golang.org/x/sys",
56+
"from": "0.38.0",
57+
"to": "0.43.0",
58+
"reason": "preserve CodexCliPlus vulnerability remediation floor"
59+
},
60+
{
61+
"module": "golang.org/x/text",
62+
"from": "0.31.0",
63+
"to": "0.36.0",
64+
"reason": "preserve CodexCliPlus vulnerability remediation floor"
65+
}
66+
],
1867
"notes": [
1968
"Normal build output is generated from resources/backend/source.",
2069
"The upstream archive entry cli-proxy-api.exe remains an input name only; CodexCliPlus packages ccp-core.exe.",

resources/backend/source/cmd/fetch_antigravity_models/main.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ import (
2525
"strings"
2626
"time"
2727

28-
"github.com/router-for-me/CLIProxyAPI/v6/internal/logging"
29-
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
30-
sdkauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/auth"
31-
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
32-
"github.com/router-for-me/CLIProxyAPI/v6/sdk/proxyutil"
28+
"github.com/router-for-me/CLIProxyAPI/v7/internal/logging"
29+
"github.com/router-for-me/CLIProxyAPI/v7/internal/misc"
30+
sdkauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/auth"
31+
coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"
32+
"github.com/router-for-me/CLIProxyAPI/v7/sdk/proxyutil"
3333
log "github.com/sirupsen/logrus"
3434
"github.com/tidwall/gjson"
3535
)

resources/backend/source/cmd/server/main.go

Lines changed: 112 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,32 @@ import (
1010
"fmt"
1111
"io"
1212
"io/fs"
13+
"net"
1314
"net/url"
1415
"os"
1516
"path/filepath"
17+
"strconv"
1618
"strings"
1719
"time"
1820

1921
"github.com/joho/godotenv"
20-
configaccess "github.com/router-for-me/CLIProxyAPI/v6/internal/access/config_access"
21-
"github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo"
22-
"github.com/router-for-me/CLIProxyAPI/v6/internal/cmd"
23-
"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
24-
"github.com/router-for-me/CLIProxyAPI/v6/internal/logging"
25-
"github.com/router-for-me/CLIProxyAPI/v6/internal/managementasset"
26-
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
27-
"github.com/router-for-me/CLIProxyAPI/v6/internal/redisqueue"
28-
"github.com/router-for-me/CLIProxyAPI/v6/internal/registry"
29-
"github.com/router-for-me/CLIProxyAPI/v6/internal/store"
30-
_ "github.com/router-for-me/CLIProxyAPI/v6/internal/translator"
31-
"github.com/router-for-me/CLIProxyAPI/v6/internal/tui"
32-
"github.com/router-for-me/CLIProxyAPI/v6/internal/usage"
33-
"github.com/router-for-me/CLIProxyAPI/v6/internal/util"
34-
sdkAuth "github.com/router-for-me/CLIProxyAPI/v6/sdk/auth"
35-
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
22+
configaccess "github.com/router-for-me/CLIProxyAPI/v7/internal/access/config_access"
23+
"github.com/router-for-me/CLIProxyAPI/v7/internal/buildinfo"
24+
"github.com/router-for-me/CLIProxyAPI/v7/internal/cmd"
25+
"github.com/router-for-me/CLIProxyAPI/v7/internal/config"
26+
"github.com/router-for-me/CLIProxyAPI/v7/internal/home"
27+
"github.com/router-for-me/CLIProxyAPI/v7/internal/logging"
28+
"github.com/router-for-me/CLIProxyAPI/v7/internal/managementasset"
29+
"github.com/router-for-me/CLIProxyAPI/v7/internal/misc"
30+
"github.com/router-for-me/CLIProxyAPI/v7/internal/redisqueue"
31+
"github.com/router-for-me/CLIProxyAPI/v7/internal/registry"
32+
"github.com/router-for-me/CLIProxyAPI/v7/internal/store"
33+
_ "github.com/router-for-me/CLIProxyAPI/v7/internal/translator"
34+
"github.com/router-for-me/CLIProxyAPI/v7/internal/tui"
35+
"github.com/router-for-me/CLIProxyAPI/v7/internal/usage"
36+
"github.com/router-for-me/CLIProxyAPI/v7/internal/util"
37+
sdkAuth "github.com/router-for-me/CLIProxyAPI/v7/sdk/auth"
38+
coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"
3639
log "github.com/sirupsen/logrus"
3740
)
3841

@@ -71,6 +74,8 @@ func main() {
7174
var vertexImportPrefix string
7275
var configPath string
7376
var password string
77+
var homeAddr string
78+
var homePassword string
7479
var tuiMode bool
7580
var standalone bool
7681
var localModel bool
@@ -89,6 +94,8 @@ func main() {
8994
flag.StringVar(&vertexImport, "vertex-import", "", "Import Vertex service account key JSON file")
9095
flag.StringVar(&vertexImportPrefix, "vertex-import-prefix", "", "Prefix for Vertex model namespacing (use with -vertex-import)")
9196
flag.StringVar(&password, "password", "", "")
97+
flag.StringVar(&homeAddr, "home", "", "Home control plane address in host:port format (loads config from home and skips local config file)")
98+
flag.StringVar(&homePassword, "home-password", "", "Home control plane password (Redis AUTH)")
9299
flag.BoolVar(&tuiMode, "tui", false, "Start with terminal management UI")
93100
flag.BoolVar(&standalone, "standalone", false, "In TUI mode, start an embedded local server")
94101
flag.BoolVar(&localModel, "local-model", false, "Use embedded model catalog only, skip remote model fetching")
@@ -127,6 +134,7 @@ func main() {
127134
var err error
128135
var cfg *config.Config
129136
var isCloudDeploy bool
137+
var configLoadedFromHome bool
130138
var (
131139
usePostgresStore bool
132140
pgStoreDSN string
@@ -237,7 +245,68 @@ func main() {
237245
// Determine and load the configuration file.
238246
// Prefer the Postgres store when configured, otherwise fallback to git or local files.
239247
var configFilePath string
240-
if usePostgresStore {
248+
if strings.TrimSpace(homeAddr) != "" {
249+
configLoadedFromHome = true
250+
trimmedHomePassword := strings.TrimSpace(homePassword)
251+
host, portStr, errSplit := net.SplitHostPort(strings.TrimSpace(homeAddr))
252+
if errSplit != nil {
253+
log.Errorf("invalid -home address %q (expected host:port): %v", homeAddr, errSplit)
254+
return
255+
}
256+
host = strings.TrimSpace(host)
257+
if host == "" {
258+
log.Errorf("invalid -home address %q: host is empty", homeAddr)
259+
return
260+
}
261+
port, errPort := strconv.Atoi(strings.TrimSpace(portStr))
262+
if errPort != nil || port <= 0 {
263+
log.Errorf("invalid -home address %q: invalid port %q", homeAddr, portStr)
264+
return
265+
}
266+
267+
homeCfg := config.HomeConfig{
268+
Enabled: true,
269+
Host: host,
270+
Port: port,
271+
Password: trimmedHomePassword,
272+
}
273+
homeClient := home.New(homeCfg)
274+
defer homeClient.Close()
275+
276+
ctxHome, cancelHome := context.WithTimeout(context.Background(), 30*time.Second)
277+
raw, errGetConfig := homeClient.GetConfig(ctxHome)
278+
cancelHome()
279+
if errGetConfig != nil {
280+
log.Errorf("failed to fetch config from home: %v", errGetConfig)
281+
return
282+
}
283+
284+
parsed, errParseConfig := config.ParseConfigBytes(raw)
285+
if errParseConfig != nil {
286+
log.Errorf("failed to parse config payload from home: %v", errParseConfig)
287+
return
288+
}
289+
if parsed == nil {
290+
parsed = &config.Config{}
291+
}
292+
parsed.Home = homeCfg
293+
parsed.Port = 8317 // Default to 8317 for home mode, can be overridden by home config
294+
parsed.UsageStatisticsEnabled = true
295+
cfg = parsed
296+
297+
// Keep a non-empty config path for downstream components (log paths, management assets, etc),
298+
// but do not require the file to exist when loading config from home.
299+
if strings.TrimSpace(configPath) != "" {
300+
configFilePath = configPath
301+
} else {
302+
configFilePath = filepath.Join(wd, "config.yaml")
303+
}
304+
305+
// Local stores are intentionally disabled when config is loaded from home.
306+
usePostgresStore = false
307+
useObjectStore = false
308+
useGitStore = false
309+
} else if usePostgresStore {
241310
if pgStoreLocalPath == "" {
242311
pgStoreLocalPath = wd
243312
}
@@ -401,21 +470,25 @@ func main() {
401470
// In cloud deploy mode, check if we have a valid configuration
402471
var configFileExists bool
403472
if isCloudDeploy {
404-
if info, errStat := os.Stat(configFilePath); errStat != nil {
405-
// Don't mislead: API server will not start until configuration is provided.
406-
log.Info("Cloud deploy mode: No configuration file detected; standing by for configuration")
407-
configFileExists = false
408-
} else if info.IsDir() {
409-
log.Info("Cloud deploy mode: Config path is a directory; standing by for configuration")
410-
configFileExists = false
411-
} else if cfg.Port == 0 {
412-
// LoadConfigOptional returns empty config when file is empty or invalid.
413-
// Config file exists but is empty or invalid; treat as missing config
414-
log.Info("Cloud deploy mode: Configuration file is empty or invalid; standing by for valid configuration")
415-
configFileExists = false
473+
if configLoadedFromHome && cfg != nil {
474+
configFileExists = cfg.Port != 0
416475
} else {
417-
log.Info("Cloud deploy mode: Configuration file detected; starting service")
418-
configFileExists = true
476+
if info, errStat := os.Stat(configFilePath); errStat != nil {
477+
// Don't mislead: API server will not start until configuration is provided.
478+
log.Info("Cloud deploy mode: No configuration file detected; standing by for configuration")
479+
configFileExists = false
480+
} else if info.IsDir() {
481+
log.Info("Cloud deploy mode: Config path is a directory; standing by for configuration")
482+
configFileExists = false
483+
} else if cfg.Port == 0 {
484+
// LoadConfigOptional returns empty config when file is empty or invalid.
485+
// Config file exists but is empty or invalid; treat as missing config
486+
log.Info("Cloud deploy mode: Configuration file is empty or invalid; standing by for valid configuration")
487+
configFileExists = false
488+
} else {
489+
log.Info("Cloud deploy mode: Configuration file detected; starting service")
490+
configFileExists = true
491+
}
419492
}
420493
}
421494
usage.SetStatisticsEnabled(cfg.UsageStatisticsEnabled)
@@ -488,8 +561,11 @@ func main() {
488561
if standalone {
489562
// Standalone mode: start an embedded local server and connect TUI client to it.
490563
managementasset.StartAutoUpdater(context.Background(), configFilePath)
491-
if !localModel {
564+
misc.StartAntigravityVersionUpdater(context.Background())
565+
if !localModel && !cfg.Home.Enabled {
492566
registry.StartModelsUpdater(context.Background())
567+
} else if cfg.Home.Enabled {
568+
log.Info("Home mode: remote model updates disabled")
493569
}
494570
hook := tui.NewLogHook(2000)
495571
hook.SetFormatter(&logging.LogFormatter{})
@@ -563,8 +639,11 @@ func main() {
563639
} else {
564640
// Start the main proxy service
565641
managementasset.StartAutoUpdater(context.Background(), configFilePath)
566-
if !localModel {
642+
misc.StartAntigravityVersionUpdater(context.Background())
643+
if !localModel && !cfg.Home.Enabled {
567644
registry.StartModelsUpdater(context.Background())
645+
} else if cfg.Home.Enabled {
646+
log.Info("Home mode: remote model updates disabled")
568647
}
569648
cmd.StartService(cfg, configFilePath, password)
570649
}

resources/backend/source/config.example.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ tls:
1111
cert: ""
1212
key: ""
1313

14+
# Optional "home" control plane integration over Redis protocol.
15+
home:
16+
enabled: false
17+
host: "127.0.0.1"
18+
port: 6379
19+
password: ""
20+
1421
# Management API settings
1522
remote-management:
1623
# Whether to allow remote (non-localhost) management access.
@@ -67,6 +74,7 @@ error-logs-max-files: 10
6774
usage-statistics-enabled: false
6875

6976
# How long (in seconds) Redis usage queue items are retained in memory for the RESP interface (LPOP/RPOP).
77+
# Note: the in-process Redis RESP usage output is disabled when home.enabled is true.
7078
# Default: 60. Max: 3600.
7179
redis-usage-queue-retention-seconds: 60
7280

@@ -149,6 +157,7 @@ nonstream-keepalive-interval: 0
149157
# gemini-api-key:
150158
# - api-key: "AIzaSy...01"
151159
# prefix: "test" # optional: require calls like "test/gemini-3-pro-preview" to target this credential
160+
# disable-cooling: false # optional: per-auth override for auth/model cooldown scheduling
152161
# base-url: "https://generativelanguage.googleapis.com"
153162
# headers:
154163
# X-Custom-Header: "custom-value"
@@ -168,6 +177,7 @@ nonstream-keepalive-interval: 0
168177
# codex-api-key:
169178
# - api-key: "sk-atSM..."
170179
# prefix: "test" # optional: require calls like "test/gpt-5-codex" to target this credential
180+
# disable-cooling: false # optional: per-auth override for auth/model cooldown scheduling
171181
# base-url: "https://www.example.com" # use the custom codex API endpoint
172182
# headers:
173183
# X-Custom-Header: "custom-value"
@@ -187,6 +197,7 @@ nonstream-keepalive-interval: 0
187197
# - api-key: "sk-atSM..." # use the official claude API key, no need to set the base url
188198
# - api-key: "sk-atSM..."
189199
# prefix: "test" # optional: require calls like "test/claude-sonnet-latest" to target this credential
200+
# disable-cooling: false # optional: per-auth override for auth/model cooldown scheduling
190201
# base-url: "https://www.example.com" # use the custom claude API endpoint
191202
# headers:
192203
# X-Custom-Header: "custom-value"
@@ -242,6 +253,7 @@ nonstream-keepalive-interval: 0
242253
# disabled: false # optional: set to true to disable this provider without removing it
243254
# prefix: "test" # optional: require calls like "test/kimi-k2" to target this provider's credentials
244255
# base-url: "https://openrouter.ai/api/v1" # The base URL of the provider.
256+
# disable-cooling: false # optional: per-provider override for auth/model cooldown scheduling
245257
# headers:
246258
# X-Custom-Header: "custom-value"
247259
# api-key-entries:

resources/backend/source/go.mod

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module github.com/router-for-me/CLIProxyAPI/v6
1+
module github.com/router-for-me/CLIProxyAPI/v7
22

33
go 1.26.0
44

@@ -33,6 +33,12 @@ require (
3333

3434
require github.com/rogpeppe/go-internal v1.14.1 // indirect
3535

36+
require (
37+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
38+
github.com/redis/go-redis/v9 v9.19.0 // indirect
39+
go.uber.org/atomic v1.11.0 // indirect
40+
)
41+
3642
require (
3743
cloud.google.com/go/compute/metadata v0.3.0 // indirect
3844
github.com/Microsoft/go-winio v0.6.2 // indirect

0 commit comments

Comments
 (0)