Documentation
¶
Overview ¶
Package relay 是转发内核:把客户端方言的请求体转换成上游方言,把上游的响应体 转换回客户端方言,并在两个方向上原样带出转换损耗的诊断。
内核是纯函数式的,不发网络请求、不读配置:上游地址、鉴权、重试都在 channel 与 server 层。同方言不走转换,本包在两方言相同时直接返回 passthrough 标记, 只按字节定点改顶层 model 一个字段而不重新序列化 —— 逐字节保留未建模字段只有 在不经过 JSON 往返时才成立。
Index ¶
- Constants
- Variables
- func SetMediaResolver(resolver MediaResolver)
- type Diagnostic
- type Engine
- func (e *Engine) NewStream(from, to dialect.Name, originModel, upstreamModel string, opts StreamOptions) (*Stream, error)
- func (e *Engine) ParseModel(model string) (string, *Reasoning)
- func (e *Engine) PrepareRequest(ctx context.Context, req Request) (*Prepared, error)
- func (e *Engine) PrepareResponse(ctx context.Context, resp Response) (*PreparedResponse, error)
- type LossPolicy
- type MediaResolver
- type MediaSource
- type Options
- type Prepared
- type PreparedResponse
- type Quality
- type Reasoning
- type Report
- type Request
- type Response
- type Severity
- type Step
- type Stream
- func (s *Stream) Convert(ctx context.Context, data []byte) ([]dialect.StreamEvent, error)
- func (s *Stream) Diagnostics() []Diagnostic
- func (s *Stream) Fail(code, message, param string) ([]dialect.StreamEvent, bool)
- func (s *Stream) Finalize(ctx context.Context) ([]dialect.StreamEvent, error)
- func (s *Stream) Report() Report
- func (s *Stream) Usage() *dto.Usage
- type StreamOptions
Constants ¶
const DefaultClaudeMaxTokens = 4096
DefaultClaudeMaxTokens 是 OpenAI 或 Gemini 转 Claude 时,源请求未带 max_tokens 时补的默认值。Claude Messages 要求该字段,缺失即 400。
Variables ¶
var ErrSameDialect = errors.New("relay: 源方言与目标方言相同,应按字节透传")
ErrSameDialect 表示两个方言相同,无需转换。
Functions ¶
func SetMediaResolver ¶
func SetMediaResolver(resolver MediaResolver)
SetMediaResolver 注册媒体解析能力。
这是一个进程级的全局设置,只能在启动阶段调用一次。它与 RelayKit 的对应函数是 同一个开关,因此同一进程内只需要有一处设置。核心包提供这个入口,是为了让调用方 不必自己依赖 RelayKit。
Types ¶
type Diagnostic ¶
type Diagnostic struct {
// Code 是机器可读的原因标识。
Code string
// Path 是出问题的字段路径,可能为空。
Path string
// Message 是给人看的说明。
Message string
// Severity 是级别。
Severity Severity
// From 与 To 是这一跳的源方言与目标方言。
From dialect.Name
To dialect.Name
}
Diagnostic 是一条转换损耗。
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine 是转换内核。可以并发使用。
func (*Engine) NewStream ¶
func (e *Engine) NewStream(from, to dialect.Name, originModel, upstreamModel string, opts StreamOptions) (*Stream, error)
NewStream 创建转换会话。
from 是渠道方言,to 是客户端方言。两方言相同时返回 ErrSameDialect:那种情况 应当按字节管道转发,经过 JSON 往返会丢掉未建模字段。
func (*Engine) ParseModel ¶
ParseModel 按需剥离模型名尾缀。
未打开 ModelSuffix 时原样返回,状态为 nil。打开时识别各家已知尾缀,返回 基础模型名与推理状态;识别不出尾缀时同样原样返回。
调用方应当用返回的基础模型名去匹配路由规则,再去发请求。
func (*Engine) PrepareRequest ¶
PrepareRequest 生成发给上游的请求体。
两方言相同时返回 Passthrough 为真的结果,不做 DTO 建模;但只要规则给了与 客户端模型名不同的上游名,顶层 model 字段仍会被定点改写,见 setModelField。
func (*Engine) PrepareResponse ¶
PrepareResponse 把上游非流式响应转换回客户端方言。
type LossPolicy ¶
type LossPolicy string
LossPolicy 决定请求转换遇到工具语义损耗时怎么处理。
const ( // LossPolicyAllow 是默认值:照常完成转换,每条损耗都记进诊断。 LossPolicyAllow LossPolicy = "allow" // LossPolicySafe 在 error 级诊断时把请求转换判为失败。 LossPolicySafe LossPolicy = "safe" // LossPolicyStrict 在任何诊断下都把请求转换判为失败。 LossPolicyStrict LossPolicy = "strict" )
type MediaResolver ¶
type MediaResolver struct {
// GetBase64Data 按来源取回内容,返回 base64 数据与它的 MIME 类型。
GetBase64Data func(ctx context.Context, source MediaSource) (base64Data string, mimeType string, err error)
// DecodeBase64FileData 解析一段 data URL,返回它的 MIME 类型与 base64 数据。
DecodeBase64FileData func(dataURL string) (mimeType string, base64Data string, err error)
}
MediaResolver 提供跨协议转换时需要下载图片与解析 data URL 的能力。
内核本身不发网络请求:两个回调都由宿主提供。缺少回调时,需要媒体解析的转换 会明确报错,而不是静默丢掉内容。
type MediaSource ¶
type MediaSource struct {
// URL 是图片来源地址,需要取回内容。
URL string
// Data 是内联的 base64 内容,不含 data URL 前缀。
Data string
// MimeType 是内联内容声明的类型,可能为空。
MimeType string
}
MediaSource 是一次媒体解析请求的来源。
URL 与 Data 只会有一个非空:URL 表示内容要自己去取,Data 是内联的 base64。
func (MediaSource) Identifier ¶
func (m MediaSource) Identifier() string
Identifier 返回可用于日志与报错的简短标识。
type Options ¶
type Options struct {
// ToolLossPolicy 决定请求转换遇到工具语义损耗时是否报错。默认 allow:
// 照常完成并把每条损耗写进诊断。响应与流式转换不受该策略影响。
ToolLossPolicy LossPolicy
// DefaultMaxTokens 返回源请求未带 max_tokens 时给 Claude 补的值。
// 为 nil 时用 DefaultClaudeMaxTokens。
DefaultMaxTokens func(model string) int
// ThinkingAdapter 打开推理设置的渲染。模型名尾缀仍由 ParseModel 先行剥离。
ThinkingAdapter bool
// ModelSuffix 打开模型名尾缀识别。打开时 ParseModel 才会剥离
// -thinking / -nothinking / -high 这类尾缀。
ModelSuffix bool
}
Options 是内核的行为开关。零值可用,此时只做无附加适配的协议转换。
type Prepared ¶
type Prepared struct {
// Passthrough 为真时 Body 是客户端原始报文字节(可能只改过顶层 model 一个
// 字段),未做 DTO 建模。
Passthrough bool
// Body 是发给上游的请求体。
Body []byte
// Stream 是客户端请求的流式意图。
Stream bool
// contains filtered or unexported fields
}
Prepared 是转换后的上游请求。
func (*Prepared) Diagnostics ¶
func (p *Prepared) Diagnostics() []Diagnostic
Diagnostics 返回请求转换产生的诊断。Passthrough 为真时返回空。
type PreparedResponse ¶
type PreparedResponse struct {
// Passthrough 为真时 Body 是上游原始报文字节,未做解析。
Passthrough bool
// Body 是发给客户端的响应体。
Body []byte
// Usage 是归一后的用量,可能为 nil。
//
// 这个字段用的是 RelayKit 的类型,理由见 docs/relay.md 的
// 「与 RelayKit 的关系」:镜像用量结构只会带来漂移。
Usage *dto.Usage
// contains filtered or unexported fields
}
PreparedResponse 是转换后的非流式响应。
func (*PreparedResponse) Diagnostics ¶
func (p *PreparedResponse) Diagnostics() []Diagnostic
Diagnostics 返回响应转换产生的诊断。Passthrough 为真时返回空。
func (*PreparedResponse) Report ¶
func (p *PreparedResponse) Report() Report
Report 说明这次转换是怎么完成的。Passthrough 为真时返回零值。
type Reasoning ¶
type Reasoning struct {
// Mode 是推理模式,例如 thinking 或 nothinking。
Mode string
// Effort 是推理强度,例如 low、medium、high。
Effort string
// BudgetTokens 是推理预算的 token 数。
BudgetTokens *int
// IncludeThoughts 表示是否要求把推理内容写进响应。
IncludeThoughts *bool
}
Reasoning 是模型名尾缀解析出的推理设置。
type Report ¶
type Report struct {
// Converter 是所选转换器的标识。
Converter string
// Quality 是转换质量的等级。
Quality Quality
// Steps 是实际经过的转换跳;直接转换只有一跳。
Steps []Step
// From 与 To 是整个转换的源方言与目标方言。
From dialect.Name
To dialect.Name
}
Report 说明一次转换实际是怎么完成的。
type Request ¶
type Request struct {
From dialect.Name
To dialect.Name
Body []byte
OriginModel string
UpstreamModel string
Stream bool
}
Request 描述一次待转换的请求。
UpstreamModel 是发往上游的模型名,由调用方从配置的路由规则算出;为空时沿用 OriginModel。OriginModel 是客户端请求的模型名,用于推理状态判断与诊断。
Stream 是调用方从请求行或路径得到的流式意图。Gemini 的流式只体现在路径上 (:streamGenerateContent),请求体里没有该字段,因此这个方言必须由调用方给出; 另外三方言以请求体为准,体里没写时才用本字段。
Body 会被完整读入内存后解析,调用方负责限制其大小。
type Response ¶
type Response struct {
From dialect.Name
To dialect.Name
Body []byte
OriginModel string
UpstreamModel string
}
Response 描述一次待转换的非流式响应。From 是渠道方言,To 是客户端方言。
type Step ¶
type Step struct {
// Converter 是这一跳所用的转换器标识。
Converter string
// From 与 To 是这一跳的源方言与目标方言。
From dialect.Name
To dialect.Name
}
Step 是一次转换跳。
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream 是一条上游流的转换会话。每条上游流对应一个实例,不可并发复用。
func (*Stream) Convert ¶
Convert 转换一条上游流式事件。data 是 SSE 的 data 负载。返回空切片表示这条 事件不承载内容,调用方跳过即可。
meta.IsStream 在会话内固定为真,供上游为 Gemini 的转换路径判断目标请求是否 需要流式字段。
func (*Stream) Fail ¶
func (s *Stream) Fail(code, message, param string) ([]dialect.StreamEvent, bool)
Fail 在流中途失败时补出错误事件。第二个返回值表示是否补出了事件。
type StreamOptions ¶
type StreamOptions struct {
// ID 是转发给客户端的响应 id 前缀。
ID string
// Model 是客户端请求的模型名,写进响应信封。
Model string
// Created 是响应创建时间(Unix 秒)。
Created int64
// IncludeUsage 要求上游在流末尾给出用量。
IncludeUsage bool
// EmitSequenceNumber 打开 OpenAI Responses 的 sequence_number 字段。
EmitSequenceNumber bool
}
StreamOptions 是流式转换会话的创建参数,取自客户端请求里与响应信封相关的字段。