mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-02 04:20:50 +08:00
- Added extensive SDK usage guides for `cliproxy`, `sdk/access`, and watcher integration. - Introduced `--password` flag for specifying local management access passwords. - Enhanced management API with local password checks to secure localhost requests. - Updated documentation to reflect the new password functionality.
4.7 KiB
4.7 KiB
SDK 高级指南:执行器与翻译器
本文介绍如何使用 SDK 扩展内嵌代理:
- 实现自定义 Provider 执行器以调用你的上游 API
- 注册请求/响应翻译器进行协议转换
- 注册模型以出现在
/v1/models
示例基于 Go 1.24+ 与 v6 模块路径。
概念
- Provider 执行器:实现
auth.ProviderExecutor的运行时组件,负责某个 provider key(如gemini、claude、codex)的真正出站调用。若实现RequestPreparer接口,可在原始 HTTP 请求上注入凭据。 - 翻译器注册表:由
sdk/translator驱动的协议转换函数。内置了 OpenAI/Gemini/Claude/Codex 的互转;你也可以注册新的格式转换。 - 模型注册表:对外发布可用模型列表,供
/v1/models与路由参考。
1) 实现 Provider 执行器
创建类型满足 auth.ProviderExecutor 接口。
package myprov
import (
"context"
"net/http"
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
clipexec "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/executor"
)
type Executor struct{}
func (Executor) Identifier() string { return "myprov" }
// 可选:在原始 HTTP 请求上注入凭据
func (Executor) PrepareRequest(req *http.Request, a *coreauth.Auth) error {
// 例如:req.Header.Set("Authorization", "Bearer "+a.Attributes["api_key"])
return nil
}
func (Executor) Execute(ctx context.Context, a *coreauth.Auth, req clipexec.Request, opts clipexec.Options) (clipexec.Response, error) {
// 基于 req.Payload 构造上游请求,返回上游 JSON 负载
return clipexec.Response{Payload: []byte(`{"ok":true}`)}, nil
}
func (Executor) ExecuteStream(ctx context.Context, a *coreauth.Auth, req clipexec.Request, opts clipexec.Options) (<-chan clipexec.StreamChunk, error) {
ch := make(chan clipexec.StreamChunk, 1)
go func() { defer close(ch); ch <- clipexec.StreamChunk{Payload: []byte("data: {\\"done\\":true}\\n\\n")} }()
return ch, nil
}
func (Executor) Refresh(ctx context.Context, a *coreauth.Auth) (*coreauth.Auth, error) { return a, nil }
在启动服务前将执行器注册到核心管理器:
core := coreauth.NewManager(coreauth.NewFileStore(cfg.AuthDir), nil, nil)
core.RegisterExecutor(myprov.Executor{})
svc, _ := cliproxy.NewBuilder().WithConfig(cfg).WithConfigPath(cfgPath).WithCoreAuthManager(core).Build()
当凭据的 Provider 为 "myprov" 时,管理器会将请求路由到你的执行器。
2) 注册翻译器
内置处理器接受 OpenAI/Gemini/Claude/Codex 的入站格式。要支持新的 provider 协议,需要在 sdk/translator 的默认注册表中注册转换函数。
方向很重要:
- 请求:从“入站格式”转换为“provider 格式”
- 响应:从“provider 格式”转换回“入站格式”
示例:OpenAI Chat → MyProv Chat 及其反向。
package myprov
import (
"context"
sdktr "github.com/router-for-me/CLIProxyAPI/v6/sdk/translator"
)
const (
FOpenAI = sdktr.Format("openai.chat")
FMyProv = sdktr.Format("myprov.chat")
)
func init() {
sdktr.Register(FOpenAI, FMyProv,
func(model string, raw []byte, stream bool) []byte { return convertOpenAIToMyProv(model, raw, stream) },
sdktr.ResponseTransform{
Stream: func(ctx context.Context, model string, originalReq, translatedReq, raw []byte, param *any) []string {
return convertStreamMyProvToOpenAI(model, originalReq, translatedReq, raw)
},
NonStream: func(ctx context.Context, model string, originalReq, translatedReq, raw []byte, param *any) string {
return convertMyProvToOpenAI(model, originalReq, translatedReq, raw)
},
},
)
}
当 OpenAI 处理器接到需要路由到 myprov 的请求时,流水线会自动应用已注册的转换。
3) 注册模型
通过全局模型注册表将模型暴露到 /v1/models:
models := []*cliproxy.ModelInfo{
{ ID: "myprov-pro-1", Object: "model", Type: "myprov", DisplayName: "MyProv Pro 1" },
}
cliproxy.GlobalModelRegistry().RegisterClient(authID, "myprov", models)
内置 Provider 会自动注册;自定义 Provider 建议在启动时(例如加载到 Auth 后)或在 Auth 注册钩子中调用。
凭据与传输
- 使用
Manager.SetRoundTripperProvider注入按账户的*http.Transport(例如代理):core.SetRoundTripperProvider(myProvider) // 按账户返回 transport - 对于原始 HTTP 请求,若实现了
PrepareRequest,或通过Manager.InjectCredentials(req, authID)进行头部注入。
测试建议
- 启用请求日志:管理 API GET/PUT
/v0/management/request-log - 切换调试日志:管理 API GET/PUT
/v0/management/debug - 热更新:
config.yaml与auths/变化会自动被侦测并应用