mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-17 19:47:10 +08:00
532 lines
21 KiB
Go
532 lines
21 KiB
Go
package runtime
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"cursor/internal/modelchannel"
|
|
)
|
|
|
|
var (
|
|
// ErrInvalidSystemSetting 表示当前模块中的 ErrInvalidSystemSetting 状态值。
|
|
ErrInvalidSystemSetting = errors.New("invalid system setting")
|
|
// ErrChannelNotAvailable 表示当前没有可用模型渠道。
|
|
ErrChannelNotAvailable = errors.New("model channel not available")
|
|
// ErrChannelRateLimited 表示当前模型渠道被限流。
|
|
ErrChannelRateLimited = errors.New("model channel rate limited")
|
|
)
|
|
|
|
const (
|
|
// configurableChannelTimeoutMS 表示当前声明中的 configurableChannelTimeoutMS。
|
|
configurableChannelTimeoutMS = int((2 * time.Hour) / time.Millisecond)
|
|
// configurableChannelContextWindowTokens 表示当前声明中的默认上下文窗口大小。
|
|
configurableChannelContextWindowTokens = 200_000
|
|
// configurableChannelMaxTokens 表示当前声明中的 configurableChannelMaxTokens。
|
|
configurableChannelMaxTokens = 65_536
|
|
// configurableChannelThinkingBudgetTokens 表示当前声明中的 configurableChannelThinkingBudgetTokens。
|
|
configurableChannelThinkingBudgetTokens = 4_096
|
|
// configurableChannelAnthropicThinkingEffort 表示 Anthropic adaptive thinking 默认强度。
|
|
configurableChannelAnthropicThinkingEffort = "xhigh"
|
|
)
|
|
|
|
// ModelAdapterConfig 定义了当前模块中的 ModelAdapterConfig 类型。
|
|
type ModelAdapterConfig struct {
|
|
ID string `json:"id,omitempty"`
|
|
// Sort 表示模型渠道的展示顺序。
|
|
Sort int `json:"sort"`
|
|
// DisplayName 表示当前声明中的 DisplayName。
|
|
DisplayName string `json:"displayName"`
|
|
// Type 表示当前声明中的 Type。
|
|
Type string `json:"type"`
|
|
// BaseURL 表示当前声明中的 BaseURL。
|
|
BaseURL string `json:"baseURL"`
|
|
// APIKey 表示当前声明中的 APIKey。
|
|
APIKey string `json:"apiKey"`
|
|
// TooltipData 表示当前声明中的 TooltipData。
|
|
TooltipData string `json:"tooltipData"`
|
|
// ModelID 表示当前声明中的 ModelID。
|
|
ModelID string `json:"modelID"`
|
|
// ReasoningEffort 表示当前声明中的 ReasoningEffort。
|
|
ReasoningEffort string `json:"reasoningEffort"`
|
|
// OpenAIEndpoint 表示 OpenAI 兼容适配器使用的 API 端点。
|
|
OpenAIEndpoint string `json:"openAIEndpoint"`
|
|
// OpenAIExtraParamsEnabled 表示是否启用 OpenAI 额外请求参数。
|
|
OpenAIExtraParamsEnabled bool `json:"openAIExtraParamsEnabled"`
|
|
// OpenAIExtraParamsJSON 表示 OpenAI 额外请求参数 JSON 对象。
|
|
OpenAIExtraParamsJSON string `json:"openAIExtraParamsJSON"`
|
|
// CustomHeadersEnabled 表示是否启用自定义请求头。
|
|
CustomHeadersEnabled bool `json:"customHeadersEnabled"`
|
|
// CustomHeadersJSON 表示自定义请求头 JSON 对象。
|
|
CustomHeadersJSON string `json:"customHeadersJSON"`
|
|
// AnthropicExtraParamsEnabled 表示是否启用 Anthropic 额外请求参数。
|
|
AnthropicExtraParamsEnabled bool `json:"anthropicExtraParamsEnabled"`
|
|
// AnthropicExtraParamsJSON 表示 Anthropic 额外请求参数 JSON 对象。
|
|
AnthropicExtraParamsJSON string `json:"anthropicExtraParamsJSON"`
|
|
// ContextWindowTokens 表示当前声明中的 ContextWindowTokens。
|
|
ContextWindowTokens int `json:"contextWindowTokens"`
|
|
// MaxCompletionTokens 表示当前声明中的 MaxCompletionTokens。
|
|
MaxCompletionTokens int `json:"maxCompletionTokens"`
|
|
// AnthropicMaxTokens 表示当前声明中的 AnthropicMaxTokens。
|
|
AnthropicMaxTokens int `json:"anthropicMaxTokens"`
|
|
// AnthropicThinkingEffort 表示 Anthropic adaptive thinking 的 output_config.effort。
|
|
AnthropicThinkingEffort string `json:"anthropicThinkingEffort,omitempty"`
|
|
// ThinkingBudgetTokens 表示当前声明中的 ThinkingBudgetTokens。
|
|
ThinkingBudgetTokens int `json:"thinkingBudgetTokens"`
|
|
}
|
|
|
|
// RuntimeConfigSnapshot 定义了当前模块中的 RuntimeConfigSnapshot 类型。
|
|
type RuntimeConfigSnapshot struct {
|
|
// ObservabilityLogEnabled 表示当前声明中的 ObservabilityLogEnabled。
|
|
ObservabilityLogEnabled bool
|
|
// ProviderStreamIdleTimeout 表示 provider 流式响应无有效内容时的空闲超时,单位秒。
|
|
ProviderStreamIdleTimeout int
|
|
// ModelAdapters 表示当前声明中的 ModelAdapters。
|
|
ModelAdapters []ModelAdapterConfig
|
|
}
|
|
|
|
// RuntimeConfigProvider 定义了当前模块中的 RuntimeConfigProvider 类型。
|
|
type RuntimeConfigProvider func(context.Context) (RuntimeConfigSnapshot, error)
|
|
|
|
// NormalizeModelAdapterConfigs 用于处理与 NormalizeModelAdapterConfigs 相关的逻辑。
|
|
func NormalizeModelAdapterConfigs(input []ModelAdapterConfig) ([]ModelAdapterConfig, error) {
|
|
if len(input) == 0 {
|
|
return []ModelAdapterConfig{}, nil
|
|
}
|
|
|
|
normalized := make([]ModelAdapterConfig, 0, len(input))
|
|
seenChannelIDs := make(map[string]struct{}, len(input))
|
|
for _, item := range input {
|
|
baseURL, err := modelchannel.NormalizeBaseURL(item.BaseURL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
next := ModelAdapterConfig{
|
|
Sort: item.Sort,
|
|
DisplayName: strings.TrimSpace(item.DisplayName),
|
|
Type: normalizeModelAdapterType(item.Type),
|
|
BaseURL: baseURL,
|
|
APIKey: strings.TrimSpace(item.APIKey),
|
|
TooltipData: strings.TrimSpace(item.TooltipData),
|
|
ModelID: strings.TrimSpace(item.ModelID),
|
|
ReasoningEffort: normalizeReasoningEffort(item.ReasoningEffort),
|
|
OpenAIEndpoint: modelchannel.NormalizeOpenAIEndpoint(item.Type, item.OpenAIEndpoint),
|
|
ContextWindowTokens: normalizeMaxCompletionTokens(item.ContextWindowTokens),
|
|
MaxCompletionTokens: normalizeMaxCompletionTokens(item.MaxCompletionTokens),
|
|
AnthropicMaxTokens: normalizeMaxCompletionTokens(item.AnthropicMaxTokens),
|
|
ThinkingBudgetTokens: normalizeMaxCompletionTokens(item.ThinkingBudgetTokens),
|
|
}
|
|
if next.Type == "openai" {
|
|
next.OpenAIExtraParamsEnabled = item.OpenAIExtraParamsEnabled
|
|
next.OpenAIExtraParamsJSON = strings.TrimSpace(item.OpenAIExtraParamsJSON)
|
|
} else if next.Type == "anthropic" {
|
|
next.AnthropicThinkingEffort = normalizeAnthropicThinkingEffort(item.AnthropicThinkingEffort)
|
|
next.AnthropicExtraParamsEnabled = item.AnthropicExtraParamsEnabled
|
|
next.AnthropicExtraParamsJSON = strings.TrimSpace(item.AnthropicExtraParamsJSON)
|
|
}
|
|
next.CustomHeadersEnabled = item.CustomHeadersEnabled
|
|
next.CustomHeadersJSON = strings.TrimSpace(item.CustomHeadersJSON)
|
|
switch {
|
|
case next.DisplayName == "":
|
|
return nil, errors.New("模型适配器 displayName 不能为空")
|
|
case next.Type == "":
|
|
return nil, errors.New("模型适配器 type 仅支持 openai 或 anthropic")
|
|
case next.APIKey == "":
|
|
return nil, errors.New("模型适配器 apiKey 不能为空")
|
|
case next.TooltipData == "":
|
|
return nil, errors.New("模型适配器 tooltipData 不能为空")
|
|
case next.ModelID == "":
|
|
return nil, errors.New("模型适配器 modelID 不能为空")
|
|
case next.Type == "openai" && next.ReasoningEffort == "":
|
|
return nil, errors.New("模型适配器 reasoningEffort 仅支持 low、medium、high、xhigh、max")
|
|
case next.Type == "openai" && next.OpenAIEndpoint == "":
|
|
return nil, errors.New("模型适配器 openAIEndpoint 仅支持 /v1/responses 或 /v1/chat/completions")
|
|
case next.Type == "openai" && next.OpenAIExtraParamsEnabled:
|
|
if err := validateJSONMap(next.OpenAIExtraParamsJSON, "openAIExtraParamsJSON"); err != nil {
|
|
return nil, err
|
|
}
|
|
case next.CustomHeadersEnabled:
|
|
if err := validateHeadersJSON(next.CustomHeadersJSON); err != nil {
|
|
return nil, err
|
|
}
|
|
case next.Type == "anthropic" && next.AnthropicExtraParamsEnabled:
|
|
if err := validateJSONMap(next.AnthropicExtraParamsJSON, "anthropicExtraParamsJSON"); err != nil {
|
|
return nil, err
|
|
}
|
|
case next.Type == "anthropic" && next.AnthropicThinkingEffort == "":
|
|
return nil, errors.New("模型适配器 anthropicThinkingEffort 仅支持 low、medium、high、xhigh、max")
|
|
}
|
|
next.ID = modelchannel.BuildChannelID(next.BaseURL, next.ModelID, next.APIKey, next.DisplayName, next.OpenAIEndpoint)
|
|
if _, exists := seenChannelIDs[next.ID]; exists {
|
|
return nil, errors.New("模型适配器渠道不能重复,请检查 url、modelID、apiKey、displayName、endpoint 组合")
|
|
}
|
|
seenChannelIDs[next.ID] = struct{}{}
|
|
normalized = append(normalized, next)
|
|
}
|
|
normalizeModelAdapterSorts(normalized)
|
|
return normalized, nil
|
|
}
|
|
|
|
func normalizeModelAdapterSorts(adapters []ModelAdapterConfig) {
|
|
sort.SliceStable(adapters, func(leftIndex, rightIndex int) bool {
|
|
left := adapters[leftIndex].Sort
|
|
right := adapters[rightIndex].Sort
|
|
switch {
|
|
case left <= 0 && right <= 0:
|
|
return false
|
|
case left <= 0:
|
|
return false
|
|
case right <= 0:
|
|
return true
|
|
default:
|
|
return left < right
|
|
}
|
|
})
|
|
for index := range adapters {
|
|
adapters[index].Sort = index + 1
|
|
}
|
|
}
|
|
|
|
func validateJSONMap(value string, fieldName string) error {
|
|
text := strings.TrimSpace(value)
|
|
if text == "" {
|
|
return fmt.Errorf("模型适配器 %s 不能为空", fieldName)
|
|
}
|
|
var parsed map[string]any
|
|
if err := json.Unmarshal([]byte(text), &parsed); err != nil {
|
|
return fmt.Errorf("模型适配器 %s 必须是合法 JSON 对象", fieldName)
|
|
}
|
|
if parsed == nil {
|
|
return fmt.Errorf("模型适配器 %s 必须是 JSON 对象", fieldName)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateHeadersJSON(value string) error {
|
|
text := strings.TrimSpace(value)
|
|
if err := validateJSONMap(text, "customHeadersJSON"); err != nil {
|
|
return err
|
|
}
|
|
var parsed map[string]string
|
|
if err := json.Unmarshal([]byte(text), &parsed); err != nil {
|
|
return errors.New("模型适配器 customHeadersJSON 的值必须是字符串")
|
|
}
|
|
for key := range parsed {
|
|
if strings.TrimSpace(key) == "" {
|
|
return errors.New("模型适配器 customHeadersJSON 的请求头名称不能为空")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func normalizeReasoningEffort(value string) string {
|
|
switch strings.ToLower(strings.TrimSpace(value)) {
|
|
case "", "medium":
|
|
return "medium"
|
|
case "low", "high", "xhigh", "max":
|
|
return strings.ToLower(strings.TrimSpace(value))
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func normalizeAnthropicThinkingEffort(value string) string {
|
|
switch strings.ToLower(strings.TrimSpace(value)) {
|
|
case "", "xhigh":
|
|
return "xhigh"
|
|
case "low", "medium", "high", "max":
|
|
return strings.ToLower(strings.TrimSpace(value))
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func normalizeMaxCompletionTokens(value int) int {
|
|
if value <= 0 {
|
|
return 0
|
|
}
|
|
return value
|
|
}
|
|
|
|
// normalizeModelAdapterType 用于处理与 normalizeModelAdapterType 相关的逻辑。
|
|
func normalizeModelAdapterType(value string) string {
|
|
switch strings.ToLower(strings.TrimSpace(value)) {
|
|
case "openai":
|
|
return "openai"
|
|
case "anthropic":
|
|
return "anthropic"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// ResolvedChannel 表示当前选中的模型渠道。
|
|
type ResolvedChannel struct {
|
|
// ID 表示当前声明中的 ID。
|
|
ID string
|
|
// Name 表示当前声明中的 Name。
|
|
Name string
|
|
// GroupName 表示当前声明中的 GroupName。
|
|
GroupName string
|
|
// Code 表示当前声明中的 Code。
|
|
Code string
|
|
// Provider 表示当前声明中的 Provider。
|
|
Provider string
|
|
// BaseURL 表示当前声明中的 BaseURL。
|
|
BaseURL string
|
|
// APIKey 表示当前声明中的 APIKey。
|
|
APIKey string
|
|
// Model 表示当前声明中的 Model。
|
|
Model string
|
|
// TimeoutMS 表示当前声明中的 TimeoutMS。
|
|
TimeoutMS int
|
|
// ContextWindowTokens 表示当前声明中的 ContextWindowTokens。
|
|
ContextWindowTokens int
|
|
// MaxTokens 表示当前声明中的 MaxTokens。
|
|
MaxTokens int
|
|
// ReasoningEffort 表示当前声明中的 ReasoningEffort。
|
|
ReasoningEffort string
|
|
// OpenAIEndpoint 表示 OpenAI 兼容适配器使用的 API 端点。
|
|
OpenAIEndpoint string
|
|
// OpenAIExtraParamsEnabled 表示是否启用 OpenAI 额外请求参数。
|
|
OpenAIExtraParamsEnabled bool
|
|
// OpenAIExtraParamsJSON 表示 OpenAI 额外请求参数 JSON 对象。
|
|
OpenAIExtraParamsJSON string
|
|
// CustomHeadersEnabled 表示是否启用自定义请求头。
|
|
CustomHeadersEnabled bool
|
|
// CustomHeadersJSON 表示自定义请求头 JSON 对象。
|
|
CustomHeadersJSON string
|
|
// AnthropicExtraParamsEnabled 表示是否启用 Anthropic 额外请求参数。
|
|
AnthropicExtraParamsEnabled bool
|
|
// AnthropicExtraParamsJSON 表示 Anthropic 额外请求参数 JSON 对象。
|
|
AnthropicExtraParamsJSON string
|
|
// AnthropicMaxTokens 表示当前声明中的 AnthropicMaxTokens。
|
|
AnthropicMaxTokens int
|
|
// AnthropicThinkingEffort 表示 Anthropic adaptive thinking 的 output_config.effort。
|
|
AnthropicThinkingEffort string
|
|
// ThinkingEnabled 表示当前声明中的 ThinkingEnabled。
|
|
ThinkingEnabled bool
|
|
// ThinkingBudgetTokens 表示当前声明中的 ThinkingBudgetTokens。
|
|
ThinkingBudgetTokens int
|
|
}
|
|
|
|
// ChannelUsageRecordCreatePayload 定义了一次渠道使用记录的最小载荷。
|
|
type ChannelUsageRecordCreatePayload struct {
|
|
// RequestID 表示当前声明中的 RequestID。
|
|
RequestID string
|
|
// ConversationID 表示当前声明中的 ConversationID。
|
|
ConversationID string
|
|
// RuntimeModelID 表示当前声明中的 RuntimeModelID。
|
|
RuntimeModelID string
|
|
}
|
|
|
|
// ChannelCallRecordCreatePayload 定义了一次渠道调用记录的最小载荷。
|
|
type ChannelCallRecordCreatePayload struct {
|
|
// RequestID 表示当前声明中的 RequestID。
|
|
RequestID string
|
|
// ConversationID 表示当前声明中的 ConversationID。
|
|
ConversationID string
|
|
// ChannelID 表示当前声明中的 ChannelID。
|
|
ChannelID string
|
|
// ChannelName 表示当前声明中的 ChannelName。
|
|
ChannelName string
|
|
// GroupName 表示当前声明中的 GroupName。
|
|
GroupName string
|
|
// Provider 表示当前声明中的 Provider。
|
|
Provider string
|
|
// RuntimeModelID 表示当前声明中的 RuntimeModelID。
|
|
RuntimeModelID string
|
|
// ProviderModelID 表示当前声明中的 ProviderModelID。
|
|
ProviderModelID string
|
|
// StatusCode 表示当前声明中的 StatusCode。
|
|
StatusCode int
|
|
// Success 表示当前声明中的 Success。
|
|
Success bool
|
|
// DurationMS 表示当前声明中的 DurationMS。
|
|
DurationMS int64
|
|
// ErrorCode 表示当前声明中的 ErrorCode。
|
|
ErrorCode string
|
|
// ErrorMessage 表示当前声明中的 ErrorMessage。
|
|
ErrorMessage string
|
|
}
|
|
|
|
// FixedChannelService 定义了当前模块中的 FixedChannelService 类型。
|
|
type FixedChannelService struct {
|
|
// channel 表示当前声明中的 channel。
|
|
channel ResolvedChannel
|
|
// configProvider 表示当前声明中的 configProvider。
|
|
configProvider RuntimeConfigProvider
|
|
}
|
|
|
|
// NewFixedChannelService 用于处理与 NewFixedChannelService 相关的逻辑。
|
|
func NewFixedChannelService(channel ResolvedChannel, logsRoot string) *FixedChannelService {
|
|
_ = logsRoot
|
|
return &FixedChannelService{
|
|
channel: channel,
|
|
}
|
|
}
|
|
|
|
// NewConfigurableChannelService 用于处理与 NewConfigurableChannelService 相关的逻辑。
|
|
func NewConfigurableChannelService(provider RuntimeConfigProvider, logsRoot string) *FixedChannelService {
|
|
_ = logsRoot
|
|
return &FixedChannelService{
|
|
configProvider: provider,
|
|
}
|
|
}
|
|
|
|
// SelectChannelForRequestBody 用于处理与 SelectChannelForRequestBody 相关的逻辑。
|
|
func (s *FixedChannelService) SelectChannelForRequestBody(_ context.Context, _ []byte) (*ResolvedChannel, error) {
|
|
return s.SelectChannelForModel(context.Background(), "")
|
|
}
|
|
|
|
// SelectChannelForModel 用于处理与 SelectChannelForModel 相关的逻辑。
|
|
func (s *FixedChannelService) SelectChannelForModel(ctx context.Context, modelID string) (*ResolvedChannel, error) {
|
|
if s == nil {
|
|
return nil, ErrChannelNotAvailable
|
|
}
|
|
if s.configProvider != nil {
|
|
cfg, err := s.configProvider(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
adapters, err := NormalizeModelAdapterConfigs(cfg.ModelAdapters)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
matchIndex, ok := modelchannel.ResolveAdapterIndex(
|
|
adapters,
|
|
modelID,
|
|
func(adapter ModelAdapterConfig) string { return adapter.ID },
|
|
func(adapter ModelAdapterConfig) string { return adapter.ModelID },
|
|
func(adapter ModelAdapterConfig) string {
|
|
return modelchannel.BuildLegacyChannelID(adapter.BaseURL, adapter.ModelID, adapter.APIKey, adapter.DisplayName)
|
|
},
|
|
)
|
|
if !ok {
|
|
return nil, ErrChannelNotAvailable
|
|
}
|
|
adapter := adapters[matchIndex]
|
|
resolved := ResolvedChannel{
|
|
ID: strings.TrimSpace(adapter.ID),
|
|
Name: strings.TrimSpace(adapter.DisplayName),
|
|
GroupName: "local",
|
|
Code: strings.TrimSpace(adapter.ID),
|
|
Provider: strings.TrimSpace(adapter.Type),
|
|
BaseURL: strings.TrimSpace(adapter.BaseURL),
|
|
APIKey: strings.TrimSpace(adapter.APIKey),
|
|
Model: strings.TrimSpace(adapter.ModelID),
|
|
TimeoutMS: configurableChannelTimeoutMS,
|
|
ContextWindowTokens: configurableChannelContextWindowTokens,
|
|
MaxTokens: configurableChannelMaxTokens,
|
|
ReasoningEffort: strings.TrimSpace(adapter.ReasoningEffort),
|
|
OpenAIEndpoint: strings.TrimSpace(adapter.OpenAIEndpoint),
|
|
OpenAIExtraParamsEnabled: adapter.OpenAIExtraParamsEnabled,
|
|
OpenAIExtraParamsJSON: strings.TrimSpace(adapter.OpenAIExtraParamsJSON),
|
|
CustomHeadersEnabled: adapter.CustomHeadersEnabled,
|
|
CustomHeadersJSON: strings.TrimSpace(adapter.CustomHeadersJSON),
|
|
AnthropicExtraParamsEnabled: adapter.AnthropicExtraParamsEnabled,
|
|
AnthropicExtraParamsJSON: strings.TrimSpace(adapter.AnthropicExtraParamsJSON),
|
|
AnthropicMaxTokens: configurableChannelMaxTokens,
|
|
AnthropicThinkingEffort: configurableChannelAnthropicThinkingEffort,
|
|
ThinkingEnabled: true,
|
|
ThinkingBudgetTokens: configurableChannelThinkingBudgetTokens,
|
|
}
|
|
if adapter.ContextWindowTokens > 0 {
|
|
resolved.ContextWindowTokens = adapter.ContextWindowTokens
|
|
}
|
|
if adapter.MaxCompletionTokens > 0 {
|
|
resolved.MaxTokens = adapter.MaxCompletionTokens
|
|
}
|
|
if adapter.ThinkingBudgetTokens > 0 {
|
|
resolved.ThinkingBudgetTokens = adapter.ThinkingBudgetTokens
|
|
}
|
|
if adapter.AnthropicMaxTokens > 0 {
|
|
resolved.AnthropicMaxTokens = adapter.AnthropicMaxTokens
|
|
}
|
|
if strings.TrimSpace(adapter.AnthropicThinkingEffort) != "" {
|
|
resolved.AnthropicThinkingEffort = strings.TrimSpace(adapter.AnthropicThinkingEffort)
|
|
}
|
|
return &resolved, nil
|
|
}
|
|
if strings.TrimSpace(s.channel.BaseURL) == "" || strings.TrimSpace(s.channel.APIKey) == "" {
|
|
return nil, ErrChannelNotAvailable
|
|
}
|
|
resolved := s.channel
|
|
return &resolved, nil
|
|
}
|
|
|
|
// RecordRunRequestUsage 用于处理与 RecordRunRequestUsage 相关的逻辑。
|
|
func (s *FixedChannelService) RecordRunRequestUsage(_ context.Context, payload ChannelUsageRecordCreatePayload) error {
|
|
_ = s
|
|
_ = payload
|
|
return nil
|
|
}
|
|
|
|
// RecordChannelCall 用于处理与 RecordChannelCall 相关的逻辑。
|
|
func (s *FixedChannelService) RecordChannelCall(_ context.Context, payload ChannelCallRecordCreatePayload) error {
|
|
_ = s
|
|
_ = payload
|
|
return nil
|
|
}
|
|
|
|
// LocalSystemSettingService 定义了当前模块中的 LocalSystemSettingService 类型。
|
|
type LocalSystemSettingService struct {
|
|
// provider 表示当前声明中的 provider。
|
|
provider RuntimeConfigProvider
|
|
}
|
|
|
|
// NewLocalSystemSettingService 用于处理与 NewLocalSystemSettingService 相关的逻辑。
|
|
func NewLocalSystemSettingService(provider RuntimeConfigProvider) *LocalSystemSettingService {
|
|
return &LocalSystemSettingService{provider: provider}
|
|
}
|
|
|
|
// ResolveFrontendBaseURL 用于处理与 ResolveFrontendBaseURL 相关的逻辑。
|
|
func (s *LocalSystemSettingService) ResolveFrontendBaseURL(context.Context) (string, error) {
|
|
return "http://127.0.0.1", nil
|
|
}
|
|
|
|
// IsObservabilityLogEnabled 用于处理与 IsObservabilityLogEnabled 相关的逻辑。
|
|
func (s *LocalSystemSettingService) IsObservabilityLogEnabled(ctx context.Context) bool {
|
|
cfg, err := s.load(ctx)
|
|
if err != nil {
|
|
return true
|
|
}
|
|
return cfg.ObservabilityLogEnabled
|
|
}
|
|
|
|
// IsAgentRuntimeModelEnabled 用于处理与 IsAgentRuntimeModelEnabled 相关的逻辑。
|
|
func (s *LocalSystemSettingService) IsAgentRuntimeModelEnabled(context.Context) bool {
|
|
return true
|
|
}
|
|
|
|
// ResolveCursorServerBridge 用于处理与 ResolveCursorServerBridge 相关的逻辑。
|
|
func (s *LocalSystemSettingService) ResolveCursorServerBridge(context.Context) (string, bool) {
|
|
return "", false
|
|
}
|
|
|
|
// LoadRuntimeConfigSnapshot 用于处理与 LoadRuntimeConfigSnapshot 相关的逻辑。
|
|
func (s *LocalSystemSettingService) LoadRuntimeConfigSnapshot(ctx context.Context) (RuntimeConfigSnapshot, error) {
|
|
return s.load(ctx)
|
|
}
|
|
|
|
// ResolveModelAdapters 用于处理与 ResolveModelAdapters 相关的逻辑。
|
|
func (s *LocalSystemSettingService) ResolveModelAdapters(ctx context.Context) ([]ModelAdapterConfig, error) {
|
|
cfg, err := s.load(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NormalizeModelAdapterConfigs(cfg.ModelAdapters)
|
|
}
|
|
|
|
// load 用于处理与 load 相关的逻辑。
|
|
func (s *LocalSystemSettingService) load(ctx context.Context) (RuntimeConfigSnapshot, error) {
|
|
if s == nil || s.provider == nil {
|
|
return RuntimeConfigSnapshot{}, nil
|
|
}
|
|
return s.provider(ctx)
|
|
}
|