protocolcore

package
v1.25.4 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CompatibilityWarningAuxiliaryMetadata = "auxiliary_metadata_dropped"
	CompatibilityWarningLogprobs          = "logprobs_degraded"
	CompatibilityWarningIntegrityMetadata = "integrity_metadata_dropped"
	CompatibilityWarningTerminalReason    = "terminal_reason_degraded"
	CompatibilityWarningResponseContent   = "response_content_dropped"
	CompatibilityWarningResponseText      = "response_content_text_fallback"
	CompatibilityWarningEmptyImage        = "empty_image_dropped"
	CompatibilityWarningToolArguments     = "tool_arguments_quoted"
	CompatibilityWarningResponseAction    = "response_action_omitted"
	CompatibilityWarningContentOrder      = "content_order_degraded"
	CompatibilityWarningPostTerminalEvent = "post_terminal_event_dropped"
	CompatibilityWarningToolIdentity      = "tool_identity_degraded"
	CompatibilityWarningUnnamedToolCall   = "unnamed_tool_call_dropped"
)
View Source
const (
	CompatibilityWarningRequestExtension         = "request_extension_forwarded"
	CompatibilityWarningRequestExtensionConflict = "request_extension_conflict"
	CompatibilityWarningRequestExtra             = "request_extra_omitted"
	CompatibilityWarningRequestOpaque            = "request_opaque_forwarded"
	CompatibilityWarningRequestContentDegraded   = "request_content_degraded"
	CompatibilityWarningRequestContentOmitted    = "request_content_omitted"
	CompatibilityWarningRequestActionDegraded    = "request_action_omitted"
)
View Source
const (
	CompatibilityWarningToolArgumentsFallback = CompatibilityWarningToolArguments
)
View Source
const DefaultStreamFrameLimit = 16 << 20

DefaultStreamFrameLimit bounds one upstream frame so an untrusted peer cannot grow bridge memory indefinitely by withholding a line delimiter. This is a transport resource policy, not a provider capability check; callers can pass a negative explicit limit when a trusted endpoint requires unbounded frames.

Variables

View Source
var (
	ErrStreamLineTooLarge = errors.New("stream line exceeds maximum size")
	ErrSSEEventTooLarge   = errors.New("SSE event data exceeds maximum size")
)
View Source
var ErrInvalidStreamToolArguments = errors.New("stream tool call ended with invalid JSON arguments")

ErrInvalidStreamToolArguments identifies a structured-protocol tool call whose fragments require JSON-string fallback. StreamToolArgumentGuard turns it into a compatibility warning; direct low-level validation may still use errors.Is to recognize the condition.

View Source
var ErrMalformedUpstreamResponse = errors.New("upstream structured response could not be decoded")

ErrMalformedUpstreamResponse reports a response that cannot be decoded as the configured wire protocol.

View Source
var ErrStreamWriterMissingFinish = errors.New("stream writer ended without a semantic finish event")

ErrStreamWriterMissingFinish marks a direct StreamWriter Done/Close call that arrived before any semantic EventFinish. Writers emit one native failed/error terminal before returning this sentinel.

Functions

func AppendSystem

func AppendSystem(existing, next string) string

func AttachGatewayMetrics added in v1.23.0

func AttachGatewayMetrics(payload map[string]any, sample *metrics.Sample) map[string]any

AttachGatewayMetrics adds the gateway-owned telemetry extension to an already-encoded response object. It is the shared entry point for every non-streaming encoder, so the field name and the "omit when unmeasurable" rule stay identical across protocols.

The extension lives in its own top-level field: no protocol's native usage/counter object is touched, so a client that does not know the field can ignore it and a strict validator can allowlist exactly one name.

func BridgeStopFields added in v1.18.5

func BridgeStopFields(r *ir.Request)

BridgeStopFields makes the stop-sequence settings mutually readable across protocols. Chat/Ollama use `stop`; Claude/Gemini use `stop_sequences`. When only one is set, derive the other from it so every target encoder sees the stops regardless of which field the source populated.

func ChatReasoningEffortFromResponsesReasoning

func ChatReasoningEffortFromResponsesReasoning(value any) any

