dialect

package
v0.2.0 Latest Latest
Warning

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

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

Documentation

Overview

Package dialect 定义对外暴露的四种大模型文本协议方言,以及它们在本地端点与 上游端点上的路径形状。

方言只描述「客户端用哪种协议说话」,不描述「上游是哪家厂商」。同一个方言可以 对应多个渠道,渠道的 BaseURL 与鉴权方式由 channel 包负责。

Index

Constants

This section is empty.

Variables

View Source
var ErrUnsupportedPayload = errors.New("dialect: 载荷类型与方言不匹配")

ErrUnsupportedPayload 表示载荷类型不属于该方言。

Functions

func CheckPayload

func CheckPayload(name Name, value any) error

CheckPayload 校验载荷类型是否与方言一致,供测试与断言使用。

载荷本身是 RelayKit 的 DTO,因此这个函数是给知道那套类型的调用方用的; 只需要收发字节的调用方用不上它。

func DecodeRequest

func DecodeRequest(name Name, body []byte) (any, error)

DecodeRequest 把请求体解析成 RelayKit 的请求 DTO。返回的具体类型由方言决定: OpenAI Chat 是 *dto.GeneralOpenAIRequest,OpenAI Responses 是 *dto.OpenAIResponsesRequest,Claude 是 *dto.ClaudeRequest,Gemini 是 *dto.GeminiChatRequest。

func DecodeResponse

func DecodeResponse(name Name, body []byte) (any, error)

DecodeResponse 把非流式响应体解析成 RelayKit 的响应 DTO。

func DecodeStreamEvent

func DecodeStreamEvent(name Name, data []byte) (any, bool, error)

DecodeStreamEvent 解析一条上游流式事件的 data 负载。第二个返回值为假表示 这条事件不承载内容(结束标记、心跳),调用方应跳过它。

空负载与 OpenAI Chat 的 [DONE] 标记都属于跳过之列;Claude 与 OpenAI Responses 的 ping 事件同理。

func DecodeStreamResponse

func DecodeStreamResponse(name Name, data []byte) (any, error)

DecodeStreamResponse 把流式事件的负载解析成对应方言的流式 DTO。

流式与非流式的 DTO 不同名也不同形(例如 OpenAI Chat 的分片是 delta 而不是 message),这里必须分开解析,否则转换器会因类型不符直接报错。

func DoneEvent

func DoneEvent() []byte

DoneEvent 返回 OpenAI Chat Completions 的流结束标记。

func Encode

func Encode(value any) ([]byte, error)

Encode 把 DTO 编成 JSON 字节。

func EntriesOf added in v0.2.0

func EntriesOf(name Name, body []byte) ([][]byte, error)

EntriesOf 返回请求里的内容条目序列,每一段都已经规范化成稳定的字节。

序列的第一个条目固定是「工具定义加系统提示」,后面依次是对话条目。这个划分让 同一段会话在连续几轮里的条目序列保持前缀关系:只有尾部在增长。上游的提示缓存 按前缀工作,调用方要靠这个关系认出「当前请求里的哪一段是上一轮发过的」。

规范化走「解码再序列化」而不是截取原始字节。客户端重发同一段历史时 JSON 键 顺序不保证稳定,直接哈希原始字节会让同一个前缀算出不同的指纹。

没有对话条目时返回的序列只有头条目,不是空序列。

func IsDoneMarker

func IsDoneMarker(data []byte) bool

IsDoneMarker 报告一段 data 负载是否是流结束标记。

func ModelOf

func ModelOf(name Name, body []byte) (string, error)

ModelOf 从请求体里读出模型名。

只有 Gemini 的模型名在 URL 路径上,因此该方言返回空串且不报错,调用方需自行 从路径取用。其余三方言返回请求体里的 model 字段,缺失时返回错误。

func SessionKeyOf added in v0.2.0

func SessionKeyOf(name Name, body []byte) string

SessionKeyOf 返回客户端在请求体里给出的会话标识,没有时返回空串。

只有 OpenAI 的两个方言有 prompt_cache_key 字段,它是 OpenAI 为缓存路由专门 提供的。Claude 与 Gemini 把缓存挂在别处(cache_control 断点、cachedContent 引用),体里没有对应的标识,因此返回空串,调用方应改用请求头。

解析失败返回空串而不是错误:调用方在此之前已经用 DecodeRequest 校验过请求体, 这里再报一次错只会多出一条没有信息量的分支。

func StreamIntent

func StreamIntent(name Name, body []byte, hint bool) (bool, error)

StreamIntent 返回请求的流式意图。

Gemini 的流式只体现在路径上,因此该方言直接用 hint。其余三方言以请求体为准, 体里没有 stream 字段时退回 hint。

func ValidateModelName

func ValidateModelName(model string) error

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"
)

func MustParse

func MustParse(s string) Name

MustParse 与 Parse 相同,但不识别时 panic。只用于包内常量与测试。

func Names

func Names() []Name

Names 按固定顺序返回四种方言,供配置校验、文档与测试遍历。

func Parse

func Parse(s string) (Name, bool)

Parse 解析方言名,大小写与首尾空白不计。第二个返回值表示是否识别。

func (Name) LocalPath

func (n Name) LocalPath() string

LocalPath 返回本地端点接收该方言的路径。Gemini 的模型名在路径上,因此用 {model} 占位。

func (Name) UpstreamPath

func (n Name) UpstreamPath(model string, stream bool) (string, error)

UpstreamPath 返回发往上游时应拼在渠道 BaseURL 之后的路径。stream 为真时 取流式端点。

只有 Gemini 把模型名写在路径上,必须由调用方给出;其余三方言的模型名在请求体 里,model 会被忽略。

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 字段。

Jump to

Keyboard shortcuts

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