common

package
v0.10.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2026 License: AGPL-3.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	LastMessageTypeNone     = "none"
	LastMessageTypeText     = "text"
	LastMessageTypeTools    = "tools"
	LastMessageTypeThinking = "thinking"
)

Variables

This section is empty.

Functions

func AppendRequestConversionFromRequest

func AppendRequestConversionFromRequest(info *RelayInfo, req any)

func ApplyParamOverride

func ApplyParamOverride(jsonData []byte, paramOverride map[string]interface{}, conditionContext map[string]interface{}) ([]byte, error)

func BuildParamOverrideContext

func BuildParamOverrideContext(info *RelayInfo) map[string]interface{}

BuildParamOverrideContext 提供 ApplyParamOverride 可用的上下文信息。 目前内置以下字段:

  • upstream_model/model:始终为通道映射后的上游模型名。
  • original_model:请求最初指定的模型名。
  • request_path:请求路径
  • is_channel_test:是否为渠道测试请求(同 is_test)。

func GetAPIVersion

func GetAPIVersion(c *gin.Context) string

func GetFullRequestURL

func GetFullRequestURL(baseURL string, requestURL string, channelType int) string

func GuessRelayFormatFromRequest

func GuessRelayFormatFromRequest(req any) (types.RelayFormat, bool)

func RemoveDisabledFields

func RemoveDisabledFields(jsonData []byte, channelOtherSettings dto.ChannelOtherSettings) ([]byte, error)

RemoveDisabledFields 从请求 JSON 数据中移除渠道设置中禁用的字段 service_tier: 服务层级字段,可能导致额外计费(OpenAI、Claude、Responses API 支持) store: 数据存储授权字段,涉及用户隐私(仅 OpenAI、Responses API 支持,默认允许透传,禁用后可能导致 Codex 无法使用) safety_identifier: 安全标识符,用于向 OpenAI 报告违规用户(仅 OpenAI 支持,涉及用户隐私)

func RemoveGeminiDisabledFields

func RemoveGeminiDisabledFields(jsonData []byte) ([]byte, error)

RemoveGeminiDisabledFields removes disabled fields from Gemini request JSON data Currently supports removing functionResponse.id field which Vertex AI does not support

func ValidateBasicTaskRequest

func ValidateBasicTaskRequest(c *gin.Context, info *RelayInfo, action string) *dto.TaskError

func ValidateMultipartDirect

func ValidateMultipartDirect(c *gin.Context, info *RelayInfo) *dto.TaskError

Types

type BillingSettler added in v0.10.8

type BillingSettler interface {
	// Settle 根据实际消耗额度进行结算,计算 delta = actualQuota - preConsumedQuota,
	// 同时调整资金来源(钱包/订阅)和令牌额度。
	Settle(actualQuota int) error

	// Refund 退还所有预扣费额度(资金来源 + 令牌),幂等安全。
	// 通过 gopool 异步执行。如果已经结算或退款则不做任何操作。
	Refund(c *gin.Context)

	// NeedsRefund 返回会话是否存在需要退还的预扣状态(未结算且未退款)。
	NeedsRefund() bool

	// GetPreConsumedQuota 返回实际预扣的额度值(信任用户可能为 0)。
	GetPreConsumedQuota() int
}

BillingSettler 抽象计费会话的生命周期操作。 由 service.BillingSession 实现,存储在 RelayInfo 上以避免循环引用。

type BuildInToolInfo

type BuildInToolInfo struct {
	ToolName          string
	CallCount         int
	SearchContextSize string
}

type ChannelMeta

type ChannelMeta struct {
	ChannelType          int
	ChannelId            int
	ChannelIsMultiKey    bool
	ChannelMultiKeyIndex int
	ChannelBaseUrl       string
	ApiType              int
	ApiVersion           string
	ApiKey               string
	Organization         string
	ChannelCreateTime    int64
	ParamOverride        map[string]interface{}
	HeadersOverride      map[string]interface{}
	ChannelSetting       dto.ChannelSettings
	ChannelOtherSettings dto.ChannelOtherSettings
	UpstreamModelName    string
	IsModelMapped        bool
	SupportStreamOptions bool // 是否支持流式选项
}

type ClaudeConvertInfo

type ClaudeConvertInfo struct {
	LastMessagesType string
	Index            int
	Usage            *dto.Usage
	FinishReason     string
	Done             bool
}

type ConditionOperation