func ChatResponseFormatFromResponsesText

func ChatResponseFormatFromResponsesText(value any) any

func DecodeJSONWithExtraFromBody

func DecodeJSONWithExtraFromBody(body []byte, dst any, knownKeys ...string) (map[string]any, error)

func DecodeStreamJSON

func DecodeStreamJSON(data string, dst any) (bool, error)

func DefaultToolParameters

func DefaultToolParameters(raw json.RawMessage) json.RawMessage

func FirstText

func FirstText(parts []ir.ContentPart) string

func FlushWriter

func FlushWriter(w io.Writer) error

func GatewayMetricsObject added in v1.23.0

func GatewayMetricsObject(sample *metrics.Sample) map[string]any

GatewayMetricsObject renders the extension object for stream frames that carry the telemetry inline. It returns nil when there is nothing to report, so callers can leave the field out entirely.

func GeminiModelPath

func GeminiModelPath(model string) string

func ImageAsDataURI

func ImageAsDataURI(img *ir.Image) string

func IsKnownClaudeStopReason added in v1.20.2

func IsKnownClaudeStopReason(reason string) bool

IsKnownClaudeStopReason reports whether reason is one of the terminal enums in the pinned Anthropic Messages contract. Decoders still retain future non-empty reasons for same-protocol replay; foreign protocols must not guess that an unknown terminal means a successful stop.

func IsStandardUsageField added in v1.18.5

func IsStandardUsageField(key string) bool

IsStandardUsageField reports whether a usage JSON key is a standard token field defined by one of the supported protocols (OpenAI prompt_tokens/ completion_tokens, Claude input_tokens/output_tokens, Gemini counts, cache details). Same-protocol usage encoders skip these keys when replaying owner-scoped usage.Extra so the emitted usage stays canonical; cross-protocol encoders never receive Extra and use only the structured ir.Usage fields.

func IsStructuredJSONResponse added in v1.20.2

func IsStructuredJSONResponse(body []byte, contentType string) bool

IsStructuredJSONResponse reports whether a response body or media type looks JSON-shaped. It is retained for diagnostic callers.

func IsUnsupportedContent added in v1.20.2

func IsUnsupportedContent(err error) bool

func JSONRequest

func JSONRequest(ctx context.Context, method, baseURL, route, token string, payload any, auth func(*http.Request, string)) (*http.Request, error)

func JoinURL

func JoinURL(baseURL, route string, query url.Values) (string, error)

func MapFinishFromClaude

func MapFinishFromClaude(reason string) ir.FinishReason

func MapFinishFromGemini

func MapFinishFromGemini(reason string) ir.FinishReason

func MapFinishFromOpenAI

func MapFinishFromOpenAI(reason string) ir.FinishReason

func MapFinishToClaude

func MapFinishToClaude(reason ir.FinishReason) string

func MapFinishToGemini

func MapFinishToGemini(reason ir.FinishReason) string

func MapFinishToOpenAI

func MapFinishToOpenAI(reason ir.FinishReason) string

func MergeForeignToolChoicePayload added in v1.20.2

func MergeForeignToolChoicePayload(payload any, raw json.RawMessage, ownerProtocol, targetProtocol string) any

MergeForeignToolChoicePayload is the tool-choice counterpart. It preserves unknown object members when both source and target use object envelopes; target typed fields remain authoritative on conflicts.

func MergeForeignToolPayload added in v1.20.2

func MergeForeignToolPayload(payload any, tool ir.Tool, targetProtocol string) any

MergeForeignToolPayload overlays non-conflicting fields from a typed tool's source envelope onto the target protocol's canonical tool object. Target fields win on conflicts; unknown vendor fields remain available to the compatible remote endpoint.

func MergeJSONPayload

func MergeJSONPayload(payload any, extra map[string]any) any

func MergeUsageCounters added in v1.20.2

func MergeUsageCounters(existing, next *ir.Usage) *ir.Usage

MergeUsageCounters combines successive usage snapshots without inferring a provider's reporting model from its protocol name. The latest non-zero component wins. An explicit latest total is preserved; when the latest frame updates components but omits total, a fresh sum is synthesized.

