Documentation
¶
Overview ¶
Package dialect 定义对外暴露的四种大模型文本协议方言,以及它们在本地端点与 上游端点上的路径形状。
方言只描述「客户端用哪种协议说话」,不描述「上游是哪家厂商」。同一个方言可以 对应多个渠道,渠道的 BaseURL 与鉴权方式由 channel 包负责。
Index ¶
- Variables
- func CheckPayload(name Name, value any) error
- func DecodeRequest(name Name, body []byte) (any, error)
- func DecodeResponse(name Name, body []byte) (any, error)
- func DecodeStreamEvent(name Name, data []byte) (any, bool, error)
- func DecodeStreamResponse(name Name, data []byte) (any, error)
- func DoneEvent() []byte
- func Encode(value any) ([]byte, error)
- func EntriesOf(name Name, body []byte) ([][]byte, error)
- func IsDoneMarker(data []byte) bool
- func ModelOf(name Name, body []byte) (string, error)
- func SessionKeyOf(name Name, body []byte) string
- func StreamIntent(name Name, body []byte, hint bool) (bool, error)
- func ValidateModelName(model string) error
- type Name
- type StreamEvent
Constants ¶
This section is empty.
Variables ¶
var ErrUnsupportedPayload = errors.New("dialect: 载荷类型与方言不匹配")
ErrUnsupportedPayload 表示载荷类型不属于该方言。
Functions ¶
func CheckPayload ¶
CheckPayload 校验载荷类型是否与方言一致,供测试与断言使用。
载荷本身是 RelayKit 的 DTO,因此这个函数是给知道那套类型的调用方用的; 只需要收发字节的调用方用不上它。
func DecodeRequest ¶
DecodeRequest 把请求体解析成 RelayKit 的请求 DTO。返回的具体类型由方言决定: OpenAI Chat 是 *dto.GeneralOpenAIRequest,OpenAI Responses 是 *dto.OpenAIResponsesRequest,Claude 是 *dto.ClaudeRequest,Gemini 是 *dto.GeminiChatRequest。
func DecodeResponse ¶
DecodeResponse 把非流式响应体解析成 RelayKit 的响应 DTO。
func DecodeStreamEvent ¶
DecodeStreamEvent 解析一条上游流式事件的 data 负载。第二个返回值为假表示 这条事件不承载内容(结束标记、心跳),调用方应跳过它。
空负载与 OpenAI Chat 的 [DONE] 标记都属于跳过之列;Claude 与 OpenAI Responses 的 ping 事件同理。
func DecodeStreamResponse ¶
DecodeStreamResponse 把流式事件的负载解析成对应方言的流式 DTO。
流式与非流式的 DTO 不同名也不同形(例如 OpenAI Chat 的分片是 delta 而不是 message),这里必须分开解析,否则转换器会因类型不符直接报错。
func EntriesOf ¶ added in v0.2.0
EntriesOf 返回请求里的内容条目序列,每一段都已经规范化成稳定的字节。
序列的第一个条目固定是「工具定义加系统提示」,后面依次是对话条目。这个划分让 同一段会话在连续几轮里的条目序列保持前缀关系:只有尾部在增长。上游的提示缓存 按前缀工作,调用方要靠这个关系认出「当前请求里的哪一段是上一轮发过的」。
规范化走「解码再序列化」而不是截取原始字节。客户端重发同一段历史时 JSON 键 顺序不保证稳定,直接哈希原始字节会让同一个前缀算出不同的指纹。
没有对话条目时返回的序列只有头条目,不是空序列。
func ModelOf ¶
ModelOf 从请求体里读出模型名。
只有 Gemini 的模型名在 URL 路径上,因此该方言返回空串且不报错,调用方需自行 从路径取用。其余三方言返回请求体里的 model 字段,缺失时返回错误。
func SessionKeyOf ¶ added in v0.2.0
SessionKeyOf 返回客户端在请求体里给出的会话标识,没有时返回空串。
只有 OpenAI 的两个方言有 prompt_cache_key 字段,它是 OpenAI 为缓存路由专门 提供的。Claude 与 Gemini 把缓存挂在别处(cache_control 断点、cachedContent 引用),体里没有对应的标识,因此返回空串,调用方应改用请求头。
解析失败返回空串而不是错误:调用方在此之前已经用 DecodeRequest 校验过请求体, 这里再报一次错只会多出一条没有信息量的分支。
func StreamIntent ¶
StreamIntent 返回请求的流式意图。
Gemini 的流式只体现在路径上,因此该方言直接用 hint。其余三方言以请求体为准, 体里没有 stream 字段时退回 hint。
func ValidateModelName ¶
ValidateModelName 校验适合写进 URL 路径的模型名。
Gemini 把模型名写在路径上,因此它必须是一段不含分隔符的名字。允许的字符是 字母、数字与 . _ - 三种符号:斜杠会把模型名拆成两段路径,问号会凭空添出查询 参数,百分号能绕开这段检查去构造前面两种情况。
Types ¶
type Name ¶
type Name string
Name 是方言标识,取值即配置文件里 dialect 字段的写法。
const ( // OpenAIChat 是 OpenAI Chat Completions。 OpenAIChat Name = "openai" // OpenAIResponses 是 OpenAI Responses。 OpenAIResponses Name = "openai_responses" // ClaudeMessages 是 Anthropic Claude Messages。 ClaudeMessages Name = "claude" // GeminiGenerate 是 Google Gemini generateContent。 GeminiGenerate Name = "gemini" )
type StreamEvent ¶
type StreamEvent struct {
// Event 是 SSE 的 event 名。四种方言里只有 Claude Messages 与 OpenAI
// Responses 用命名事件,另外两种为空。
Event string
// Data 是事件的 JSON 负载。
Data []byte
}
StreamEvent 是一条待写出的流式事件。
func EncodeStreamEvent ¶
func EncodeStreamEvent(name Name, value any) (StreamEvent, error)
EncodeStreamEvent 把转换结果编成一条可写出的流式事件。
转成 OpenAI Responses 时 RelayKit 返回 relayconvert.ChatToResponsesStreamEvent 包装体,事件名在包装体的 Type 上而负载在 Payload 上;其它情况事件名取自 DTO 自身的 type 字段。