type ConditionOperation struct {
	Path           string      `json:"path"`             // JSON路径
	Mode           string      `json:"mode"`             // full, prefix, suffix, contains, gt, gte, lt, lte
	Value          interface{} `json:"value"`            // 匹配的值
	Invert         bool        `json:"invert"`           // 反选功能,true表示取反结果
	PassMissingKey bool        `json:"pass_missing_key"` // 未获取到json key时的行为
}

type HasImage

type HasImage interface {
	HasImage() bool
}

type HasPrompt

type HasPrompt interface {
	GetPrompt() string
}

type ParamOperation

type ParamOperation struct {
	Path       string               `json:"path"`
	Mode       string               `json:"mode"` // delete, set, move, copy, prepend, append, trim_prefix, trim_suffix, ensure_prefix, ensure_suffix, trim_space, to_lower, to_upper, replace, regex_replace
	Value      interface{}          `json:"value"`
	KeepOrigin bool                 `json:"keep_origin"`
	From       string               `json:"from,omitempty"`
	To         string               `json:"to,omitempty"`
	Conditions []ConditionOperation `json:"conditions,omitempty"` // 条件列表
	Logic      string               `json:"logic,omitempty"`      // AND, OR (默认OR)
}

type RelayInfo

type RelayInfo struct {
	TokenId           int
	TokenKey          string
	TokenGroup        string
	UserId            int
	UsingGroup        string // 使用的分组,当auto跨分组重试时,会变动
	UserGroup         string // 用户所在分组
	TokenUnlimited    bool
	StartTime         time.Time
	FirstResponseTime time.Time

	//SendLastReasoningResponse bool
	IsStream               bool
	IsGeminiBatchEmbedding bool
	IsPlayground           bool
	UsePrice               bool
	RelayMode              int
	OriginModelName        string
	RequestURLPath         string
	ShouldIncludeUsage     bool
	DisablePing            bool // 是否禁止向下游发送自定义 Ping
	ClientWs               *websocket.Conn
	TargetWs               *websocket.Conn
	InputAudioFormat       string
	OutputAudioFormat      string
	RealtimeTools          []dto.RealTimeTool
	IsFirstRequest         bool
	AudioUsage             bool
	ReasoningEffort        string
	UserSetting            dto.UserSetting
	UserEmail              string
	UserQuota              int
	RelayFormat            types.RelayFormat
	SendResponseCount      int
	ReceivedResponseCount  int
	FinalPreConsumedQuota  int // 最终预消耗的配额
	// Billing 是计费会话,封装了预扣费/结算/退款的统一生命周期。
	// 免费模型和按次计费(MJ/Task)时为 nil。
	Billing BillingSettler
	// BillingSource indicates whether this request is billed from wallet quota or subscription.
	// "" or "wallet" => wallet; "subscription" => subscription
	BillingSource string
	// SubscriptionId is the user_subscriptions.id used when BillingSource == "subscription"
	SubscriptionId int
	// SubscriptionPreConsumed is the amount pre-consumed on subscription item (quota units or 1)
	SubscriptionPreConsumed int64
	// SubscriptionPostDelta is the post-consume delta applied to amount_used (quota units; can be negative).
	SubscriptionPostDelta int64
	// SubscriptionPlanId / SubscriptionPlanTitle are used for logging/UI display.
	SubscriptionPlanId    int
	SubscriptionPlanTitle string
	// RequestId is used for idempotent pre-consume/refund
	RequestId string
	// SubscriptionAmountTotal / SubscriptionAmountUsedAfterPreConsume are used to compute remaining in logs.
	SubscriptionAmountTotal               int64
	SubscriptionAmountUsedAfterPreConsume int64
	IsClaudeBetaQuery                     bool // /v1/messages?beta=true
	IsChannelTest                         bool // channel test request

	PriceData types.PriceData

	Request dto.Request

	// RequestConversionChain records request format conversions in order, e.g.
	// ["openai", "openai_responses"] or ["openai", "claude"].
	RequestConversionChain []types.RelayFormat

	ThinkingContentInfo
	TokenCountMeta
	*ClaudeConvertInfo
	*RerankerInfo
	*ResponsesUsageInfo
	*ChannelMeta
	*TaskRelayInfo
	// contains filtered or unexported fields
}

func GenRelayInfo

func GenRelayInfo(c *gin.Context, relayFormat types.RelayFormat, request dto.Request, ws *websocket.Conn) (*RelayInfo, error)

func GenRelayInfoClaude

func GenRelayInfoClaude(c *gin.Context, request dto.Request) *RelayInfo

func GenRelayInfoEmbedding

func GenRelayInfoEmbedding(c *gin.Context, request dto.Request) *RelayInfo