func MergeUsageDetails added in v1.20.2

func MergeUsageDetails(preserved any, structured map[string]any) map[string]any

MergeUsageDetails overlays structured token counters onto an owner-preserved usage detail object. Known counters win while unknown nested fields remain, and json.Number keeps large provider integers exact.

func MergeUsageExtra added in v1.20.2

func MergeUsageExtra(out, next *ir.Usage)

MergeUsageExtra merges provider-owned usage extensions without making them portable. Conflicting owners clear the extensions instead of choosing one provider's schema and potentially leaking it into another protocol.

func NewUnsupportedContentError added in v1.20.2

func NewUnsupportedContentError(protocolName, detail string) error

func NormalizeRequestForConversion

func NormalizeRequestForConversion(r *ir.Request, sourceProtocol, targetProtocol string)

NormalizeRequestForConversion preserves the historical no-result API. New call sites that can surface compatibility diagnostics should use NormalizeRequestForConversionWithWarnings.

func NormalizeResponseLifecycleForTarget added in v1.20.2

func NormalizeResponseLifecycleForTarget(response *ir.Response, targetProtocol string) error

NormalizeResponseLifecycleForTarget selects the portable fallback for a lifecycle that is explicitly terminal but whose provider-specific reason is unknown. The owning Responses encoder still replays Raw and is untouched.

func NormalizeToolArgumentsForTarget added in v1.20.2

func NormalizeToolArgumentsForTarget(arguments json.RawMessage, targetProtocol string) (json.RawMessage, bool)

NormalizeToolArgumentsForTarget preserves model-generated arguments on a target whose wire embeds arguments as JSON. Complete JSON values pass through unchanged; incomplete bytes become one valid JSON string value so the remote endpoint, rather than the bridge, decides whether to accept it. OpenAI-style targets already carry arguments as an opaque string and need no rewrite. The boolean reports whether quoting was applied.

func NormalizeToolCallFinish added in v1.18.5

func NormalizeToolCallFinish(r *ir.Response)

NormalizeToolCallFinish 将含工具调用的 stop 响应提升为 tool_calls 结束原因; Gemini 和 Ollama 常把这类回合误标为 STOP,但下游需靠结束原因识别工具轮次。

func NormalizeToolCallIDs added in v1.18.3

func NormalizeToolCallIDs(r *ir.Request)

NormalizeToolCallIDs assigns a stable ID to every tool call that lacks one and back-fills the matching tool result's ToolCallID so the call/result pair always references the same ID. Gemini functionCall and Ollama tool_calls never carry an ID, so without this every downstream encoder would mint its own independent ID for the assistant call and the tool result, producing a mismatched pair that OpenAI Chat / Responses and Claude reject.

func OllamaFormatFromResponsesText

func OllamaFormatFromResponsesText(value any) any

func ParseDataURI

func ParseDataURI(raw string) (mediaType, data string, ok bool)

func ParseImageURL

func ParseImageURL(raw string) *ir.Image

func PreserveToolParameters added in v1.20.2

func PreserveToolParameters(raw json.RawMessage) json.RawMessage

PreserveToolParameters keeps any valid JSON value exactly as the caller supplied it. Adapters are wire converters and must not replace a compatible backend's scalar, array, boolean, or future schema shape merely because a pinned provider contract documents an object. Only a missing definition receives the historical empty-schema fallback.

func PromoteSystemMessages added in v1.18.3

func PromoteSystemMessages(r *ir.Request)

PromoteSystemMessages 合并所有 RoleSystem 消息到 r.System,并从消息列表移除; 这样只读取请求级系统字段的编码器也不会把系统提示降级为用户消息。

func RawFromObject

func RawFromObject(v any) json.RawMessage

func RawToJSONString

func RawToJSONString(raw json.RawMessage) string

func RawToObject

func RawToObject(raw json.RawMessage) map[string]any

func RawToValue added in v1.18.5

func RawToValue(raw json.RawMessage) any

RawToValue decodes one complete JSON tool-call argument without changing its shape. Protocol-specific validators reject non-object values for targets that require an object; this helper must never manufacture a {"value": ...} wrapper because that changes the tool's argument contract.

