Documentation
¶
Overview ¶
Package api holds the protocol-neutral request model shared by every wire protocol implementation (OpenAI Chat Completions, OpenAI Responses, Anthropic Messages, Google Generative AI, Ollama) plus the helpers those implementations share: SSE reading, the SSRF-safe transport, streaming tool-call assembly, prompt-cache bookkeeping and usage logging.
Protocol packages live under api/<protocol>; vendor facts live in internal/models/catalog and internal/models/providers. This package must not import either of them.
Index ¶
- Constants
- Variables
- func ApplyCacheControlBreakpoints(payload map[string]any, marker *CacheControlMarker)
- func AttachSessionAffinityHeaders(req *http.Request, sessionID string)
- func BuildPromptCacheKey(tenantID uint64, modelID, purpose, prefixFingerprint string) string
- func ClampPromptCacheKey(key string) string
- func EncodeMultipart(fields []FormField, file FormFile) ([]byte, string, error)
- func FingerprintPromptPrefix(parts ...string) string
- func IsMultimodalNotSupportedError(err error) bool
- func IsSandboxMutationTool(name string) bool
- func LogRequest(ctx context.Context, url, model string, body []byte, stream bool)
- func LogUsage(ctx context.Context, model string, u *types.TokenUsage)
- func PlaceEmbeddings(want, got int, at func(i int) (int, []float32)) ([][]float32, error)
- func PromptPrefixFingerprint(messages []Message, opts *Options) string
- func Ptr[T any](value T) *T
- func ResolveImageURLForLLM(imageURL string) string
- func ResolveImageURLForOllama(imageURL string) []byte
- func SignatureFor(protocol API, tagged string) string
- func StringPtr(s string) *string
- func TagSignature(protocol API, signature string) string
- func TruncateForDebug(s string, maxRunes int) string
- func WithLLMTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc)
- type API
- type AnthropicMessagesCompat
- type AnthropicMessagesSettings
- type AnthropicThinkingMode
- type AuthFunc
- type Batch
- type BatchLimits
- type CacheControlMarker
- type CacheRetention
- type Credentials
- type Delta
- type EmbedImage
- type EmbedInputType
- type Embedder
- type EmbeddingAPI
- type EmbeddingImageFormat
- type EmbeddingsCompat
- type EmbeddingsSettings
- type Endpoint
- func (e Endpoint) Do(req *http.Request) (*http.Response, error)
- func (e Endpoint) NewRequest(ctx context.Context, url string, body any, stream bool) (*http.Request, []byte, error)
- func (e Endpoint) PostJSON(ctx context.Context, url string, body, out any) error
- func (e Endpoint) PostJSONWithRetry(ctx context.Context, url string, body, out any, policy RetryPolicy, ...) error
- func (e Endpoint) PostMultipartWithRetry(ctx context.Context, url string, body []byte, contentType string, out any, ...) error
- func (e Endpoint) Resolve(defaultPath string) string
- type FormField
- type FormFile
- type FunctionCall
- type FunctionDef
- type GoogleGenerativeAICompat
- type GoogleGenerativeAISettings
- type GoogleThinkingMode
- type HTTPError
- type ImageEmbedder
- type ImageInput
- type ImageReranker
- type ImageURL
- type JSONFieldExtractor
- type Message
- type MessageContentPart
- type MessageKind
- type OpenAICompletionsCompat
- type OpenAICompletionsSettings
- type OpenAIResponsesCompat
- type OpenAIResponsesSettings
- type OpenAIUsage
- type Options
- type ReasoningEffort
- type RerankAPI
- type RerankCompat
- type RerankResult
- type RerankSettings
- type Reranker
- type RetryPolicy
- type SSEEvent
- type SSEReader
- type SandboxFileProgress
- type ScoreScale
- type StreamAssembler
- func (a *StreamAssembler) Aborted() bool
- func (a *StreamAssembler) Emit(ch chan<- types.StreamResponse, content string)
- func (a *StreamAssembler) End(ch chan<- types.StreamResponse)
- func (a *StreamAssembler) EndAtEOF(ch chan<- types.StreamResponse)
- func (a *StreamAssembler) Fail(ch chan<- types.StreamResponse, err error)
- func (a *StreamAssembler) Finish(ch chan<- types.StreamResponse)
- func (a *StreamAssembler) OrderedToolCalls() []types.LLMToolCall
- func (a *StreamAssembler) Process(ch chan<- types.StreamResponse, d Delta)
- func (a *StreamAssembler) ReplaceToolCalls(calls []types.LLMToolCall)
- func (a *StreamAssembler) SetToolCallMetadata(index int, metadata types.ToolCallMetadata)
- func (a *StreamAssembler) SetUsage(u types.TokenUsage)
- func (a *StreamAssembler) ToolCallCount() int
- type StreamPacketDumper
- func (d *StreamPacketDumper) Close()
- func (d *StreamPacketDumper) Path() string
- func (d *StreamPacketDumper) WriteError(message string)
- func (d *StreamPacketDumper) WriteHTTPError(statusCode int, body []byte)
- func (d *StreamPacketDumper) WritePacket(v any)
- func (d *StreamPacketDumper) WritePacketRaw(raw []byte)
- type ThinkingEmitter
- type ThinkingFormat
- type ThinkingLevelMap
- type Tool
- type ToolCall
- type ToolCallDelta
- type Transcriber
- type Transcription
- type TranscriptionAPI
- type TranscriptionRequest
- type TranscriptionSegment
- type TranscriptionsCompat
- type TranscriptionsSettings
- type TransportError
Constants ¶
const ( // LanguageForm is a multipart field named language (OpenAI's shape, // ISO-639-1). LanguageForm = "form" // LanguageHeader is an HTTP request header named language (MiniMax, // BCP-47). LanguageHeader = "header" // LanguageASROptions is asr_options.language in a chat-served request // body (Alibaba, Xiaomi). LanguageASROptions = "asr_options" )
Where a transcription protocol puts the operator's language hint. Each vendor documents one place, or none.
Variables ¶
var ( DefaultChatTimeout = envDurationSeconds("WEKNORA_LLM_CHAT_TIMEOUT_SECONDS", 300*time.Second) DefaultStreamTimeout = envDurationSeconds("WEKNORA_LLM_STREAM_TIMEOUT_SECONDS", 600*time.Second) )
LLM 调用超时配置。仅作为"上层未设置 deadline 时"的兜底,避免 hung 请求 永久阻塞 worker。如果上层 ctx 已经设置了 deadline(无论比默认更短还是更长), 都会原样尊重,不再叠加默认超时。可通过环境变量覆盖:
- WEKNORA_LLM_CHAT_TIMEOUT_SECONDS 非流式调用兜底超时(默认 600s)
- WEKNORA_LLM_STREAM_TIMEOUT_SECONDS 流式调用兜底超时(默认 1800s)
var AllReasoningEfforts = append([]ReasoningEffort{ReasoningOff, ReasoningAuto}, ReasoningLadder...)
AllReasoningEfforts is every accepted value, in UI order.
var HTTPClient = secutils.NewSSRFSafeHTTPClientWithTransport( secutils.SSRFSafeHTTPClientConfig{Timeout: 0, MaxRedirects: 10}, httpTransport, )
HTTPClient is the shared SSRF-safe client every protocol uses.
var LocalImageResolver func(storageURL string) ([]byte, bool)
LocalImageResolver resolves a resource:// or provider storage URL to bytes using the owning tenant's storage config. The application layer sets it at startup. Stored local:// URLs are relative to the storage base dir and do NOT encode the tenant's configured PathPrefix, so a plain env-based join would miss the prefix. When nil (e.g. in tests), callers fall back to the env-based LOCAL_STORAGE_BASE_DIR resolution below.
var ReasoningLadder = []ReasoningEffort{ ReasoningMinimal, ReasoningLow, ReasoningMedium, ReasoningHigh, ReasoningXHigh, ReasoningMax, }
ReasoningLadder lists the graded levels from weakest to strongest. Off and Auto are deliberately excluded: they are switches, not intensities.
Functions ¶
func ApplyCacheControlBreakpoints ¶
func ApplyCacheControlBreakpoints(payload map[string]any, marker *CacheControlMarker)
ApplyCacheControlBreakpoints injects Anthropic-style cache_control markers into an OpenAI-compatible JSON body: the first instruction message, the last tool definition and the last conversation message.
func AttachSessionAffinityHeaders ¶
AttachSessionAffinityHeaders sets the sticky-routing headers OpenAI-style gateways use to keep one conversation on one cache shard.
func BuildPromptCacheKey ¶
BuildPromptCacheKey derives an opaque process-local coordination key. Tenant and model identifiers are hashed rather than retained in memory.
func ClampPromptCacheKey ¶
ClampPromptCacheKey trims a routing key to the 64 characters OpenAI accepts.
func EncodeMultipart ¶
EncodeMultipart writes fields and one file into a multipart/form-data body and returns it with its Content-Type. It is encoded once: those bytes are what a signing vendor hashes and what every retry sends again.
The file part carries a filename and no Content-Type of its own. Servers identify the format from the extension then — OpenAI asks for "an extension-bearing filename", and vox-box (GPUStack's audio backend) falls back to guessing from it — whereas a guessed type that a server does not list is rejected outright.
func FingerprintPromptPrefix ¶
FingerprintPromptPrefix returns a short, non-reversible identifier suitable for logs and cache routing. Raw prompts must never be used as metric labels.
func IsMultimodalNotSupportedError ¶
IsMultimodalNotSupportedError checks if an error indicates the model does not support multimodal/image input.
The status is read off the error, never matched as text: HTTPError.Error() prints "status 400" for every 400, and vendor bodies carry "400" inside unrelated numbers ("max 4000 px"), so a substring test turned any failure that merely mentions an image into a "model is not multimodal" verdict and silently retried it stripped.
func IsSandboxMutationTool ¶
IsSandboxMutationTool reports whether a tool name writes sandbox files.
func LogRequest ¶
LogRequest emits the standard request log line with image payloads compacted so data URIs do not flood the log.
func LogUsage ¶
func LogUsage(ctx context.Context, model string, u *types.TokenUsage)
LogUsage emits the standard "[LLM Usage]" line shared by every Chat implementation. It is a no-op when usage is nil so callers can pass through optional usage blocks without guarding at each call site.
func PlaceEmbeddings ¶
PlaceEmbeddings puts returned vectors back in the order the texts were sent, using the index each vendor reports, and refuses a response that does not cover every input.
Both halves matter. A vendor is free to answer out of order, so the index has to be honoured rather than assumed — and reading the wrong field for it silently collapses a whole batch onto slot 0, which is what Tencent/WeKnora#3484 was. An unfilled slot then reaches the index as an empty vector, where it is stored and poisons retrieval without anything failing, so a gap is an error instead. So is an index reported twice: one of the two vectors belongs to some other input.
func PromptPrefixFingerprint ¶
PromptPrefixFingerprint hashes the stable portion common to normal chat and agent requests: leading system messages plus the deterministic tool schema. Dynamic conversation/user messages intentionally do not participate.
func ResolveImageURLForLLM ¶
ResolveImageURLForLLM converts stored image paths to a format that LLM APIs can consume. - data: URIs and http(s):// URLs are returned as-is. - resource:// and provider-backed local paths are read through the application resolver and converted to base64 data URIs.
func ResolveImageURLForOllama ¶
ResolveImageURLForOllama converts stored image paths to raw bytes for the Ollama API.
func SignatureFor ¶
SignatureFor returns the raw signature when it was issued by protocol, and "" for signatures from another protocol or without a protocol tag.
func TagSignature ¶
TagSignature records which protocol issued a reasoning signature. Stored signatures are opaque to every other provider, so they must only be replayed to the protocol that produced them.
func TruncateForDebug ¶
TruncateForDebug shortens a string for log previews.
func WithLLMTimeout ¶
WithLLMTimeout 仅在上层 ctx 没有 deadline 时附加一个兜底超时; 如果上层已显式设置 deadline(无论更短或更长),则原样返回, 让调用方对自己的超时策略拥有最终决定权。
Types ¶
type API ¶
type API string
API identifies a wire protocol. It is the value of the "api" field in a vendor's models.json and decides which protocol package talks to the endpoint.
const ( // APIOpenAICompletions is the OpenAI Chat Completions protocol, the // lingua franca of almost every third-party vendor. APIOpenAICompletions API = "openai-completions" // APIOpenAIResponses is the OpenAI Responses protocol. APIOpenAIResponses API = "openai-responses" // APIAnthropicMessages is the Anthropic Messages protocol, also exposed by // MiniMax, Zhipu and Moonshot as a compatibility surface. APIAnthropicMessages API = "anthropic-messages" // APIGoogleGenerativeAI is the native Gemini generateContent protocol. APIGoogleGenerativeAI API = "google-generative-ai" // APIOllama is the local Ollama chat protocol. APIOllama API = "ollama" )
type AnthropicMessagesCompat ¶
type AnthropicMessagesCompat struct {
ThinkingMode *AnthropicThinkingMode `json:"thinking_mode,omitempty"`
ThinkingOffType *string `json:"thinking_off_type,omitempty"`
SupportsEffort *bool `json:"supports_effort,omitempty"`
ThinkingBudgets map[ReasoningEffort]int `json:"thinking_budgets,omitempty"`
DefaultMaxTokens *int `json:"default_max_tokens,omitempty"`
SupportsTemperature *bool `json:"supports_temperature,omitempty"`
TemperatureWithThinking *bool `json:"temperature_with_thinking,omitempty"`
SupportsTopP *bool `json:"supports_top_p,omitempty"`
SupportsCacheControl *bool `json:"supports_cache_control,omitempty"`
SupportsCacheControlOnTool *bool `json:"supports_cache_control_on_tools,omitempty"`
LongCacheTTL *string `json:"long_cache_ttl,omitempty"`
Version *string `json:"version,omitempty"`
BetaHeaders []string `json:"beta_headers,omitempty"`
InterleavedThinkingBeta *string `json:"interleaved_thinking_beta,omitempty"`
PromptCacheAccounting *bool `json:"prompt_cache_accounting,omitempty"`
ExtraBody map[string]any `json:"extra_body,omitempty"`
}
AnthropicMessagesCompat is the overlay for the Messages protocol.
type AnthropicMessagesSettings ¶
type AnthropicMessagesSettings struct {
ThinkingMode AnthropicThinkingMode
// ThinkingOffType is the thinking.type sent to turn thinking off in
// adaptive mode; empty means "disabled". Claude Sonnet 5.5 rejects
// "disabled" and turns off up-front thinking with "between_tools".
ThinkingOffType string `json:",omitempty"`
SupportsEffort bool
// ThinkingBudgets maps graded levels to budget_tokens for budget mode.
ThinkingBudgets map[ReasoningEffort]int
// DefaultMaxTokens is used when the caller set no budget (max_tokens is
// mandatory on this protocol).
DefaultMaxTokens int
SupportsTemperature bool
TemperatureWithThinking bool
SupportsTopP bool
SupportsCacheControl bool
SupportsCacheControlOnTool bool
LongCacheTTL string
Version string
BetaHeaders []string
// InterleavedThinkingBeta is added to anthropic-beta when thinking and
// tools are both active (budget mode only). Empty disables it.
InterleavedThinkingBeta string
PromptCacheAccounting bool
ExtraBody map[string]any
}
AnthropicMessagesSettings is the resolved Messages configuration.
func DefaultAnthropicMessages ¶
func DefaultAnthropicMessages() AnthropicMessagesSettings
DefaultAnthropicMessages is the anthropic.com baseline for the budget-thinking generation of models.
type AnthropicThinkingMode ¶
type AnthropicThinkingMode string
AnthropicThinkingMode selects the thinking request shape.
const ( // AnthropicThinkingBudget sends {"type":"enabled","budget_tokens":N}. AnthropicThinkingBudget AnthropicThinkingMode = "budget" // AnthropicThinkingAdaptive sends {"type":"adaptive"} and steers the // intensity through output_config.effort. AnthropicThinkingAdaptive AnthropicThinkingMode = "adaptive" )
type AuthFunc ¶
AuthFunc stamps credentials onto an outbound request. body is the exact bytes being sent so signing vendors can hash them.
func BearerAuth ¶
BearerAuth is the default: Authorization: Bearer <key>.
func HeaderAuth ¶
HeaderAuth writes the key under an arbitrary header (api-key for Azure, x-api-key for Anthropic, x-goog-api-key for Gemini).
type Batch ¶
Batch is one slice of the input, and where it started.
func SplitBatches ¶
func SplitBatches(items []string, fixedRunes int, limits BatchLimits) ([]Batch, error)
SplitBatches divides items into requests that satisfy limits. fixedRunes is charged to every batch (the query, which each request repeats).
A single item that cannot fit on its own is an error rather than a silent truncation: the caller asked for this document to be scored, and scoring a prefix of it returns a number for something the user never sent.
type BatchLimits ¶
type BatchLimits struct {
// MaxItems caps how many documents one request may carry.
MaxItems int
// MaxItemRunes caps a single document. Vendors state these in characters
// or tokens; runes are the closest thing we can count without a
// tokenizer, and undercounting is the safe direction.
MaxItemRunes int
// MaxTotalRunes caps the whole request, query included.
MaxTotalRunes int
}
BatchLimits are the per-request ceilings a vendor documents. A zero field means the vendor states no limit, and nothing is enforced for it.
type CacheControlMarker ¶
CacheControlMarker is the Anthropic-style cache breakpoint object that several OpenAI-compatible gateways (OpenRouter, DashScope) also accept.
func CacheControlFor ¶
func CacheControlFor(retention CacheRetention, longTTL string) *CacheControlMarker
CacheControlFor builds the marker for a retention preference, or nil when the caller disabled caching for this request.
type CacheRetention ¶
type CacheRetention string
CacheRetention is the prompt-cache TTL preference. Empty means short (the default 5-minute provider cache). Compaction/summarization uses none so a different prompt prefix does not occupy the session's cache slot.
const ( CacheRetentionNone CacheRetention = "none" CacheRetentionShort CacheRetention = "short" CacheRetentionLong CacheRetention = "long" )
Cache retention preferences.
func ResolveCacheRetention ¶
func ResolveCacheRetention(opts *Options) CacheRetention
ResolveCacheRetention returns the caller's retention preference, defaulting to the provider's short cache.
type Credentials ¶
Credentials is what the operator stored for one model row.
type Delta ¶
type Delta struct {
Reasoning string
Content string
ToolCalls []ToolCallDelta
FinishReason string
}
Delta is one protocol-neutral streaming event. A single wire chunk may carry several of these fields at once.
type EmbedImage ¶
EmbedImage is one image to embed. It travels inline rather than as a URL: the object store WeKnora reads images from is usually not reachable from the vendor, and every multimodal vendor in the catalog accepts base64.
func (EmbedImage) Base64 ¶
func (i EmbedImage) Base64() string
Base64 is the image in standard base64, Gemini's inlineData form.
func (EmbedImage) DataURI ¶
func (i EmbedImage) DataURI() string
DataURI is the data:{mime};base64,{data} form Ark, DashScope and Jina document.
type EmbedInputType ¶
type EmbedInputType string
EmbedInputType distinguishes the two sides of a retrieval pair. Several vendors score them differently and want to be told which one they are embedding; the field they want it in differs, so the catalog names it.
const ( // EmbedDocument is text being indexed. EmbedDocument EmbedInputType = "document" // EmbedQuery is text being searched with. EmbedQuery EmbedInputType = "query" )
type Embedder ¶
type Embedder interface {
Embed(ctx context.Context, texts []string, kind EmbedInputType) ([][]float32, error)
}
Embedder is what every embedding protocol package implements. Callers pass the whole batch; splitting it to the vendor's documented ceiling is the shared layer's job, not the protocol's.
type EmbeddingAPI ¶
type EmbeddingAPI string
EmbeddingAPI names an embedding wire protocol. Like RerankAPI it is its own type, so a chat row's extra_config.api cannot name an embedding dialect and pass validation.
const ( // EmbeddingOpenAI is POST {base}/embeddings with {model, input[]} answering // {data: [{embedding, index}]} — the shape OpenAI defined and every // compatible gateway copied. Jina, NVIDIA, Azure and WeKnora Cloud speak // it too, with their own optional fields, URL or credential. EmbeddingOpenAI EmbeddingAPI = "openai-embeddings" // EmbeddingDashScope is Alibaba Model Studio's native multimodal shape: // input.contents, parameters.dimension, output.embeddings. EmbeddingDashScope EmbeddingAPI = "dashscope-embeddings" // EmbeddingArk is Volcengine Ark's multimodal shape, which fuses every // input into one vector and therefore embeds one text per request. EmbeddingArk EmbeddingAPI = "ark-embeddings" // EmbeddingGoogle is Gemini's batchEmbedContents. EmbeddingGoogle EmbeddingAPI = "google-embeddings" )
The embedding protocols WeKnora speaks.
func (EmbeddingAPI) Known ¶
func (a EmbeddingAPI) Known() bool
Known reports whether the value names a protocol this build implements.
type EmbeddingImageFormat ¶
type EmbeddingImageFormat string
EmbeddingImageFormat is how an image travels on the OpenAI embedding shape, which has no standard image input of its own.
const ( // EmbeddingImageObject puts {ImageField: data URI} in `input`, as Jina // and SGLang document. EmbeddingImageObject EmbeddingImageFormat = "object" // EmbeddingImageMessages sends a chat conversation in `messages` instead // of `input`, which is how vLLM serves multimodal embedding models // (https://docs.vllm.ai/en/latest/models/pooling_models/embed/). Each // conversation yields one vector; BatchMessages can batch conversations. EmbeddingImageMessages EmbeddingImageFormat = "messages" )
func (EmbeddingImageFormat) Known ¶
func (f EmbeddingImageFormat) Known() bool
Known reports whether f is a format this build can send; empty is known.
type EmbeddingsCompat ¶
type EmbeddingsCompat struct {
// API overrides the vendor's embedding protocol for one model. Aliyun and
// Volcengine each serve two: a text endpoint in the OpenAI shape and a
// multimodal one of their own, chosen by which model the row names.
API *EmbeddingAPI `json:"api,omitempty"`
Path *string `json:"path,omitempty"`
SendEncodingFormat *bool `json:"send_encoding_format,omitempty"`
DimensionsField *string `json:"dimensions_field,omitempty"`
TruncateField *string `json:"truncate_field,omitempty"`
TruncateValue *string `json:"truncate_value,omitempty"`
InputTypeField *string `json:"input_type_field,omitempty"`
InputTypeValues map[string]string `json:"input_type_values,omitempty"`
MaxBatchSize *int `json:"max_batch_size,omitempty"`
MaxInputChars *int `json:"max_input_chars,omitempty"`
// AcceptsTruncatePromptTokens marks a vLLM-class runtime, the only kind
// that implements the `truncate_prompt_tokens` extension.
AcceptsTruncatePromptTokens *bool `json:"accepts_truncate_prompt_tokens,omitempty"`
RequestTimeout *int `json:"request_timeout_seconds,omitempty"`
ExtraBody map[string]any `json:"extra_body,omitempty"`
ImageField *string `json:"image_field,omitempty"`
MaxImageBatchSize *int `json:"max_image_batch_size,omitempty"`
MaxImageBytes *int `json:"max_image_bytes,omitempty"`
ImageMIMETypes []string `json:"image_mime_types,omitempty"`
ImageFormat *EmbeddingImageFormat `json:"image_format,omitempty"`
ImagePrompt *string `json:"image_prompt,omitempty"`
TextAsMessages *bool `json:"text_as_messages,omitempty"`
BatchMessages *bool `json:"batch_messages,omitempty"`
}
EmbeddingsCompat is the overlay form (every field optional) of the embedding settings. JSON keys are the documented names used in models.json and config/models.json.
type EmbeddingsSettings ¶
type EmbeddingsSettings struct {
// API is the protocol this model speaks, which may differ from the
// vendor's default.
API EmbeddingAPI
// Path is appended to the base URL; vendors whose default base URL names
// the full endpoint leave it empty.
Path string
// SendEncodingFormat sends encoding_format: "float". OpenAI documents it;
// several compatible gateways do not list it at all.
SendEncodingFormat bool
// DimensionsField carries the requested vector width: "dimensions" on the
// OpenAI shape, "dimension" on DashScope (nested under parameters),
// "outputDimensionality" on Gemini, and empty where the vendor does not
// let a request choose. It is sent only when the row opted in with
// supports_dimension_override; the field name is the vendor's fact, the
// decision to narrow the vector is the operator's.
DimensionsField string
// TruncateField and TruncateValue are the vendor's server-side truncation
// switch for over-long input: a boolean on Jina, an enum on NIM. Empty
// sends nothing.
TruncateField string
TruncateValue string
// InputTypeField names the parameter that distinguishes an indexed
// document from a search query, and InputTypeValues maps the neutral
// EmbedInputType values onto the vendor's vocabulary. Asymmetric
// models score the two sides differently and are measurably worse when
// both are embedded the same way.
InputTypeField string
InputTypeValues map[string]string
// MaxBatchSize and MaxInputChars are the documented per-request ceilings.
MaxBatchSize int
MaxInputChars int
// AcceptsTruncatePromptTokens reports a vLLM-class runtime. The extension
// appears in no managed vendor's schema, so it must never be sent to one.
AcceptsTruncatePromptTokens bool
// TruncatePromptTokens is the budget the operator opted into on this row,
// honoured only where the vendor accepts the extension.
TruncatePromptTokens int
// RequestTimeout caps one request, in seconds. 0 leaves the client
// without its own deadline and lets the caller's context govern.
RequestTimeout int
ExtraBody map[string]any
// ImageInput is how this endpoint takes images: on the OpenAI shape, the
// key of the input object that carries one ("image" on Jina; that shape
// has no standard image input, so an endpoint that names none takes no
// images), plus the documented per-request and per-image limits.
ImageInput
// ImageFormat chooses between ImageField's object in `input` and a chat
// conversation in `messages`. Empty means object when ImageField is set.
ImageFormat EmbeddingImageFormat `json:",omitempty"`
// ImagePrompt is the text sent beside each image in the messages format;
// some chat templates (VLM2Vec's) expect an instruction there. Empty
// sends the image alone.
ImagePrompt string `json:",omitempty"`
// TextAsMessages sends texts in the messages format too. A model whose
// chat template frames its inputs only places text and images in the same
// space when both pass through it; a plain `input` skips the template.
TextAsMessages bool `json:",omitempty"`
// BatchMessages enables independent conversations in a two-dimensional
// messages array (vLLM 0.29 supports this). False preserves the one-input
// request shape for older servers. Single inputs always keep that shape.
BatchMessages bool `json:",omitempty"`
}
EmbeddingsSettings is the resolved (fully defaulted) form.
func DefaultEmbeddings ¶
func DefaultEmbeddings() EmbeddingsSettings
DefaultEmbeddings is the protocol baseline, and it is deliberately bare: `model` and `input` are the only two fields every vendor in this catalog documents. The rest disagree — NVIDIA NIM and Volcengine's text endpoint have no `dimensions` at all, Zhipu has no `encoding_format`, and the parameter that separates a query from a document is spelled three different ways. A vendor that documents one declares it; nothing is sent on the assumption that an OpenAI-shaped endpoint accepts every OpenAI field.
The one non-wire default is the request deadline: every pre-catalog embedding client carried 60 seconds.
func (EmbeddingsSettings) BatchLimits ¶
func (s EmbeddingsSettings) BatchLimits() BatchLimits
BatchLimits renders the documented ceilings for SplitBatches.
func (EmbeddingsSettings) InputTypeValue ¶
func (s EmbeddingsSettings) InputTypeValue(kind EmbedInputType) string
InputTypeValue maps a neutral input kind onto the vendor's vocabulary, returning "" when this vendor does not distinguish the two sides.
func (EmbeddingsSettings) OpenAIImageFormat ¶
func (s EmbeddingsSettings) OpenAIImageFormat() EmbeddingImageFormat
OpenAIImageFormat is the effective image format on the OpenAI shape, empty when the endpoint takes no images there.
type Endpoint ¶
type Endpoint struct {
// BaseURL is the vendor root without a trailing slash.
BaseURL string
// URL, when set, is the complete request URL and overrides the protocol
// default of BaseURL + protocol path. Vendors with non-standard paths
// (Azure deployments, WeKnora Cloud) set it.
URL string
// Query is appended to the final URL (Azure api-version).
Query map[string]string
// Model is the name sent on the wire; ModelID is WeKnora's own identifier.
Model string
ModelID string
// Auth stamps credentials; Headers are static extra headers (vendor
// betas, user-configured custom headers). User headers never override
// the protocol's own reserved headers.
Auth AuthFunc
Headers map[string]string
// Client is the HTTP client; nil uses the shared SSRF-safe client.
Client *http.Client
}
Endpoint is everything a protocol client needs to reach one model.
func (Endpoint) Do ¶
Do sends the request and returns the response. Non-2xx responses are turned into an error carrying the body so callers surface vendor messages.
func (Endpoint) NewRequest ¶
func (e Endpoint) NewRequest(ctx context.Context, url string, body any, stream bool) (*http.Request, []byte, error)
NewRequest prepares an authenticated JSON POST. The body is marshalled once so signing vendors see exactly what is sent.
func (Endpoint) PostJSON ¶
PostJSON sends one authenticated JSON request and decodes the reply into out. It is the whole round-trip for the non-streaming protocols (rerank, embeddings), which have no SSE to assemble.
It never returns a nil error with nothing decoded: every failure path — marshalling, SSRF, transport, non-2xx, decoding — returns an error, so a caller cannot mistake an empty result for a successful empty answer.
func (Endpoint) PostJSONWithRetry ¶
func (e Endpoint) PostJSONWithRetry( ctx context.Context, url string, body, out any, policy RetryPolicy, label string, ) error
PostJSONWithRetry sends one authenticated JSON request, retrying transport failures, and decodes the reply into out.
It never returns a nil error without decoding: the eight hand-written retry loops this replaces kept `resp` and `err` in the enclosing scope and returned `(nil, err)` at the end, so writing `req, err := ...` inside the loop shadowed the error, left the outer one nil, and handed the caller a nil response with no error to check — a nil-pointer panic that took the process down instead of reporting "connection refused" (Tencent/WeKnora#3484). Here the last error is captured in the enclosing scope on purpose and the function cannot fall through without it.
Only transport failures are retried, including a reply cut off while it was being read. A non-2xx reply is the vendor answering, and repeating a rejected request neither fixes it nor tells the operator anything new; a reply that arrived whole but does not decode is the same answer every time, and sending it again would bill the request twice.
func (Endpoint) PostMultipartWithRetry ¶
func (e Endpoint) PostMultipartWithRetry( ctx context.Context, url string, body []byte, contentType string, out any, policy RetryPolicy, label string, ) error
PostMultipartWithRetry sends an encoded multipart body, retrying transport failures only, and decodes the JSON reply into out. It has the guarantees of PostJSONWithRetry.
type FunctionCall ¶
type FunctionCall struct {
Name string `json:"name"`
Arguments string `json:"arguments"` // JSON string
}
FunctionCall represents a function call
type FunctionDef ¶
type FunctionDef struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters json.RawMessage `json:"parameters"`
}
FunctionDef represents a function definition
type GoogleGenerativeAICompat ¶
type GoogleGenerativeAICompat struct {
ThinkingMode *GoogleThinkingMode `json:"thinking_mode,omitempty"`
ThinkingBudgets map[ReasoningEffort]int `json:"thinking_budgets,omitempty"`
IncludeThoughts *bool `json:"include_thoughts,omitempty"`
SupportsSeed *bool `json:"supports_seed,omitempty"`
SupportsPenalty *bool `json:"supports_penalty,omitempty"`
ExtraGeneration map[string]any `json:"extra_generation_config,omitempty"`
PromptCacheAcct *bool `json:"prompt_cache_accounting,omitempty"`
APIVersionPrefix *string `json:"api_version_prefix,omitempty"`
}
GoogleGenerativeAICompat is the overlay for the Gemini protocol.
type GoogleGenerativeAISettings ¶
type GoogleGenerativeAISettings struct {
ThinkingMode GoogleThinkingMode
ThinkingBudgets map[ReasoningEffort]int
IncludeThoughts bool
SupportsSeed bool
SupportsPenalty bool
ExtraGeneration map[string]any
PromptCacheAcct bool
// APIVersionPrefix is appended to a bare host base URL ("/v1beta").
APIVersionPrefix string
}
GoogleGenerativeAISettings is the resolved Gemini configuration.
func DefaultGoogleGenerativeAI ¶
func DefaultGoogleGenerativeAI() GoogleGenerativeAISettings
DefaultGoogleGenerativeAI is the generativelanguage.googleapis.com baseline.
type GoogleThinkingMode ¶
type GoogleThinkingMode string
GoogleThinkingMode selects the thinkingConfig shape.
const ( // GoogleThinkingBudget sends thinkingConfig.thinkingBudget (Gemini 2.5). GoogleThinkingBudget GoogleThinkingMode = "budget" // GoogleThinkingLevel sends thinkingConfig.thinkingLevel (Gemini 3+). GoogleThinkingLevel GoogleThinkingMode = "level" // GoogleThinkingNone sends no thinkingConfig. GoogleThinkingNone GoogleThinkingMode = "none" )
type HTTPError ¶
type HTTPError struct {
StatusCode int
Body string
// Header is the reply's headers, kept so a retry can honour the vendor's
// Retry-After on a 429 or 503 instead of guessing its own backoff.
Header http.Header
}
HTTPError is a non-2xx vendor reply.
func (*HTTPError) RetryAfter ¶
RetryAfter is how long the vendor asked the caller to wait before trying again, from the Retry-After header in either of its two forms (delay in seconds or an HTTP date). It is zero when the header is absent, malformed or already in the past.
type ImageEmbedder ¶
type ImageEmbedder interface {
// AcceptsImages reports whether this endpoint can carry an image at all.
AcceptsImages() bool
EmbedImages(ctx context.Context, images []EmbedImage, kind EmbedInputType) ([][]float32, error)
}
ImageEmbedder is implemented by the protocols that can carry an image. Whether a given model maps images into the space of its text vectors is the catalog entry's input, not the protocol's, so the caller checks that first. Callers pass a batch within EmbeddingsSettings.ImageBatchLimit.
type ImageInput ¶
type ImageInput struct {
// ImageField is the key of the object that carries an image on a shape
// with no standard image input ("image" on Jina). Protocols whose schema
// fixes the image part ignore it.
ImageField string `json:",omitempty"`
// MaxImageBatchSize is the documented number of images per request.
// 0 means one: a vendor that fuses its inputs, or does not say, must not
// be sent several.
MaxImageBatchSize int `json:",omitempty"`
// MaxImageBytes is the documented size limit of one image, 0 when the
// vendor states none. The caller shrinks an image to fit; the client
// refuses one that does not rather than spend a request on it.
MaxImageBytes int `json:",omitempty"`
// ImageMIMETypes lists the formats the vendor documents, empty when it
// takes any common one.
ImageMIMETypes []string `json:",omitempty"`
}
ImageInput is how an endpoint takes images, shared by the embedding and rerank settings. Its fields are flattened into both, so the compat keys read the same on either: image_field, max_image_batch_size, max_image_bytes and image_mime_types.
func (ImageInput) CheckImage ¶
func (s ImageInput) CheckImage(img EmbedImage) error
CheckImage reports an image the vendor documents it will not take.
func (ImageInput) ImageBatchLimit ¶
func (s ImageInput) ImageBatchLimit() int
ImageBatchLimit is the number of images one request may carry.
type ImageReranker ¶
type ImageReranker interface {
// AcceptsImages reports whether this endpoint can carry an image at all.
AcceptsImages() bool
RerankImages(ctx context.Context, query string, images []EmbedImage) ([]RerankResult, error)
}
ImageReranker is implemented by the rerank protocols that can carry an image document. Whether a given model scores images is its catalog entry's input, not the protocol's, so the caller checks that first. The images go in a request of their own, at most RerankSettings.ImageBatchLimit of them; result indices refer to the images slice.
type ImageURL ¶
type ImageURL struct {
URL string `json:"url"` // URL or base64 data URI
Detail string `json:"detail,omitempty"` // "auto", "low", "high"
}
ImageURL represents the image URL structure
type JSONFieldExtractor ¶
type JSONFieldExtractor struct {
// contains filtered or unexported fields
}
JSONFieldExtractor extracts a specific string field value from streaming JSON fragments. It processes incremental JSON argument chunks from LLM tool calls.
Example: for fieldName="answer", expected JSON format: {"answer":"...content..."} The extractor uses a simple state machine to skip the JSON prefix and extract the string value.
func NewJSONFieldExtractor ¶
func NewJSONFieldExtractor(fieldName string) *JSONFieldExtractor
NewJSONFieldExtractor creates a new extractor instance for the given field name
func (*JSONFieldExtractor) Feed ¶
func (e *JSONFieldExtractor) Feed(argsDelta string) string
Feed processes a new argument delta and returns any new content to emit. Returns empty string if no new content is available yet.
func (*JSONFieldExtractor) IsDone ¶
func (e *JSONFieldExtractor) IsDone() bool
IsDone returns whether the extractor has finished (closing quote found)
type Message ¶
type Message struct {
Role string `json:"role"` // 角色:system, user, assistant, tool
Content string `json:"content"` // 消息内容
MultiContent []MessageContentPart `json:"multi_content,omitempty"` // 多内容消息(文本+图片)
Name string `json:"name,omitempty"` // Function/tool name (for tool role)
ToolCallID string `json:"tool_call_id,omitempty"` // Tool call ID (for tool role)
ToolCalls []ToolCall `json:"tool_calls,omitempty"` // Tool calls (for assistant role)
// Images are image URLs for multimodal input (current user message only).
Images []string `json:"images,omitempty"`
// ReasoningContent 是 assistant 推理类模型上一轮输出的思考内容。部分供应商
// (MiMo、DeepSeek V3.2+、Kimi K2.5+)要求多轮对话中把 assistant 的
// reasoning_content 原样回传,否则会以 400 拒绝请求;其他不要求的供应商会
// 忽略未知字段。Anthropic 则要求把 thinking block 连同签名一起回放。
ReasoningContent string `json:"reasoning_content,omitempty"`
// ReasoningSignature is the provider-issued signature that must accompany
// ReasoningContent when it is replayed (Anthropic thinking blocks, Gemini
// thought signatures on text parts). Empty when the provider issues none.
ReasoningSignature string `json:"reasoning_signature,omitempty"`
// ReasoningMetadata carries opaque provider state that must round-trip
// with the assistant turn but has no protocol-neutral representation:
// OpenAI Responses reasoning items (encrypted_content), OpenRouter
// reasoning_details, and so on. Keyed by protocol / vendor namespace.
ReasoningMetadata types.ProviderMetadata `json:"reasoning_metadata,omitempty"`
// Kind is engine-internal bookkeeping. `json:"-"` keeps it off the wire:
// providers reject unknown message fields on some endpoints, and this one
// means nothing to them anyway.
Kind MessageKind `json:"-"`
// TurnID is the stored assistant message whose turn this history message
// was replayed from. It is empty for the live turn and for messages the
// engine synthesized. Compaction uses it to tell whether a summary ends
// exactly on a stored turn, the only kind it can persist for later turns.
// Engine-internal like Kind, and kept off the wire for the same reason.
TurnID string `json:"-"`
}
Message 表示聊天消息
func NeutralizeMessageSpecialTokens ¶
NeutralizeMessageSpecialTokens returns a copy of the message with chat template delimiters broken so tokenizers treat them as data.
func StripImagesFromMessages ¶
StripImagesFromMessages returns a copy of messages with all image data removed.
Images travel in two shapes: the Images list (chat history, Ollama) and image_url parts inside MultiContent, which is what the remote VLM path and every assembled multimodal turn actually send. Clearing only the first left the retry sending the identical request, so the "retry without images" fallback never recovered anything on those paths.
type MessageContentPart ¶
type MessageContentPart struct {
Type string `json:"type"` // "text" or "image_url"
Text string `json:"text,omitempty"` // For type="text"
ImageURL *ImageURL `json:"image_url,omitempty"` // For type="image_url"
}
MessageContentPart represents a part of multi-content message
type MessageKind ¶
type MessageKind string
MessageKind marks messages the engine synthesized rather than received from the user or the model. Compaction needs to tell its own summary apart from a real user turn: a summary that looks like ordinary history gets fed back into the next summarization pass and degrades into a summary of a summary.
const MessageKindCompactionSummary MessageKind = "compaction_summary"
MessageKindCompactionSummary marks the message that replaces compacted history. It carries the `user` role because that is where providers expect conversation history, so the role alone cannot identify it.
type OpenAICompletionsCompat ¶
type OpenAICompletionsCompat struct {
MaxTokensField *string `json:"max_tokens_field,omitempty"`
ThinkingFormat *ThinkingFormat `json:"thinking_format,omitempty"`
ThinkingEnabledValue *string `json:"thinking_enabled_value,omitempty"`
ThinkingAlwaysSend *bool `json:"thinking_always_send,omitempty"`
ThinkingDisableOnNonStream *bool `json:"thinking_disable_on_non_stream,omitempty"`
ThinkingBudgetField *string `json:"thinking_budget_field,omitempty"`
ThinkingBudgetExcludesEffort *bool `json:"thinking_budget_excludes_effort,omitempty"`
ReasoningEffortField *string `json:"reasoning_effort_field,omitempty"`
SupportsReasoningEffort *bool `json:"supports_reasoning_effort,omitempty"`
SupportsDeveloperRole *bool `json:"supports_developer_role,omitempty"`
SupportsStore *bool `json:"supports_store,omitempty"`
SupportsUsageInStreaming *bool `json:"supports_usage_in_streaming,omitempty"`
SupportsTemperature *bool `json:"supports_temperature,omitempty"`
FixedTemperature *float64 `json:"fixed_temperature,omitempty"`
SupportsSeed *bool `json:"supports_seed,omitempty"`
ToolChoiceModes []string `json:"tool_choice_modes,omitempty"`
SupportsParallelToolCalls *bool `json:"supports_parallel_tool_calls,omitempty"`
SupportsResponseFormat *bool `json:"supports_response_format,omitempty"`
SupportsMultiContent *bool `json:"supports_multi_content,omitempty"`
ReplayReasoningContent *bool `json:"replay_reasoning_content,omitempty"`
PromptCacheKey *bool `json:"prompt_cache_key,omitempty"`
CacheControlFormat *string `json:"cache_control_format,omitempty"`
PromptCacheAccounting *bool `json:"prompt_cache_accounting,omitempty"`
ToolCallExtraFields []string `json:"tool_call_extra_fields,omitempty"`
ExtraBody map[string]any `json:"extra_body,omitempty"`
ReasoningFields []string `json:"reasoning_fields,omitempty"`
}
OpenAICompletionsCompat is the overlay form (every field optional) of the Chat Completions settings. JSON keys are the documented names used in models.json and config/models.json.
type OpenAICompletionsSettings ¶
type OpenAICompletionsSettings struct {
// MaxTokensField is "max_tokens" or "max_completion_tokens".
MaxTokensField string
ThinkingFormat ThinkingFormat
// ThinkingEnabledValue is the "type" sent for thinking-type when enabled
// ("enabled" by default; MiniMax M3 uses "adaptive").
ThinkingEnabledValue string
// ThinkingAlwaysSend pins the switch on every request even when the
// caller expressed no preference (DashScope hybrid models require it).
ThinkingAlwaysSend bool
// ThinkingDisableOnNonStream forces the switch off for non-streaming
// calls (Qwen3 rejects thinking without stream).
ThinkingDisableOnNonStream bool
// ThinkingBudgetField carries Options.ThinkingBudgetTokens ("thinking_budget").
ThinkingBudgetField string
// ThinkingBudgetExcludesEffort marks a vendor that rejects a request
// carrying both the budget and the effort (DashScope's qwen3.8-max
// series: "不支持 reasoning_effort 与 thinking_budget 同时设置,同时设置
// 会报错"). The graded level is what the caller actually picked, so the
// budget is the field that yields.
ThinkingBudgetExcludesEffort bool
// ReasoningEffortField is "reasoning_effort" unless a vendor renames it.
ReasoningEffortField string
SupportsReasoningEffort bool
// SupportsDeveloperRole switches the system prompt to the developer role
// on reasoning models.
SupportsDeveloperRole bool
// SupportsStore sends store:false (OpenAI keeps completions otherwise).
SupportsStore bool
SupportsUsageInStreaming bool
// SupportsTemperature false drops every sampling parameter (o-series,
// GPT-5 family, Kimi K2.5+).
SupportsTemperature bool
// FixedTemperature pins the value when the vendor only accepts one.
FixedTemperature *float64
SupportsSeed bool
ToolChoiceModes []string
SupportsParallelToolCalls bool
SupportsResponseFormat bool
// SupportsMultiContent false flattens image/text parts to plain text.
SupportsMultiContent bool
// ReplayReasoningContent sends reasoning_content on prior assistant turns.
ReplayReasoningContent bool
// PromptCacheKey sends prompt_cache_key / prompt_cache_retention and the
// session-affinity headers.
PromptCacheKey bool
// CacheControlFormat "anthropic" injects cache_control breakpoints.
CacheControlFormat string
// PromptCacheAccounting states the vendor reports cache usage at all.
PromptCacheAccounting bool
// ToolCallExtraFields lists tool_call keys to round-trip opaquely
// (Gemini-through-OpenAI "extra_content").
ToolCallExtraFields []string
// ExtraBody is merged into every request body (vendor knobs such as
// enable_search, sampling defaults).
ExtraBody map[string]any
// ReasoningFields are the delta keys that carry thinking text, in
// priority order.
ReasoningFields []string
}
OpenAICompletionsSettings is the resolved (fully defaulted) form.
func DefaultOpenAICompletions ¶
func DefaultOpenAICompletions() OpenAICompletionsSettings
DefaultOpenAICompletions is the protocol baseline: plain OpenAI semantics.
func (OpenAICompletionsSettings) AllowsToolChoice ¶
func (s OpenAICompletionsSettings) AllowsToolChoice(mode string) bool
AllowsToolChoice reports whether a tool_choice mode is accepted.
type OpenAIResponsesCompat ¶
type OpenAIResponsesCompat struct {
SupportsDeveloperRole *bool `json:"supports_developer_role,omitempty"`
SupportsMaxOutputTokens *bool `json:"supports_max_output_tokens,omitempty"`
SupportsReasoningSummary *bool `json:"supports_reasoning_summary,omitempty"`
SupportsEncryptedReasoning *bool `json:"supports_encrypted_reasoning,omitempty"`
SupportsStore *bool `json:"supports_store,omitempty"`
SupportsTemperature *bool `json:"supports_temperature,omitempty"`
PromptCacheKey *bool `json:"prompt_cache_key,omitempty"`
SupportsLongCacheRetention *bool `json:"supports_long_cache_retention,omitempty"`
SupportsParallelToolCalls *bool `json:"supports_parallel_tool_calls,omitempty"`
ExtraBody map[string]any `json:"extra_body,omitempty"`
}
OpenAIResponsesCompat is the overlay for the Responses protocol.
type OpenAIResponsesSettings ¶
type OpenAIResponsesSettings struct {
SupportsDeveloperRole bool
SupportsMaxOutputTokens bool
SupportsReasoningSummary bool
SupportsEncryptedReasoning bool
SupportsStore bool
SupportsTemperature bool
PromptCacheKey bool
SupportsLongCacheRetention bool
SupportsParallelToolCalls bool
ExtraBody map[string]any
}
OpenAIResponsesSettings is the resolved Responses configuration.
func DefaultOpenAIResponses ¶
func DefaultOpenAIResponses() OpenAIResponsesSettings
DefaultOpenAIResponses is the openai.com baseline.
type OpenAIUsage ¶
type OpenAIUsage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
PromptCacheHitTokens *int `json:"prompt_cache_hit_tokens"`
PromptCacheMissTokens *int `json:"prompt_cache_miss_tokens"`
CachedTokens *int `json:"cached_tokens"`
CacheReadInputTokens *int `json:"cache_read_input_tokens"`
CacheCreationInputTokens *int `json:"cache_creation_input_tokens"`
PromptTokensDetails *struct {
CachedTokens *int `json:"cached_tokens"`
CacheWriteTokens *int `json:"cache_write_tokens"`
} `json:"prompt_tokens_details"`
CompletionTokensDetails *struct {
ReasoningTokens int `json:"reasoning_tokens"`
} `json:"completion_tokens_details"`
}
OpenAIUsage is the superset of the usage shapes OpenAI-compatible endpoints return. Vendors disagree on where cache counters live:
- OpenAI / Azure / most gateways: prompt_tokens_details.cached_tokens
- DeepSeek: prompt_cache_hit_tokens / prompt_cache_miss_tokens
- Kimi: top-level cached_tokens
- Anthropic-through-OpenRouter: cache_read_input_tokens / cache_creation_input_tokens
All of them are decoded here so protocol code never guesses per vendor.
func (OpenAIUsage) ToTokenUsage ¶
func (u OpenAIUsage) ToTokenUsage(cacheAccounting bool) types.TokenUsage
ToTokenUsage normalizes the counters. cacheAccounting states whether the vendor documents prompt-cache accounting at all: when it does not, a missing counter means "unsupported" rather than "unreported".
type Options ¶
type Options struct {
Temperature float64 `json:"temperature"` // 温度参数
TopP float64 `json:"top_p"` // Top P 参数
Seed int `json:"seed"` // 随机种子
// MaxTokens and MaxCompletionTokens are aliases for one completion budget.
// Callers may set either; CompletionBudget() prefers MaxCompletionTokens.
// The outbound JSON carries exactly one field, named per vendor.
MaxTokens int `json:"max_tokens"`
MaxCompletionTokens int `json:"max_completion_tokens"`
FrequencyPenalty float64 `json:"frequency_penalty"` // 频率惩罚
PresencePenalty float64 `json:"presence_penalty"` // 存在惩罚
// Thinking is the legacy on/off switch. Prefer ReasoningEffort; when both
// are set ReasoningEffort wins. true maps to ReasoningAuto, false to
// ReasoningOff.
Thinking *bool `json:"thinking"`
// ReasoningEffort selects the thinking intensity. Empty leaves the model
// default untouched (no thinking fields are sent unless the vendor
// requires them on every request).
ReasoningEffort ReasoningEffort `json:"reasoning_effort,omitempty"`
// ThinkingBudgetTokens caps the thinking tokens where the vendor exposes a
// budget (Anthropic budget_tokens, DashScope thinking_budget, Gemini
// thinkingBudget). 0 leaves the vendor default.
ThinkingBudgetTokens int `json:"thinking_budget_tokens,omitempty"`
Tools []Tool `json:"tools,omitempty"` // 可用工具列表
// ToolChoice is "auto", "required", "none" or a specific tool name.
ToolChoice string `json:"tool_choice,omitempty"`
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"` // 是否允许并行工具调用(默认 nil 表示由模型决定)
Format json.RawMessage `json:"format,omitempty"` // 响应格式定义
// PromptCacheKey is the provider routing key (OpenAI prompt_cache_key).
// Empty falls back to the session ID on the call context.
PromptCacheKey string `json:"-"`
// CacheRetention controls provider prompt-cache TTL. none disables cache
// markers; empty/short is the default 5-minute cache; long requests 1h/24h
// where the provider accepts it.
CacheRetention CacheRetention `json:"-"`
}
Options 聊天选项。It is protocol-neutral: every field is a capability the caller asks for, and the protocol package decides how (or whether) the vendor can honour it.
func WithSessionCacheKey ¶
WithSessionCacheKey returns opts with PromptCacheKey filled from the session on ctx when the caller left it empty, so calls made inside a session keep their cache routing key. opts itself is never mutated.
func (*Options) CompletionBudget ¶
CompletionBudget is the single per-call generation cap. MaxTokens and MaxCompletionTokens on Options are input aliases for the same budget (YAML, older callers, and the agent UI all feed one of them). When both are set, the newer MaxCompletionTokens wins.
func (*Options) Reasoning ¶
func (o *Options) Reasoning() (ReasoningEffort, bool)
Reasoning resolves the requested thinking level from ReasoningEffort and the legacy Thinking boolean. The bool result reports whether the caller expressed any preference at all; when false the model default applies.
The stored level is re-parsed here rather than trusted: the write paths validate, but rows persisted before that validation existed, builtin YAML agents and SummaryConfig all reach this struct through a plain string cast. An unparseable value ("hgih") is non-empty, so Enabled() would read it as "thinking on" and the protocol packages would send the vendor a level it never defined. Ignoring it falls back to the legacy boolean, which is what "no usable preference" has always meant.
func (*Options) ThinkingRequested ¶
ThinkingRequested reports whether the caller asked for thinking to be on.
type ReasoningEffort ¶
type ReasoningEffort string
ReasoningEffort is the protocol-neutral thinking level. Vendors map it onto their own vocabulary through a ThinkingLevelMap; the protocol package then emits whichever wire field the vendor documents (reasoning_effort, thinking.type, enable_thinking, thinkingConfig, ...).
const ( // ReasoningOff disables extended thinking where the model allows it. ReasoningOff ReasoningEffort = "off" // ReasoningAuto enables thinking but leaves the intensity to the provider // default. This is what the legacy boolean `thinking: true` maps to. ReasoningAuto ReasoningEffort = "auto" // ReasoningMinimal is the weakest graded level. ReasoningMinimal ReasoningEffort = "minimal" // ReasoningLow is the low graded level. ReasoningLow ReasoningEffort = "low" // ReasoningMedium is the medium graded level. ReasoningMedium ReasoningEffort = "medium" // ReasoningHigh is the high graded level. ReasoningHigh ReasoningEffort = "high" // ReasoningXHigh is the extra-high graded level (OpenAI, Zhipu). ReasoningXHigh ReasoningEffort = "xhigh" // ReasoningMax is the strongest graded level. ReasoningMax ReasoningEffort = "max" )
func ParseReasoningEffort ¶
func ParseReasoningEffort(s string) (ReasoningEffort, bool)
ParseReasoningEffort validates a user-provided level. Empty input yields ("", true) meaning "unset: let the model default apply".
func SanitizeReasoningEffort ¶
func SanitizeReasoningEffort(ctx context.Context, raw, source string) ReasoningEffort
SanitizeReasoningEffort validates a stored or configured level on its way into Options. Callers that read the level out of a database row, a YAML agent or a session config cast a plain string, so this is where a typo is caught and dropped: an unknown level must never reach the vendor, and must never be mistaken for "thinking on". Returning "" means "no preference", leaving the legacy Thinking boolean to decide.
func (ReasoningEffort) Enabled ¶
func (r ReasoningEffort) Enabled() bool
Enabled reports whether the level asks for thinking to be on.
func (ReasoningEffort) Graded ¶
func (r ReasoningEffort) Graded() bool
Graded reports whether the level is one of the intensity rungs.
type RerankAPI ¶
type RerankAPI string
RerankAPI names a rerank wire protocol. It is deliberately a separate type from API, the chat protocol selector: the two vocabularies must not mix, or a chat row whose extra_config.api names a rerank dialect would pass validation and fail at call time.
const ( // RerankCohere is the de-facto standard shape — POST {base}/rerank with // {model, query, documents} and a results array of {index, // relevance_score, document}. Cohere defined it; Jina, Zhipu, // SiliconFlow, Qianfan, GPUStack and every OpenAI-compatible gateway // that serves rerank at all copy it. RerankCohere RerankAPI = "cohere-rerank" // RerankDashScope is Alibaba Model Studio's native shape, which wraps // the same fields in input/parameters and answers under output. RerankDashScope RerankAPI = "dashscope-rerank" // RerankNIM is NVIDIA NIM's retrieval shape: a query object, a passages // array, and rankings carrying an unbounded logit instead of a // probability. RerankNIM RerankAPI = "nim-rerank" // RerankPinecone is Pinecone Inference's standalone /rerank endpoint: // documents are objects and results live under data with a score field. RerankPinecone RerankAPI = "pinecone-rerank" // RerankTEI is the native Text Embeddings Inference shape: POST /rerank // with {query, texts}, answering a bare array of {index, score}. RerankTEI RerankAPI = "tei-rerank" // RerankTencentLKEAP is Tencent Cloud's RunRerank action, reached through // the official SDK because it is TC3-signed rather than key-authenticated. RerankTencentLKEAP RerankAPI = "tencent-lkeap" // RerankVolcengineKnowledge is Volcengine's managed Knowledge Service // rerank, reached through the vikingdb SDK for the same reason. RerankVolcengineKnowledge RerankAPI = "volcengine-knowledge" )
The rerank protocols WeKnora speaks.
func (RerankAPI) HTTPServed ¶
HTTPServed reports whether a protocol package implements the protocol. The SDK-backed ones are built by the rerank package itself, which is where the vendor SDKs are imported.
type RerankCompat ¶
type RerankCompat struct {
Path *string `json:"path,omitempty"`
SendTopN *bool `json:"send_top_n,omitempty"`
SendReturnDocs *bool `json:"send_return_documents,omitempty"`
ScoreScale *ScoreScale `json:"score_scale,omitempty"`
Truncate *string `json:"truncate,omitempty"`
MaxDocuments *int `json:"max_documents,omitempty"`
MaxQueryChars *int `json:"max_query_chars,omitempty"`
MaxDocumentChars *int `json:"max_document_chars,omitempty"`
MaxRequestChars *int `json:"max_request_chars,omitempty"`
MaxConcurrency *int `json:"max_concurrency,omitempty"`
RequestTimeout *int `json:"request_timeout_seconds,omitempty"`
// AcceptsTruncatePromptTokens marks a vLLM-class runtime.
AcceptsTruncatePromptTokens *bool `json:"accepts_truncate_prompt_tokens,omitempty"`
// UnsupportedReason marks a model this build cannot call.
UnsupportedReason *string `json:"unsupported_reason,omitempty"`
ExtraBody map[string]any `json:"extra_body,omitempty"`
ImageField *string `json:"image_field,omitempty"`
MaxImageBatchSize *int `json:"max_image_batch_size,omitempty"`
MaxImageBytes *int `json:"max_image_bytes,omitempty"`
ImageMIMETypes []string `json:"image_mime_types,omitempty"`
}
RerankCompat is the overlay form (every field optional) of the rerank settings. JSON keys are the documented names used in models.json and config/models.json.
type RerankResult ¶
type RerankResult struct {
Index int
Score float64
// Text is the document echoed back, empty when the vendor was not asked
// to return documents. Callers index into their own slice instead of
// relying on it.
Text string
}
RerankResult is one scored document, in the vendor's own score scale. Index refers to the position in the documents slice that was sent.
type RerankSettings ¶
type RerankSettings struct {
// Path is appended to the base URL by protocols that use one. Vendors
// whose default base URL already names the full endpoint leave it empty.
Path string
// SendTopN asks for every document back by naming their count. Omitting
// it means "all", which is what every protocol here does by default.
SendTopN bool
// SendReturnDocs asks the vendor to echo the document text. Callers index
// into their own slice, so this is off unless a vendor needs it.
SendReturnDocs bool
// ScoreScale says what the returned numbers mean. See ScoreScale:
// getting this wrong makes a relevance threshold meaningless.
ScoreScale ScoreScale
// Truncate is the vendor's server-side truncation setting for
// over-long input ("END" on NIM). Empty sends nothing.
Truncate string
// Limits carry the documented per-request ceilings. MaxQueryChars is
// checked on its own rather than through BatchLimits: the query is not an
// item to be split, so an over-long one cannot be made to fit by batching.
MaxDocuments int
MaxQueryChars int
MaxDocumentChars int
MaxRequestChars int
// MaxConcurrency bounds in-flight batches when the input is split. 0
// means the caller's default.
MaxConcurrency int
// RequestTimeout caps one request, in seconds. 0 uses the rerank
// client's default (see rerank.newRerankHTTPClient).
RequestTimeout int
// AcceptsTruncatePromptTokens reports that this vendor is a vLLM-class
// runtime, which is the only kind that implements the
// `truncate_prompt_tokens` extension. It is not part of the Cohere shape
// and appears in no managed vendor's schema, so it must never be sent to
// one: that is how an undocumented field ends up on every request.
AcceptsTruncatePromptTokens bool
// UnsupportedReason is set on a catalog entry naming a rerank dialect no
// protocol package implements. Resolve refuses it rather than letting a
// request go out shaped for a different protocol, which surfaces as a
// decode error far from its cause.
UnsupportedReason string
// TruncatePromptTokens is the budget the operator opted into on this row,
// honoured only where AcceptsTruncatePromptTokens is set. It is a row
// setting rather than a vendor fact because one runtime serves models
// with different context windows. Zero sends nothing.
TruncatePromptTokens int
ExtraBody map[string]any
// ImageInput is how this endpoint takes image documents, for the models
// whose catalog input lists image. Image documents are sent in requests
// of their own, at most ImageBatchLimit per request; each is scored
// against the query on its own, so their scores compare with the text
// documents' as any two batches do.
ImageInput
}
RerankSettings is the resolved (fully defaulted) form.
func DefaultRerank ¶
func DefaultRerank() RerankSettings
DefaultRerank is the protocol baseline: ask for every document, expect a 0..1 relevance score, enforce no ceiling the vendor did not state.
func (RerankSettings) BatchLimits ¶
func (s RerankSettings) BatchLimits() BatchLimits
BatchLimits renders the documented ceilings for SplitBatches.
type Reranker ¶
type Reranker interface {
Rerank(ctx context.Context, query string, documents []string) ([]RerankResult, error)
}
Reranker is what every rerank protocol package implements.
type RetryPolicy ¶
type RetryPolicy struct {
// MaxRetries is the number of retries after the first attempt.
MaxRetries int
// BaseDelay is the wait before the first retry; it doubles each time.
BaseDelay time.Duration
// MaxDelay caps the backoff.
MaxDelay time.Duration
}
RetryPolicy describes how often to retry a failed request and how long to wait between attempts. The zero value performs one attempt and no waiting.
func DefaultRetryPolicy ¶
func DefaultRetryPolicy() RetryPolicy
DefaultRetryPolicy is three retries with 1s, 2s, 4s backoff, which is what every embedding client used before this helper existed.
type SSEReader ¶
type SSEReader struct {
// contains filtered or unexported fields
}
SSEReader 用于读取 SSE 流
type SandboxFileProgress ¶
type SandboxFileProgress struct {
// contains filtered or unexported fields
}
SandboxFileProgress tracks a streamed write/edit tool call and emits throttled progress payloads.
func NewSandboxFileProgress ¶
func NewSandboxFileProgress(toolName string) *SandboxFileProgress
NewSandboxFileProgress creates a tracker for one tool call.
type ScoreScale ¶
type ScoreScale string
ScoreScale describes what a rerank score means, which differs per protocol and cannot be inferred from the number itself.
const ( // ScoreProbability is a 0..1 relevance score. Every protocol but NIM // returns one. ScoreProbability ScoreScale = "probability" // ScoreLogit is an unbounded log-odds value that may be negative. NIM // returns one, so a threshold tuned for probabilities rejects almost // everything on that vendor. ScoreLogit ScoreScale = "logit" )
type StreamAssembler ¶
type StreamAssembler struct {
ThinkingEmitter
// Usage is captured from the final stream chunk when the vendor reports it.
Usage *types.TokenUsage
// LastFinishReason is the last observed finish_reason for the EOF fallback.
LastFinishReason string
// ReasoningSignature / ReasoningMetadata accumulate provider artifacts that
// the final Done chunk hands back to the caller through Data.
ReasoningSignature string
ReasoningMetadata types.ProviderMetadata
// contains filtered or unexported fields
}
StreamAssembler turns protocol deltas into the types.StreamResponse sequence the agent engine and the chat pipeline consume. It owns the "reasoning then answer" hand-off, tool-call fragment assembly, the early tool-call notification (ResponseTypeToolCall) once a function name has stabilised, streaming extraction of the thinking tool's `thought` field and live sandbox file-edit progress.
func NewStreamAssembler ¶
func NewStreamAssembler(ctx context.Context, model string) *StreamAssembler
NewStreamAssembler creates an assembler for one stream.
func (*StreamAssembler) Aborted ¶
func (a *StreamAssembler) Aborted() bool
Aborted reports whether the consumer went away mid-stream. Protocol loops check it to stop reading instead of decoding a stream nobody listens to.
func (*StreamAssembler) Emit ¶
func (a *StreamAssembler) Emit(ch chan<- types.StreamResponse, content string)
Emit forwards a reasoning chunk through the cancellation-aware send, shadowing the embedded ThinkingEmitter's blocking version.
func (*StreamAssembler) End ¶
func (a *StreamAssembler) End(ch chan<- types.StreamResponse)
End emits the closing chunk once the vendor stream is exhausted. It logs usage and carries the assembled tool calls, usage and reasoning artifacts.
func (*StreamAssembler) EndAtEOF ¶
func (a *StreamAssembler) EndAtEOF(ch chan<- types.StreamResponse)
EndAtEOF closes a stream whose body simply ran out. A vendor that finished the message has reported a finish reason by then; without one the connection was most likely cut by a proxy or load balancer, and the answer is marked incomplete, as the Anthropic loop already does, instead of reaching the caller as a clean stop.
func (*StreamAssembler) Fail ¶
func (a *StreamAssembler) Fail(ch chan<- types.StreamResponse, err error)
Fail emits the error chunk for a broken stream.
func (*StreamAssembler) Finish ¶
func (a *StreamAssembler) Finish(ch chan<- types.StreamResponse)
Finish emits the single thinking-done marker if one is owed, through the cancellation-aware send. Shadows the embedded ThinkingEmitter's version.
func (*StreamAssembler) OrderedToolCalls ¶
func (a *StreamAssembler) OrderedToolCalls() []types.LLMToolCall
OrderedToolCalls returns the assembled calls in index order, or nil.
The indices are the vendor's, not ours: gateways number calls from 1, and parallel calls can arrive with gaps. Walking 0..len(map) would silently drop every call outside that range — and a round that loses its calls reaches the agent as a plain answer — so the keys are sorted instead.
func (*StreamAssembler) Process ¶
func (a *StreamAssembler) Process(ch chan<- types.StreamResponse, d Delta)
Process consumes one delta and emits the resulting stream responses. It mirrors the event sequence of the original OpenAI stream loop so every downstream consumer sees exactly what it saw before the protocol split.
func (*StreamAssembler) ReplaceToolCalls ¶
func (a *StreamAssembler) ReplaceToolCalls(calls []types.LLMToolCall)
ReplaceToolCalls swaps the assembled tool calls for a protocol's own final view (for example, one that drops calls the stream never closed).
func (*StreamAssembler) SetToolCallMetadata ¶
func (a *StreamAssembler) SetToolCallMetadata(index int, metadata types.ToolCallMetadata)
SetToolCallMetadata attaches provider state to the call at index, creating a placeholder entry when the metadata arrives before the call itself.
func (*StreamAssembler) SetUsage ¶
func (a *StreamAssembler) SetUsage(u types.TokenUsage)
SetUsage records usage from the vendor's final chunk.
func (*StreamAssembler) ToolCallCount ¶
func (a *StreamAssembler) ToolCallCount() int
ToolCallCount reports how many distinct tool calls have been seen.
type StreamPacketDumper ¶
type StreamPacketDumper struct {
// contains filtered or unexported fields
}
StreamPacketDumper writes one stream session to a dedicated JSONL file: line 1 = request wrapper; following lines = raw provider chunk JSON.
func NewStreamPacketDumper ¶
func NewStreamPacketDumper(modelName string, request any) *StreamPacketDumper
NewStreamPacketDumper opens a dump file for one stream, or returns nil when raw dumping is disabled.
func (*StreamPacketDumper) Close ¶
func (d *StreamPacketDumper) Close()
Close flushes and closes the dump file.
func (*StreamPacketDumper) Path ¶
func (d *StreamPacketDumper) Path() string
Path returns the dump file location.
func (*StreamPacketDumper) WriteError ¶
func (d *StreamPacketDumper) WriteError(message string)
WriteError appends a terminal error record (stream read failure, API error, etc.).
func (*StreamPacketDumper) WriteHTTPError ¶
func (d *StreamPacketDumper) WriteHTTPError(statusCode int, body []byte)
WriteHTTPError appends a non-2xx HTTP response before any SSE packets.
func (*StreamPacketDumper) WritePacket ¶
func (d *StreamPacketDumper) WritePacket(v any)
WritePacket marshals v as one JSON object per line (SDK stream Recv path).
func (*StreamPacketDumper) WritePacketRaw ¶
func (d *StreamPacketDumper) WritePacketRaw(raw []byte)
WritePacketRaw appends one provider chunk as a single JSONL line (valid JSON written as-is).
type ThinkingEmitter ¶
type ThinkingEmitter struct {
// contains filtered or unexported fields
}
ThinkingEmitter owns the "reasoning then answer" hand-off that every streaming Chat implementation shares: thinking chunks are forwarded as they arrive, and exactly one thinking-done marker is emitted before the first answer token (or when the stream ends without one). Centralizing the bookkeeping keeps the OpenAI-compatible and Ollama stream loops in sync.
func (*ThinkingEmitter) Emit ¶
func (e *ThinkingEmitter) Emit(ch chan<- types.StreamResponse, content string)
Emit forwards a reasoning chunk and records that a thinking-done marker is still owed.
func (*ThinkingEmitter) Finish ¶
func (e *ThinkingEmitter) Finish(ch chan<- types.StreamResponse)
Finish emits the single thinking-done marker if one is owed. Safe to call multiple times; only the first call after an emit sends anything.
type ThinkingFormat ¶
type ThinkingFormat string
ThinkingFormat names how an OpenAI-compatible vendor encodes the thinking switch. It is the single most divergent field across vendors, which is why it is an enum rather than free text.
const ( // ThinkingFormatNone sends no thinking fields at all. ThinkingFormatNone ThinkingFormat = "none" // ThinkingFormatOpenAI sends only reasoning_effort (OpenAI, Azure, xAI). ThinkingFormatOpenAI ThinkingFormat = "openai" // ThinkingFormatThinkingType sends {"thinking": {"type": "enabled"|"disabled"}} // plus reasoning_effort when supported (DeepSeek, Zhipu, Volcengine Ark, // Moonshot K2.6+, MiniMax M3, LKEAP). ThinkingFormatThinkingType ThinkingFormat = "thinking-type" // ThinkingFormatEnableThinking sends enable_thinking: bool plus // thinking_budget (DashScope, SiliconFlow, Hunyuan). ThinkingFormatEnableThinking ThinkingFormat = "enable-thinking" // ThinkingFormatChatTemplateKwargs sends chat_template_kwargs.enable_thinking // (vLLM, SGLang, NIM, LiteLLM in front of them). ThinkingFormatChatTemplateKwargs ThinkingFormat = "chat-template-kwargs" // ThinkingFormatOpenRouter sends {"reasoning": {"effort"|"enabled"}}. ThinkingFormatOpenRouter ThinkingFormat = "openrouter" )
type ThinkingLevelMap ¶
type ThinkingLevelMap map[ReasoningEffort]*string
ThinkingLevelMap maps protocol-neutral levels to a vendor's own vocabulary.
Semantics mirror Pi's thinkingLevelMap:
- a missing key means "supported, pass the level name through" for minimal/low/medium/high and "unsupported" for xhigh/max;
- a null value marks the level as unsupported (the caller clamps to the nearest supported rung);
- a string value is what the vendor expects on the wire.
The special key "off" may be mapped to null to state that thinking cannot be switched off (always-on reasoning models).
func (ThinkingLevelMap) Clamp ¶
func (m ThinkingLevelMap) Clamp(level ReasoningEffort) ReasoningEffort
Clamp returns the nearest supported graded level: first upward, then downward, mirroring Pi's clampThinkingLevel. Off/Auto are returned as-is (Off may still be unsupported; callers check Supports(ReasoningOff)).
func (ThinkingLevelMap) SupportedLevels ¶
func (m ThinkingLevelMap) SupportedLevels() []ReasoningEffort
SupportedLevels lists the levels this map accepts, in UI order.
func (ThinkingLevelMap) Supports ¶
func (m ThinkingLevelMap) Supports(level ReasoningEffort) bool
Supports reports whether the level is usable for this model.
func (ThinkingLevelMap) Value ¶
func (m ThinkingLevelMap) Value(level ReasoningEffort) string
Value returns the vendor value for a supported level. Unmapped levels pass through under their own name.
type Tool ¶
type Tool struct {
Type string `json:"type"` // "function"
Function FunctionDef `json:"function"`
}
Tool represents a function/tool definition
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"`
Type string `json:"type"` // "function"
Function FunctionCall `json:"function"`
ProviderMetadata types.ToolCallMetadata `json:"provider_metadata,omitempty"`
}
ToolCall represents a tool call in a message
type ToolCallDelta ¶
ToolCallDelta is one streamed fragment of a tool call, already lifted out of whatever envelope the protocol uses (OpenAI delta.tool_calls, Anthropic input_json_delta, Gemini functionCall parts, Responses function_call_arguments.delta).
type Transcriber ¶
type Transcriber interface {
Transcribe(ctx context.Context, req TranscriptionRequest) (*Transcription, error)
}
Transcriber turns one audio file into text.
type Transcription ¶
type Transcription struct {
Text string
Segments []TranscriptionSegment
// Duration is the audio length in seconds when the reply states it —
// OpenAI-shaped duration or usage.seconds — and 0 otherwise.
Duration float64
}
Transcription is what a protocol client returns.
type TranscriptionAPI ¶
type TranscriptionAPI string
TranscriptionAPI names a speech-to-text wire protocol. Like RerankAPI and EmbeddingAPI it is its own type, so no other modality's value validates.
const ( // TranscriptionOpenAI is POST {base}/audio/transcriptions as a multipart // form carrying file and model, answering {text} — or {text, segments} // when verbose_json is asked for. TranscriptionOpenAI TranscriptionAPI = "openai-transcriptions" // TranscriptionChatAudio is a dedicated speech-recognition model behind // POST {base}/chat/completions: the audio goes in as a base64 data URI in // an input_audio content part and the transcript comes back as the // assistant message. Alibaba's qwen3-asr-flash and Xiaomi's mimo-v2.5-asr // take no instruction; the model only transcribes. TranscriptionChatAudio TranscriptionAPI = "openai-chat-audio" )
The transcription protocols WeKnora speaks.
func (TranscriptionAPI) Known ¶
func (a TranscriptionAPI) Known() bool
Known reports whether the value names a protocol this build implements.
type TranscriptionRequest ¶
type TranscriptionRequest struct {
Audio []byte
FileName string
// Language is the operator's hint, empty for auto-detection. Where it is
// sent, and whether at all, is the vendor's declaration.
Language string
}
TranscriptionRequest is one file to transcribe.
type TranscriptionSegment ¶
TranscriptionSegment is one timed stretch of a transcript.
type TranscriptionsCompat ¶
type TranscriptionsCompat struct {
API *TranscriptionAPI `json:"api,omitempty"`
Path *string `json:"path,omitempty"`
// ResponseFormat is sent as response_format when non-empty. OpenAI's
// gpt-4o-transcribe and gpt-4o-mini-transcribe accept only json, which is
// also the default, so most models leave it unset.
ResponseFormat *string `json:"response_format,omitempty"`
// LanguageParam names where the language hint goes: form, header or
// asr_options; empty sends none.
LanguageParam *string `json:"language_param,omitempty"`
// MaxFileBytes is the documented upload ceiling for the audio itself.
MaxFileBytes *int `json:"max_file_bytes,omitempty"`
// MaxEncodedBytes is the documented ceiling on the base64 data URI, for
// the protocols that send the audio that way.
MaxEncodedBytes *int `json:"max_encoded_bytes,omitempty"`
// Formats lists the file extensions the vendor documents, without the
// dot. Empty means the vendor documents no closed list.
Formats []string `json:"formats,omitempty"`
RequestTimeout *int `json:"request_timeout_seconds,omitempty"`
// UnsupportedReason marks a model this build cannot call.
UnsupportedReason *string `json:"unsupported_reason,omitempty"`
}
TranscriptionsCompat is the overlay form (every field optional) of the speech-to-text settings. JSON keys are the names used in models.json.
type TranscriptionsSettings ¶
type TranscriptionsSettings struct {
API TranscriptionAPI
Path string
ResponseFormat string
LanguageParam string
// MaxFileBytes and MaxEncodedBytes refuse an upload the vendor would
// reject anyway, before sending it; 0 leaves the check to the vendor.
MaxFileBytes int
MaxEncodedBytes int
Formats []string
// RequestTimeout caps one request, in seconds.
RequestTimeout int
// UnsupportedReason is set where a vendor's recognition models, or some
// of them, cannot be called with the audio in the request — they take a
// public URL or run as asynchronous tasks. Resolve refuses such a model
// rather than sending it a shape it does not accept.
UnsupportedReason string
}
TranscriptionsSettings is the resolved (fully defaulted) form.
func DefaultTranscriptions ¶
func DefaultTranscriptions() TranscriptionsSettings
DefaultTranscriptions is the protocol baseline: a form with file and model and nothing else, which every speech-to-text endpoint in this catalog documents. The deadline is the one the pre-catalog client carried; audio transcription is slow.
type TransportError ¶
type TransportError struct {
// Op is the phase that failed: "send request" or "read response".
Op string
Err error
}
TransportError is a request that never got a whole answer: DNS, connect, TLS, a reset or a timeout, while sending or while reading the reply. It is the only failure worth sending again.
func (*TransportError) Error ¶
func (e *TransportError) Error() string
func (*TransportError) Unwrap ¶
func (e *TransportError) Unwrap() error
Source Files
¶
- batch.go
- compat_settings.go
- credentials.go
- embeddings.go
- embeddings_settings.go
- endpoint.go
- image_input.go
- images.go
- json_field_extractor.go
- multipart.go
- options.go
- prompt_cache.go
- raw_dump.go
- rerank.go
- rerank_settings.go
- retry.go
- sandbox_file_progress.go
- special_tokens.go
- sse.go
- stream_assembler.go
- thinking_emitter.go
- transcriptions.go
- transcriptions_settings.go
- transport.go
- types.go
- usage.go
- usage_log.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package anthropicmessages implements the Anthropic Messages wire protocol (https://docs.anthropic.com/en/api/messages).
|
Package anthropicmessages implements the Anthropic Messages wire protocol (https://docs.anthropic.com/en/api/messages). |
|
Package arkembeddings implements Volcengine Ark's multimodal embedding shape: an input array of typed parts answering a single `data` object.
|
Package arkembeddings implements Volcengine Ark's multimodal embedding shape: an input array of typed parts answering a single `data` object. |
|
Package cohererank implements the rerank shape Cohere defined and almost every other vendor copied: POST {base}/rerank with {model, query, documents} answering {results: [{index, relevance_score, document}]}.
|
Package cohererank implements the rerank shape Cohere defined and almost every other vendor copied: POST {base}/rerank with {model, query, documents} answering {results: [{index, relevance_score, document}]}. |
|
Package dashscopeembeddings implements Alibaba Model Studio's native multimodal embedding shape: input.contents, parameters.dimension, and results under output.embeddings.
|
Package dashscopeembeddings implements Alibaba Model Studio's native multimodal embedding shape: input.contents, parameters.dimension, and results under output.embeddings. |
|
Package dashscoperank implements Alibaba Model Studio's native text-rerank shape: the same fields as the Cohere dialect, wrapped in input/parameters and answered under output.
|
Package dashscoperank implements Alibaba Model Studio's native text-rerank shape: the same fields as the Cohere dialect, wrapped in input/parameters and answered under output. |
|
Package googleembeddings implements Gemini's batchEmbedContents: one POST carrying a request per text, answering embeddings[].values in order.
|
Package googleembeddings implements Gemini's batchEmbedContents: one POST carrying a request per text, answering embeddings[].values in order. |
|
Package googlegenai implements the native Google Gemini generateContent wire protocol (https://ai.google.dev/api/generate-content).
|
Package googlegenai implements the native Google Gemini generateContent wire protocol (https://ai.google.dev/api/generate-content). |
|
Package nimrerank implements NVIDIA NIM's retrieval reranking shape: a query object, a passages array, and rankings carrying a logit.
|
Package nimrerank implements NVIDIA NIM's retrieval reranking shape: a query object, a passages array, and rankings carrying a logit. |
|
Package openaichataudio implements speech recognition served through the chat completions endpoint: one user message whose only content part is {"type": "input_audio", "input_audio": {"data": "data:<mime>;base64,..."}}, answered by an assistant message whose content is the transcript.
|
Package openaichataudio implements speech recognition served through the chat completions endpoint: one user message whose only content part is {"type": "input_audio", "input_audio": {"data": "data:<mime>;base64,..."}}, answered by an assistant message whose content is the transcript. |
|
Package openaicompletions implements the OpenAI Chat Completions wire protocol.
|
Package openaicompletions implements the OpenAI Chat Completions wire protocol. |
|
Package openaiembeddings implements the embedding shape OpenAI defined and every compatible gateway copied: POST {base}/embeddings with {model, input} answering {data: [{embedding, index}]}.
|
Package openaiembeddings implements the embedding shape OpenAI defined and every compatible gateway copied: POST {base}/embeddings with {model, input} answering {data: [{embedding, index}]}. |
|
Package openairesponses implements the OpenAI Responses wire protocol (POST /responses).
|
Package openairesponses implements the OpenAI Responses wire protocol (POST /responses). |
|
Package openaitranscriptions implements the speech-to-text shape OpenAI defined and the compatible servers copied: a multipart POST to {base}/audio/transcriptions carrying file and model, answering {text}, or {text, segments} when response_format is verbose_json.
|
Package openaitranscriptions implements the speech-to-text shape OpenAI defined and the compatible servers copied: a multipart POST to {base}/audio/transcriptions carrying file and model, answering {text}, or {text, segments} when response_format is verbose_json. |
|
Package pineconerank implements Pinecone Inference's standalone rerank API.
|
Package pineconerank implements Pinecone Inference's standalone rerank API. |
|
Package teirank implements the native Text Embeddings Inference rerank protocol.
|
Package teirank implements the native Text Embeddings Inference rerank protocol. |
|
Package tencentlkeap implements Tencent RunRerank through its official SDK.
|
Package tencentlkeap implements Tencent RunRerank through its official SDK. |
|
Package volcengineknowledge implements Volcengine Knowledge Service rerank through its official SDK.
|
Package volcengineknowledge implements Volcengine Knowledge Service rerank through its official SDK. |