File size: 5,008 Bytes
bf9e111 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | # CLI Proxy SDK 使用指南
`sdk/cliproxy` 模块将代理能力以 Go 库的形式对外暴露,方便在其它服务中内嵌路由、鉴权、热更新与翻译层,而无需依赖可执行的 CLI 程序。
## 安装与导入
```bash
go get github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy
```
```go
import (
"context"
"errors"
"time"
"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
"github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy"
)
```
注意模块路径包含 `/v6`。
## 最小可用示例
```go
cfg, err := config.LoadConfig("config.yaml")
if err != nil { panic(err) }
svc, err := cliproxy.NewBuilder().
WithConfig(cfg).
WithConfigPath("config.yaml"). // 绝对路径或工作目录相对路径
Build()
if err != nil { panic(err) }
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
if err := svc.Run(ctx); err != nil && !errors.Is(err, context.Canceled) {
panic(err)
}
```
服务内部会管理配置与认证文件的监听、后台令牌刷新与优雅关闭。取消上下文即可停止服务。
## 服务器可选项(中间件、路由、日志)
通过 `WithServerOptions` 自定义:
```go
svc, _ := cliproxy.NewBuilder().
WithConfig(cfg).
WithConfigPath("config.yaml").
WithServerOptions(
// 追加全局中间件
cliproxy.WithMiddleware(func(c *gin.Context) { c.Header("X-Embed", "1"); c.Next() }),
// 提前调整 gin 引擎(如 CORS、trusted proxies)
cliproxy.WithEngineConfigurator(func(e *gin.Engine) { e.ForwardedByClientIP = true }),
// 在默认路由之后追加自定义路由
cliproxy.WithRouterConfigurator(func(e *gin.Engine, _ *handlers.BaseAPIHandler, _ *config.Config) {
e.GET("/healthz", func(c *gin.Context) { c.String(200, "ok") })
}),
// 覆盖请求日志的创建(启用/目录)
cliproxy.WithRequestLoggerFactory(func(cfg *config.Config, cfgPath string) logging.RequestLogger {
return logging.NewFileRequestLogger(true, "logs", filepath.Dir(cfgPath))
}),
).
Build()
```
这些选项与 CLI 服务器内部用法保持一致。
## 管理 API(内嵌时)
- 仅当 `config.yaml` 中设置了 `remote-management.secret-key` 时才会挂载管理端点。
- 远程访问还需要 `remote-management.allow-remote: true`。
- 具体端点见 MANAGEMENT_API_CN.md。内嵌服务器会在配置端口下暴露 `/v0/management`。
## 使用核心鉴权管理器
服务内部使用核心 `auth.Manager` 负责选择、执行、自动刷新。内嵌时可自定义其传输或钩子:
```go
core := coreauth.NewManager(coreauth.NewFileStore(cfg.AuthDir), nil, nil)
core.SetRoundTripperProvider(myRTProvider) // 按账户返回 *http.Transport
svc, _ := cliproxy.NewBuilder().
WithConfig(cfg).
WithConfigPath("config.yaml").
WithCoreAuthManager(core).
Build()
```
实现每个账户的自定义传输:
```go
type myRTProvider struct{}
func (myRTProvider) RoundTripperFor(a *coreauth.Auth) http.RoundTripper {
if a == nil || a.ProxyURL == "" { return nil }
u, _ := url.Parse(a.ProxyURL)
return &http.Transport{ Proxy: http.ProxyURL(u) }
}
```
管理器提供编程式执行接口:
```go
// 非流式
resp, err := core.Execute(ctx, []string{"gemini"}, req, opts)
// 流式
chunks, err := core.ExecuteStream(ctx, []string{"gemini"}, req, opts)
for ch := range chunks { /* ... */ }
```
说明:运行 `Service` 时会自动注册内置的提供商执行器;若仅单独使用 `Manager` 而不启动 HTTP 服务器,则需要自行实现并注册满足 `auth.ProviderExecutor` 的执行器。
## 自定义凭据来源
当凭据不在本地文件系统时,替换默认加载器:
```go
type memoryTokenProvider struct{}
func (p *memoryTokenProvider) Load(ctx context.Context, cfg *config.Config) (*cliproxy.TokenClientResult, error) {
// 从内存/远端加载并返回数量统计
return &cliproxy.TokenClientResult{}, nil
}
svc, _ := cliproxy.NewBuilder().
WithConfig(cfg).
WithConfigPath("config.yaml").
WithTokenClientProvider(&memoryTokenProvider{}).
WithAPIKeyClientProvider(cliproxy.NewAPIKeyClientProvider()).
Build()
```
## 启动钩子
无需修改内部代码即可观察生命周期:
```go
hooks := cliproxy.Hooks{
OnBeforeStart: func(cfg *config.Config) { log.Infof("starting on :%d", cfg.Port) },
OnAfterStart: func(s *cliproxy.Service) { log.Info("ready") },
}
svc, _ := cliproxy.NewBuilder().WithConfig(cfg).WithConfigPath("config.yaml").WithHooks(hooks).Build()
```
## 关闭
`Run` 内部会延迟调用 `Shutdown`,因此只需取消父上下文即可。若需手动停止:
```go
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
_ = svc.Shutdown(ctx)
```
## 说明
- 热更新:`config.yaml` 与 `auths/` 变化会被自动侦测并应用。
- 请求日志可通过管理 API 在运行时开关。
- `gemini-web.*` 相关配置在内嵌服务器中会被遵循。
|