func ReadLimitedLine added in v1.20.2

func ReadLimitedLine(reader *bufio.Reader, limit int) (string, error)

ReadLimitedLine reads one newline-delimited frame without Scanner's 64 KiB ceiling. Zero uses the safe default, a positive value supplies a custom bound, and a negative value reads an unbounded trusted frame. The returned line excludes its line ending. A final unterminated line is returned together with io.EOF, matching bufio.Reader.ReadString semantics.

func ResolveImageData

func ResolveImageData(ctx context.Context, img *ir.Image) (*ir.Image, error)

func ResponseFailureIsNativeLifecycle added in v1.20.2

func ResponseFailureIsNativeLifecycle(response *ir.Response, targetProtocol string) bool

ResponseFailureIsNativeLifecycle reports a valid same-protocol failed or cancelled resource envelope. It must remain a normal HTTP 200 Responses body instead of being promoted to a proxy transport error.

func ResponseHasNonNativeFailure added in v1.20.2

func ResponseHasNonNativeFailure(response *ir.Response, targetProtocol string) bool

ResponseHasNonNativeFailure reports whether any alternative reply ended in an error that the destination protocol cannot represent natively. Looking only at Response.FinishReason is insufficient because it mirrors choice 0; a later Gemini candidate may have an error finish of its own.

func ResponseID

func ResponseID(existing, prefix string) string

func ResponsePrimaryHasNonNativeFailure added in v1.20.2

func ResponsePrimaryHasNonNativeFailure(response *ir.Response, targetProtocol string) bool

ResponsePrimaryHasNonNativeFailure is the single-reply form of ResponseHasNonNativeFailure. Choice index 0 is preferred, matching DowngradeResponseChoicesForTarget; a failed discarded alternative does not make the retained response a failure.

func ResponsesReasoningFromChatReasoningEffort

func ResponsesReasoningFromChatReasoningEffort(value any) any

func ResponsesTextFromChatResponseFormat

func ResponsesTextFromChatResponseFormat(value any) any

func ResponsesTextFromOllamaFormat

func ResponsesTextFromOllamaFormat(value any) any

func ResponsesTextWithVerbosity

func ResponsesTextWithVerbosity(text any, verbosity any) any

func StopAsSequences

func StopAsSequences(value any) any

func StreamFailureIsNativeForTarget added in v1.20.2

func StreamFailureIsNativeForTarget(event *ir.StreamEvent, targetProtocol string) bool

StreamFailureIsNativeForTarget is the streaming counterpart. A provider's exact failed terminal may be relayed only to the protocol that owns its raw event or native finish enum; every other target must surface the public upstream-stream-failed contract.

func SupportsMultipleNonStreamChoices added in v1.20.2

func SupportsMultipleNonStreamChoices(protocolName string) bool

SupportsMultipleNonStreamChoices reports whether a wire response can keep independently terminated alternatives distinct.

func SupportsMultipleStreamChoices added in v1.20.2

func SupportsMultipleStreamChoices(protocolName string) bool

SupportsMultipleStreamChoices reports whether the wire protocol can keep alternative streamed replies distinct. Claude, Responses and Ollama expose one logical reply and must never merge multiple Chat/Gemini alternatives.

func SupportsOwnedRawContent added in v1.20.2

func SupportsOwnedRawContent(protocolName string) bool

func TextFromParts

func TextFromParts(parts []ir.ContentPart) string

func ValidateCrossProtocolLogprobsRequest added in v1.20.2

func ValidateCrossProtocolLogprobsRequest(request *ir.Request, sourceProtocol, targetProtocol string) error

ValidateCrossProtocolLogprobsRequest is retained for compatibility with existing callers. Logprobs compatibility is decided by the remote endpoint.

func ValidateRequestChoiceCount added in v1.20.2

func ValidateRequestChoiceCount(request *ir.Request, targetProtocol string) error

ValidateRequestChoiceCount is retained for adapter compatibility. Choice count values are endpoint inputs, so the bridge must not enforce a remote provider's range or infer support from the selected wire protocol.