func GenRelayInfoGemini

func GenRelayInfoGemini(c *gin.Context, request dto.Request) *RelayInfo

func GenRelayInfoImage

func GenRelayInfoImage(c *gin.Context, request dto.Request) *RelayInfo

func GenRelayInfoOpenAI

func GenRelayInfoOpenAI(c *gin.Context, request dto.Request) *RelayInfo

func GenRelayInfoOpenAIAudio

func GenRelayInfoOpenAIAudio(c *gin.Context, request dto.Request) *RelayInfo

func GenRelayInfoRerank

func GenRelayInfoRerank(c *gin.Context, request *dto.RerankRequest) *RelayInfo

func GenRelayInfoResponses

func GenRelayInfoResponses(c *gin.Context, request *dto.OpenAIResponsesRequest) *RelayInfo

func GenRelayInfoResponsesCompaction

func GenRelayInfoResponsesCompaction(c *gin.Context, request *dto.OpenAIResponsesCompactionRequest) *RelayInfo

func GenRelayInfoWs

func GenRelayInfoWs(c *gin.Context, ws *websocket.Conn) *RelayInfo

func (*RelayInfo) AppendRequestConversion

func (info *RelayInfo) AppendRequestConversion(format types.RelayFormat)

func (*RelayInfo) GetEstimatePromptTokens

func (info *RelayInfo) GetEstimatePromptTokens() int

func (*RelayInfo) HasSendResponse

func (info *RelayInfo) HasSendResponse() bool

func (*RelayInfo) InitChannelMeta

func (info *RelayInfo) InitChannelMeta(c *gin.Context)

func (*RelayInfo) InitRequestConversionChain

func (info *RelayInfo) InitRequestConversionChain()

func (*RelayInfo) SetEstimatePromptTokens

func (info *RelayInfo) SetEstimatePromptTokens(promptTokens int)

func (*RelayInfo) SetFirstResponseTime

func (info *RelayInfo) SetFirstResponseTime()

func (*RelayInfo) ToString

func (info *RelayInfo) ToString() string

type RerankerInfo

type RerankerInfo struct {
	Documents       []any
	ReturnDocuments bool
}

type ResponsesUsageInfo

type ResponsesUsageInfo struct {
	BuiltInTools map[string]*BuildInToolInfo
}

type TaskInfo

type TaskInfo struct {
	Code             int    `json:"code"`
	TaskID           string `json:"task_id"`
	Status           string `json:"status"`
	Reason           string `json:"reason,omitempty"`
	Url              string `json:"url,omitempty"`
	RemoteUrl        string `json:"remote_url,omitempty"`
	Progress         string `json:"progress,omitempty"`
	CompletionTokens int    `json:"completion_tokens,omitempty"` // 用于按倍率计费
	TotalTokens      int    `json:"total_tokens,omitempty"`      // 用于按倍率计费
}

func FailTaskInfo

func FailTaskInfo(reason string) *TaskInfo

type TaskRelayInfo

type TaskRelayInfo struct {
	Action       string
	OriginTaskID string

	ConsumeQuota bool
}

type TaskSubmitReq

type TaskSubmitReq struct {
	Prompt         string                 `json:"prompt"`
	Model          string                 `json:"model,omitempty"`
	Mode           string                 `json:"mode,omitempty"`
	Image          string                 `json:"image,omitempty"`
	Images         []string               `json:"images,omitempty"`
	Size           string                 `json:"size,omitempty"`
	Duration       int                    `json:"duration,omitempty"`
	Seconds        string                 `json:"seconds,omitempty"`
	InputReference string                 `json:"input_reference,omitempty"`
	Metadata       map[string]interface{} `json:"metadata,omitempty"`
}

func GetTaskRequest

func GetTaskRequest(c *gin.Context) (TaskSubmitReq, error)

func (*TaskSubmitReq) GetPrompt

func (t *TaskSubmitReq) GetPrompt() string

func (*TaskSubmitReq) HasImage

func (t *TaskSubmitReq) HasImage() bool

func (*TaskSubmitReq) UnmarshalJSON

func (t *TaskSubmitReq) UnmarshalJSON(data []byte) error

func (*TaskSubmitReq) UnmarshalMetadata

func (t *TaskSubmitReq) UnmarshalMetadata(v any) error

type ThinkingContentInfo

type ThinkingContentInfo struct {
	IsFirstThinkingContent  bool
	SendLastThinkingContent bool
	HasSentThinkingContent  bool
}

type TokenCountMeta

type TokenCountMeta struct {
	// contains filtered or unexported fields
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL