mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-15 09:23:08 +08:00
96 lines
2.7 KiB
Go
96 lines
2.7 KiB
Go
package provider
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
"strings"
|
||
|
||
"GoNavi-Wails/internal/ai"
|
||
)
|
||
|
||
// CustomProvider 自定义 Provider,根据 apiFormat 选择底层协议
|
||
// 支持 openai / anthropic / gemini / cursor-agent 等 API 格式
|
||
type CustomProvider struct {
|
||
inner Provider
|
||
name string
|
||
}
|
||
|
||
// NewCustomProvider 创建自定义 Provider 实例
|
||
func NewCustomProvider(config ai.ProviderConfig) (Provider, error) {
|
||
// 根据 apiFormat 决定使用哪个底层协议,默认 openai
|
||
apiFormat := strings.ToLower(strings.TrimSpace(config.APIFormat))
|
||
if apiFormat == "" {
|
||
apiFormat = "openai"
|
||
}
|
||
if strings.TrimSpace(config.BaseURL) == "" && apiFormat != "claude-cli" && apiFormat != "codebuddy-cli" {
|
||
return nil, fmt.Errorf("custom provider Base URL is required")
|
||
}
|
||
|
||
var innerProvider Provider
|
||
var err error
|
||
switch apiFormat {
|
||
case "anthropic":
|
||
innerProvider, err = NewAnthropicProvider(config)
|
||
case "gemini":
|
||
innerProvider, err = NewGeminiProvider(config)
|
||
case "cursor-agent":
|
||
innerProvider, err = NewCursorAgentProvider(config)
|
||
case "claude-cli":
|
||
innerProvider, err = NewClaudeCLIProvider(config)
|
||
case "codebuddy-cli":
|
||
innerProvider, err = NewCodeBuddyCLIProvider(config)
|
||
default: // "openai" 及其他
|
||
innerProvider, err = NewOpenAIProvider(config)
|
||
}
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
name := strings.TrimSpace(config.Name)
|
||
if name == "" {
|
||
name = "Custom"
|
||
}
|
||
|
||
return &CustomProvider{
|
||
inner: innerProvider,
|
||
name: name,
|
||
}, nil
|
||
}
|
||
|
||
func (p *CustomProvider) Name() string {
|
||
return p.name
|
||
}
|
||
|
||
func (p *CustomProvider) Validate() error {
|
||
if strings.TrimSpace(p.inner.(interface{ Name() string }).Name()) == "" {
|
||
// 对自定义 Provider,API Key 可选(部分本地服务不需要)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (p *CustomProvider) Chat(ctx context.Context, req ai.ChatRequest) (*ai.ChatResponse, error) {
|
||
return p.inner.Chat(ctx, req)
|
||
}
|
||
|
||
func (p *CustomProvider) ChatStream(ctx context.Context, req ai.ChatRequest, callback func(ai.StreamChunk)) error {
|
||
return p.inner.ChatStream(ctx, req, callback)
|
||
}
|
||
|
||
func (p *CustomProvider) ChatWithState(ctx context.Context, state json.RawMessage, req ai.ChatRequest) (*ai.ChatResponse, json.RawMessage, error) {
|
||
sessionProvider, ok := p.inner.(SessionChatProvider)
|
||
if !ok {
|
||
resp, err := p.inner.Chat(ctx, req)
|
||
return resp, nil, err
|
||
}
|
||
return sessionProvider.ChatWithState(ctx, state, req)
|
||
}
|
||
|
||
func (p *CustomProvider) ChatStreamWithState(ctx context.Context, state json.RawMessage, req ai.ChatRequest, callback func(ai.StreamChunk)) (json.RawMessage, error) {
|
||
sessionProvider, ok := p.inner.(SessionStreamProvider)
|
||
if !ok {
|
||
return nil, p.inner.ChatStream(ctx, req, callback)
|
||
}
|
||
return sessionProvider.ChatStreamWithState(ctx, state, req, callback)
|
||
}
|