func ValidateRequestRawParts added in v1.20.2

func ValidateRequestRawParts(request *ir.Request, targetProtocol string, supportsOwnedRaw bool) error

ValidateRequestRawParts prevents an unmodelled source-protocol block from disappearing in a target protocol that cannot represent it. Owned raw parts are permitted only for converters that actually implement same-protocol replay; every other case fails before an upstream request is sent.

func ValidateResponseChoices added in v1.20.2

func ValidateResponseChoices(response *ir.Response, targetProtocol string) error

ValidateResponseChoices prevents a single-reply protocol from silently encoding only the first alternative.

func ValidateResponseLifecycleForTarget added in v1.20.2

func ValidateResponseLifecycleForTarget(response *ir.Response, targetProtocol string) error

ValidateResponseLifecycleForTarget keeps provider resource states distinct from model-generation finish reasons. A queued, running, failed, or cancelled Responses resource is losslessly representable only by a Responses client; completed/incomplete envelopes have a typed fallback.

func ValidateResponseRawParts added in v1.20.2

func ValidateResponseRawParts(response *ir.Response, targetProtocol string, supportsOwnedRaw bool) error

ValidateResponseRawParts is the response-side equivalent of ValidateRequestRawParts.

func ValidateResponsesBackgroundRequest added in v1.20.2

func ValidateResponsesBackgroundRequest(_ *ir.Request, _, _ string) error

ValidateResponsesBackgroundRequest is retained for API compatibility. Any valid JSON value is forwarded as an owner-scoped request extension; whether the remote endpoint accepts that value is remote validation.

func ValidateStreamEventForProtocol added in v1.20.2

func ValidateStreamEventForProtocol(event *ir.StreamEvent, targetProtocol string) error

ValidateStreamEventForProtocol validates stream metadata that would make a typed conversion unsafe. The EventFinish boundary itself proves completion; an unknown typed reason can be encoded with the target's neutral terminal spelling and reported by StreamCompatibilityWarnings. Remote capability is not inferred from an enum allowlist here.

func ValidateStreamRawEvent added in v1.20.2

func ValidateStreamRawEvent(event *ir.StreamEvent, targetProtocol string) error

ValidateStreamRawEvent enforces the stream equivalent of the owned-raw content contract. The owning protocol may replay the original frame; another protocol may use a complete typed value, omit auxiliary data, or render safe passive response information as text.

func VerbosityFromResponsesText

func VerbosityFromResponsesText(value any) any

func WriteJSONLineTo

func WriteJSONLineTo(w io.Writer, payload any) error

func WriteSSEDataTo

func WriteSSEDataTo(w io.Writer, event, data string) error

func WriteSSEJSONTo

func WriteSSEJSONTo(w io.Writer, event string, payload any) error

Types

type BufferedUsageWriter added in v1.18.5

type BufferedUsageWriter interface {
	StreamWriter
	BuffersUsage() bool
}

BufferedUsageWriter is implemented by StreamWriters that accumulate usage events internally and need every usage event relayed (instead of only the merged one the proxy/library writes before EventDone). Claude's streaming writer emits message_start.usage.input_tokens, so it must see the usage frame that arrives right after message_start; buffering it locally and deferring message_start until the first content event keeps the token counts intact. Writers that do not implement this interface keep receiving only the final merged usage, as before.

type CompatibilityWarning added in v1.20.2

type CompatibilityWarning struct {
	Code    string
	Message string
}

CompatibilityWarning describes a deliberate, non-fatal protocol downgrade. Callers may surface it to operators while continuing with the remaining portable response semantics.

func DowngradeRequestChoicesForTarget added in v1.20.2

func DowngradeRequestChoicesForTarget(request *ir.Request, targetProtocol string) (*CompatibilityWarning, error)

DowngradeRequestChoicesForTarget is retained for callers compiled against the old API. Request normalization now forwards choice counts through a native target field or a target-owned extension and leaves validation to the remote endpoint, so this function never mutates the request.

func DowngradeResponseChoicesForTarget added in v1.20.2

func DowngradeResponseChoicesForTarget(response *ir.Response, targetProtocol string) (*CompatibilityWarning, error)

DowngradeResponseChoicesForTarget selects one reply when the target has only one reply channel. Choice index 0 is preferred regardless of wire order; when it is absent, the first wire-order choice is retained. Only the retained choice is semantically validated: discarded alternatives are not part of the target response and their loss is covered by the warning.

func DowngradeResponseTerminalReasonsForTarget added in v1.20.2

func DowngradeResponseTerminalReasonsForTarget(response *ir.Response, targetProtocol string) *CompatibilityWarning

DowngradeResponseTerminalReasonsForTarget drops only the owner-specific spelling of an unknown terminal enum after a decoder has established a portable, non-error typed terminal. This prevents later owner-losslessness checks from treating a compatible provider extension as a fatal conversion.

func DropEmptyRequestImages added in v1.20.2

func DropEmptyRequestImages(request *ir.Request, targetProtocol string) ([]CompatibilityWarning, error)

DropEmptyRequestImages removes image content parts that carry no data, URL, or an opaque file ID. If the image was the message's only content, the resulting empty turn is still preferable to a local compatibility error; the warning makes the lossy downgrade visible and the remote validates the resulting request.

The error result is reserved for normalization failures so callers can use the same warning/error flow as other compatibility downgrades.

func DropEmptyResponseImages added in v1.20.2

func DropEmptyResponseImages(response *ir.Response, targetProtocol string) ([]CompatibilityWarning, error)

DropEmptyResponseImages is the response-side equivalent of DropEmptyRequestImages. Explicit Choices are authoritative; after filtering, the legacy top-level fields are synchronized from choice zero. Empty successful choices remain valid after downgrade.

func DropUnnamedRequestToolCalls added in v1.23.4

func DropUnnamedRequestToolCalls(request *ir.Request) []CompatibilityWarning

DropUnnamedRequestToolCalls removes assistant tool calls whose function name is blank, together with the tool results that answer them.

A phantom call with no name reaches the client when an upstream emits one alongside normal text; the client then replays it in the next turn's history. Forwarding it makes the remote reject the whole request (Codebuddy answers 11133 model_param_invalid), and because the history only grows, every later turn of that conversation fails the same way. Dropping the call on the way in lets an already-poisoned conversation heal instead of staying stuck.

The paired results must go with it: a tool result whose call no longer exists is itself a protocol error on Claude and Gemini, so removing only the call would trade one rejection for another.

func NormalizeCrossProtocolLogprobsRequest added in v1.20.2

func NormalizeCrossProtocolLogprobsRequest(request *ir.Request, sourceProtocol, targetProtocol string) []CompatibilityWarning

NormalizeCrossProtocolLogprobsRequest reports a cross-protocol spelling change without deleting user values. NormalizeRequestForConversionWithWarnings maps fields without an explicit adapter slot into target-owned extensions so the remote endpoint makes the capability decision.

func NormalizeRequestForConversionWithWarnings added in v1.20.2

func NormalizeRequestForConversionWithWarnings(r *ir.Request, sourceProtocol, targetProtocol string) []CompatibilityWarning

NormalizeRequestForConversionWithWarnings prepares a decoded request for a target adapter without assuming that the remote endpoint implements only the target protocol's official fields. Portable fields supported by the adapter stay typed. Known fields without an adapter slot are emitted through target-owned Extra using common compatibility spellings and reported as warnings, allowing the remote endpoint to make the final capability choice.

func NormalizeResponseContentForTarget added in v1.20.2

func NormalizeResponseContentForTarget(response *ir.Response, targetProtocol string) ([]CompatibilityWarning, error)

NormalizeResponseContentForTarget applies response-only, fail-soft compatibility downgrades before a target encoder validates the IR. It may omit content that has no target channel or preserve a passive value's visible text. Untyped actions are omitted rather than exposing provider-owned parameters. Malformed JSON remains strict because it has no trustworthy value.

func NormalizeStreamRawEventForTarget added in v1.20.2

func NormalizeStreamRawEventForTarget(event *ir.StreamEvent, targetProtocol string) (*ir.StreamEvent, *CompatibilityWarning, error)

NormalizeStreamRawEventForTarget prepares one EventRaw for a destination. Owned frames are replayed unchanged. Explicit typed/auxiliary fallbacks omit the carrier to avoid duplication. Every other valid foreign or ownerless frame preserves only allowlisted passive text. Active/untyped actions and opaque media are omitted so credentials and provider parameters cannot leak.

func PostTerminalEventWarning added in v1.20.3

func PostTerminalEventWarning(targetProtocol string) CompatibilityWarning

PostTerminalEventWarning reports an upstream event that arrived after the semantic boundary for the same response choice. The event is ignored so a protocol violation cannot append content after success or manufacture a second, contradictory terminal.

func RequestCompatibilityWarnings added in v1.20.2

func RequestCompatibilityWarnings(request *ir.Request, targetProtocol string) []CompatibilityWarning

RequestCompatibilityWarnings reports provider integrity metadata that a different upstream protocol will omit while retaining portable history.

func ResponseCompatibilityWarnings added in v1.20.2

func ResponseCompatibilityWarnings(response *ir.Response, targetProtocol string) []CompatibilityWarning

ResponseCompatibilityWarnings reports owner-scoped response details that a target encoder will deliberately omit while retaining the portable answer. It never returns provider values, which may contain sensitive citations or token scoring data.

func StreamCompatibilityWarnings added in v1.20.2

func StreamCompatibilityWarnings(event *ir.StreamEvent, targetProtocol string) []CompatibilityWarning

StreamCompatibilityWarnings is the event-side equivalent of ResponseCompatibilityWarnings. Normalizers handle valid raw-only output; provider integrity metadata is reported as a non-fatal downgrade.

func TakeStreamWriterCompatibilityWarnings added in v1.20.3

func TakeStreamWriterCompatibilityWarnings(writer StreamWriter) []CompatibilityWarning

func ToolIdentityCompatibilityWarning added in v1.20.3

func ToolIdentityCompatibilityWarning(targetProtocol string) CompatibilityWarning

ToolIdentityCompatibilityWarning reports that a target-required generated ID was already emitted before a compatible upstream supplied its own ID. The first wire identity remains stable; changing it mid-stream would break tool result pairing.

type CompatibilityWarningWriter added in v1.20.3

type CompatibilityWarningWriter interface {
	StreamWriter
	TakeCompatibilityWarnings() []CompatibilityWarning
}

type Converter

type Converter interface {
	Name() string
	DecodeRequestBody(body []byte, path string) (*ir.Request, error)
	BuildHTTPRequest(ctx context.Context, baseURL, token string, r *ir.Request) (*http.Request, error)
	EncodeResponseBody(r *ir.Response) ([]byte, error)
	DecodeResponse(body []byte) (*ir.Response, error)
	NewStreamWriterTo(w http.ResponseWriter) StreamWriter
	NewStreamReader(resp *http.Response) StreamReader
}

type Options

type Options struct {
	AnthropicVersion           string
	DefaultMaxTokens           int
	AnthropicSendAuthorization bool
	// StreamFrameLimit bounds one SSE line/event or Ollama NDJSON frame.
	// Zero uses DefaultStreamFrameLimit; a negative value explicitly disables
	// the bound for trusted endpoints that legitimately emit larger frames.
	StreamFrameLimit int
}

type ProviderMetadataGuard added in v1.20.2

type ProviderMetadataGuard struct {
	Protocol string
}

ProviderMetadataGuard keeps the validation hook shared by stream writers. Lossy but recoverable owner metadata is surfaced through compatibility warnings instead of being treated as proof that the remote cannot proceed.

func (*ProviderMetadataGuard) Observe added in v1.20.2

func (g *ProviderMetadataGuard) Observe(event *ir.StreamEvent) error

type Registry

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

func NewRegistry

func NewRegistry(protocols ...Converter) (*Registry, error)

func (*Registry) All

func (r *Registry) All() []Converter

func (*Registry) Get

func (r *Registry) Get(name string) (Converter, bool)

type RouteSpec

type RouteSpec struct {
	Method string
	Path   string
}

type SSEMessage

type SSEMessage struct {
	Event string
	Data  string
}

type SSEReader

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

func NewSSEReader

func NewSSEReader(r io.Reader) *SSEReader

func NewSSEReaderWithLimit added in v1.20.2

func NewSSEReaderWithLimit(r io.Reader, limit int) *SSEReader

NewSSEReaderWithLimit creates an SSE reader whose individual lines and accumulated event data are both bounded. Zero uses the safe default; a negative limit explicitly disables the bound.

func (*SSEReader) Read

func (r *SSEReader) Read() (*SSEMessage, error)

type StreamChoiceGuard added in v1.20.2

type StreamChoiceGuard struct {
	Protocol      string
	AllowMultiple bool
	// contains filtered or unexported fields
}

StreamChoiceGuard prevents alternative choices from being merged into a target with a single reply channel and validates provider terminal metadata.

func (*StreamChoiceGuard) Observe added in v1.20.2

func (g *StreamChoiceGuard) Observe(event *ir.StreamEvent) error

type StreamChoiceSelector added in v1.20.2

type StreamChoiceSelector struct {
	Protocol      string
	AllowMultiple bool
	// contains filtered or unexported fields
}

StreamChoiceSelector keeps one indexed choice for a target with a single reply channel. It returns nil for events belonging only to discarded alternatives and emits at most one compatibility warning. Unindexed usage and lifecycle events remain visible. Stateful metadata validation still observes every event, including discarded choices.

A foreign raw carrier is never returned: its typed companion events are the portable representation. When an owned raw carrier contains several choices and has typed companions, the carrier is dropped and the retained companions are unsuppressed so an owning writer cannot lose the selected reply.

func (*StreamChoiceSelector) Select added in v1.20.2

Select returns event when it belongs to the selected stream choice, nil when it should be discarded, and a one-time warning when an alternative is first discarded. The input event is not modified.

type StreamReader

type StreamReader interface {
	Read() (*ir.StreamEvent, error)
	Close() error
}

type StreamToolArgumentGuard added in v1.20.2

type StreamToolArgumentGuard struct {
	// Protocol is the destination protocol. Chat and Responses use an opaque
	// string; the other supported wires embed one complete JSON value.
	Protocol string
	// contains filtered or unexported fields
}

StreamToolArgumentGuard tracks tool-call ordering and identifies arguments that structured writers must preserve as JSON strings. Relays observe each selected normalized event before forwarding it to the destination writer.

func (*StreamToolArgumentGuard) Observe added in v1.20.2

func (g *StreamToolArgumentGuard) Observe(event *ir.StreamEvent) error

Observe records one normalized stream event. A safe finish validates and closes the calls in its scope. Empty arguments are accepted as the conventional no-argument call and are encoded as {} by protocol writers.

func (*StreamToolArgumentGuard) TakeWarnings added in v1.20.2

func (g *StreamToolArgumentGuard) TakeWarnings() []CompatibilityWarning

TakeWarnings drains compatibility warnings accumulated since the previous call. Warning messages never contain tool names, IDs, or argument bytes.

type StreamWriter

type StreamWriter interface {
	Write(*ir.StreamEvent) error
	Close() error
}

type UnsupportedContentError added in v1.20.2

type UnsupportedContentError struct {
	Protocol string
	Detail   string
}

UnsupportedContentError marks syntactically valid protocol content that the shared IR cannot represent without losing or changing its meaning. Callers must fail closed instead of applying the malformed-body text fallback.

func (*UnsupportedContentError) Error added in v1.20.2

func (e *UnsupportedContentError) Error() string

Source Files

  • choice.go
  • compatibility_warning.go
  • empty_image_degrade.go
  • helpers.go
  • logprobs.go
  • protocol.go
  • raw_validation.go
  • registry.go
  • response_content_normalization.go
  • responses_lifecycle.go
  • sse.go
  • stream_choice.go
  • stream_metadata.go
  • stream_raw.go
  • stream_tool_arguments.go
  • tool_arguments_fallback.go
  • unnamed_tool_call.go
  • unsupported_content.go
  • usage.go

Jump to

Keyboard shortcuts

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