Documentation
¶
Overview ¶
Package llm provides the shared LLM request and response parsing library consumed by proxy middleware. It is runtime agnostic: the same package is used by the native built-in executor now and will be reused by the WASM adapter later.
Index ¶
- Constants
- Variables
- type AnthropicParser
- func (AnthropicParser) DetectFromURL(path string) bool
- func (AnthropicParser) ExtractCompletion(status int, contentType string, body []byte) string
- func (AnthropicParser) ExtractPrompt(body []byte) string
- func (AnthropicParser) ExtractSessionID(body []byte) string
- func (AnthropicParser) ParseRequest(body []byte) (RequestFacts, error)
- func (AnthropicParser) ParseResponse(status int, contentType string, body []byte) (Usage, error)
- func (AnthropicParser) Provider() Provider
- func (AnthropicParser) ProviderName() string
- type BedrockParser
- func (BedrockParser) DetectFromURL(path string) bool
- func (BedrockParser) ExtractCompletion(status int, contentType string, body []byte) string
- func (BedrockParser) ExtractPrompt(body []byte) string
- func (BedrockParser) ExtractSessionID([]byte) string
- func (BedrockParser) ParseRequest([]byte) (RequestFacts, error)
- func (BedrockParser) ParseResponse(status int, contentType string, body []byte) (Usage, error)
- func (BedrockParser) Provider() Provider
- func (BedrockParser) ProviderName() string
- type Event
- type OpenAIParser
- func (OpenAIParser) DetectFromURL(path string) bool
- func (OpenAIParser) ExtractCompletion(status int, contentType string, body []byte) string
- func (OpenAIParser) ExtractPrompt(body []byte) string
- func (OpenAIParser) ExtractSessionID(body []byte) string
- func (OpenAIParser) ParseRequest(body []byte) (RequestFacts, error)
- func (OpenAIParser) ParseResponse(status int, contentType string, body []byte) (Usage, error)
- func (OpenAIParser) Provider() Provider
- func (OpenAIParser) ProviderName() string
- type Parser
- type Provider
- type RequestFacts
- type Scanner
- type Usage
Constants ¶
const ProviderNameBedrock = "bedrock"
ProviderNameBedrock is the stable label for the AWS Bedrock parser, used as the llm.provider metadata value and the cost-meter formula selector.
Variables ¶
var ( // ErrUnknownProvider indicates no parser claimed the request path. ErrUnknownProvider = errors.New("llmobs: unknown provider") // ErrUnsupportedModel indicates the response parsed successfully but the // model is absent from the pricing table. Token counts are still valid. ErrUnsupportedModel = errors.New("llmobs: unsupported model") // ErrNotLLMResponse indicates the response is not a JSON success body // that a non-streaming parser can consume (non-200 or wrong content type). ErrNotLLMResponse = errors.New("llmobs: not an LLM response") // ErrStreamingUnsupported indicates the caller passed an SSE response to // a non-streaming parser. Streaming is handled separately via the SSE // scanner. ErrStreamingUnsupported = errors.New("llmobs: streaming response requires SSE scanner") // ErrMalformedResponse indicates the response body could not be decoded // as the provider-specific JSON schema. ErrMalformedResponse = errors.New("llmobs: malformed response body") // ErrMalformedRequest indicates the request body could not be decoded as // the provider-specific JSON schema. ErrMalformedRequest = errors.New("llmobs: malformed request body") )
Sentinel errors returned by parsers and the pricing loader. Callers use errors.Is to branch on a condition without coupling to parser internals.
Functions ¶
This section is empty.
Types ¶
type AnthropicParser ¶
type AnthropicParser struct{}
AnthropicParser implements the Parser interface for the Anthropic Messages and Completions APIs. Detection is substring-based to tolerate upstream path rewrites.
func (AnthropicParser) DetectFromURL ¶
func (AnthropicParser) DetectFromURL(path string) bool
DetectFromURL reports whether the given request path looks like an Anthropic API endpoint. The match is case-insensitive and substring-based.
func (AnthropicParser) ExtractCompletion ¶
func (AnthropicParser) ExtractCompletion(status int, contentType string, body []byte) string
ExtractCompletion returns the assistant text from a non-streaming Anthropic Messages or Completions response. Returns "" when status/content-type indicate the body is not parseable or no text part is present.
func (AnthropicParser) ExtractPrompt ¶
func (AnthropicParser) ExtractPrompt(body []byte) string
ExtractPrompt returns the user-visible prompt text from an Anthropic request body. Handles the Messages API (system + messages[]) and the legacy /v1/complete prompt string. Returns "" on any decode failure.
func (AnthropicParser) ExtractSessionID ¶
func (AnthropicParser) ExtractSessionID(body []byte) string
ExtractSessionID is the body-side fallback for Anthropic. Claude Code's authoritative session marker is the X-Claude-Code-Session-Id request header (handled by the request-parser middleware); this only mines the optional metadata.user_id for an embedded "...session_<uuid>" marker. metadata.user_id on its own is a USER identifier, not a session, so the whole value is deliberately NOT used — returning it would mislabel every request from a user as one session. Returns "" when no session marker is present.
func (AnthropicParser) ParseRequest ¶
func (AnthropicParser) ParseRequest(body []byte) (RequestFacts, error)
ParseRequest extracts the model name and streaming flag from an Anthropic request body. Unknown or missing fields leave the corresponding struct members zero-valued.
func (AnthropicParser) ParseResponse ¶
ParseResponse decodes the non-streaming Anthropic response envelope. Status codes other than 200 are treated as non-LLM responses so the caller can skip cost accounting without aborting the request.
func (AnthropicParser) Provider ¶
func (AnthropicParser) Provider() Provider
Provider returns ProviderAnthropic.
func (AnthropicParser) ProviderName ¶
func (AnthropicParser) ProviderName() string
ProviderName returns the stable label used for metrics and metadata.
type BedrockParser ¶
type BedrockParser struct{}
BedrockParser implements the Parser interface for the AWS Bedrock runtime. Bedrock carries the model in the URL path (/model/{id}/{action}); the request middleware extracts it there, so this parser focuses on the response shapes: the vendor-native InvokeModel body (e.g. Anthropic's snake_case usage) and the unified Converse body (camelCase usage).
func (BedrockParser) DetectFromURL ¶
func (BedrockParser) DetectFromURL(path string) bool
DetectFromURL reports whether the path is a Bedrock runtime model endpoint.
func (BedrockParser) ExtractCompletion ¶
func (BedrockParser) ExtractCompletion(status int, contentType string, body []byte) string
ExtractCompletion returns the assistant text from a non-streaming Bedrock response, handling InvokeModel (Anthropic content[].text) and Converse (output.message.content[].text).
func (BedrockParser) ExtractPrompt ¶
func (BedrockParser) ExtractPrompt(body []byte) string
ExtractPrompt returns the user-visible prompt from a Bedrock request body, handling both the InvokeModel (Anthropic Messages: system + messages[]) and Converse (messages[].content[].text) shapes. Returns "" on decode failure.
func (BedrockParser) ExtractSessionID ¶
func (BedrockParser) ExtractSessionID([]byte) string
ExtractSessionID has no Bedrock-native marker; session grouping relies on the request headers handled by the middleware. Returns "".
func (BedrockParser) ParseRequest ¶
func (BedrockParser) ParseRequest([]byte) (RequestFacts, error)
ParseRequest is a no-op for Bedrock: the model lives in the URL path, not the body, and the streaming flag is derived from the path action. The request middleware handles both via parseBedrockPath, so this returns empty facts.
func (BedrockParser) ParseResponse ¶
ParseResponse decodes the non-streaming Bedrock response envelope, handling both the InvokeModel and Converse usage shapes. Non-200 / non-JSON bodies are treated as non-LLM responses so the caller skips cost accounting.
func (BedrockParser) Provider ¶
func (BedrockParser) Provider() Provider
Provider returns ProviderBedrock.
func (BedrockParser) ProviderName ¶
func (BedrockParser) ProviderName() string
ProviderName returns the stable label used for metrics and metadata.
type Event ¶
Event represents a single server-sent event. Type is the dispatch name carried on an "event:" line (empty when the stream uses only "data:" lines). Data is the concatenation of every "data:" line that made up the event, joined by a single newline.
type OpenAIParser ¶
type OpenAIParser struct{}
OpenAIParser implements the Parser interface for OpenAI-compatible APIs. It recognizes chat.completions, completions, embeddings, and the newer responses endpoint; any proxy path-prefix stripping is tolerated by the substring match in DetectFromURL.
func (OpenAIParser) DetectFromURL ¶
func (OpenAIParser) DetectFromURL(path string) bool
DetectFromURL reports whether the given request path looks like an OpenAI API endpoint. The match is case-insensitive and substring-based so that a reverse proxy prefix strip or rewrite does not defeat detection.
func (OpenAIParser) ExtractCompletion ¶
func (OpenAIParser) ExtractCompletion(status int, contentType string, body []byte) string
ExtractCompletion returns the assistant text from a non-streaming OpenAI response. Handles chat.completions (choices[].message.content), legacy completions (choices[].text), and Responses API (output[].content[].text or the convenience output_text field).
func (OpenAIParser) ExtractPrompt ¶
func (OpenAIParser) ExtractPrompt(body []byte) string
ExtractPrompt returns the user-visible prompt text from an OpenAI request. Handles chat.completions (messages[].content), legacy completions (prompt string), and the Responses API (input as string or content-part array). Returns "" when nothing extractable is found.
func (OpenAIParser) ExtractSessionID ¶
func (OpenAIParser) ExtractSessionID(body []byte) string
ExtractSessionID reads the OpenAI session marker. Codex (the Responses API client) stamps client_metadata.session_id on every request body; plain chat.completions traffic carries no session id and yields "".
func (OpenAIParser) ParseRequest ¶
func (OpenAIParser) ParseRequest(body []byte) (RequestFacts, error)
ParseRequest extracts the model name and streaming flag from an OpenAI request body. Unknown or missing fields leave the corresponding struct members zero-valued.
func (OpenAIParser) ParseResponse ¶
ParseResponse decodes the non-streaming OpenAI response envelope. Status codes other than 200 are treated as non-LLM responses so the caller can skip cost accounting without aborting the request.
func (OpenAIParser) Provider ¶
func (OpenAIParser) Provider() Provider
Provider returns ProviderOpenAI.
func (OpenAIParser) ProviderName ¶
func (OpenAIParser) ProviderName() string
ProviderName returns the stable label used for metrics and metadata.
type Parser ¶
type Parser interface {
Provider() Provider
ProviderName() string
DetectFromURL(path string) bool
ParseRequest(body []byte) (RequestFacts, error)
ParseResponse(status int, contentType string, body []byte) (Usage, error)
// ExtractPrompt returns the user-facing prompt text from a request body.
// Different endpoint shapes (chat.completions, responses, messages) are
// handled by the per-provider implementation. Returns "" when no prompt
// can be extracted; never returns an error — extraction is best-effort
// because callers use the result for observability, not authorization.
ExtractPrompt(body []byte) string
// ExtractCompletion returns the assistant-facing completion text from a
// non-streaming response body. status and contentType match the
// ParseResponse arguments so implementations can fast-fail uniformly.
ExtractCompletion(status int, contentType string, body []byte) string
// ExtractSessionID returns a stable identifier that groups requests of
// the same conversation / coding session, read from the per-provider
// location clients populate (e.g. OpenAI Codex's client_metadata.session_id,
// Claude Code's metadata.user_id). Returns "" when the body carries no
// recognised session marker; extraction is best-effort and never errors.
ExtractSessionID(body []byte) string
}
Parser is the per-provider interface implemented in this package. The dispatcher selects a parser by calling DetectFromURL against the incoming request path; ties break by registration order (see Parsers).
func DetectParser ¶
DetectParser returns the first parser whose DetectFromURL matches the given request path. ok=false means no parser claimed the path.
func ParserByName ¶
ParserByName returns the parser whose ProviderName matches id. Used by callers that already know which provider surface a request will hit (e.g. the agent-network middleware chain configured per synthesised service) so they can skip URL sniffing. ok=false when no parser is registered under that name.
type Provider ¶
type Provider int
Provider identifies an LLM API provider.
const ( // ProviderUnknown signals that no parser matched the request. ProviderUnknown Provider = 0 // ProviderOpenAI identifies the OpenAI API surface. ProviderOpenAI Provider = 1 // ProviderAnthropic identifies the Anthropic Messages API surface. ProviderAnthropic Provider = 2 // ProviderBedrock identifies the AWS Bedrock runtime surface. ProviderBedrock Provider = 3 )
type RequestFacts ¶
RequestFacts captures the subset of the LLM request body that the middleware annotates as metadata (model, streaming flag). Additional fields are added as parsers grow.
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner reads SSE events from an underlying byte stream. Events are delimited by a blank line ("\n\n"). CRLF line endings are normalized to LF transparently so fixtures captured from live servers can be replayed.
Scanner is not safe for concurrent use.
func NewScanner ¶
NewScanner wraps the given reader. The default underlying buffer size is large enough for typical provider events (~64 KiB); callers needing larger events can wrap the reader in their own bufio.Reader beforehand.
type Usage ¶
type Usage struct {
InputTokens int64
OutputTokens int64
TotalTokens int64
CachedInputTokens int64
CacheCreationTokens int64
}
Usage is the provider-agnostic token accounting emitted to metrics and access logs. Downstream consumers map InputTokens/OutputTokens to the plg.llm.* metadata allowlist entries.
CachedInputTokens carries OpenAI's prompt_tokens_details.cached_tokens (a SUBSET of InputTokens) when the response is from OpenAI, or Anthropic's cache_read_input_tokens (ADDITIVE to InputTokens) when from Anthropic. The cost meter switches formula on KeyLLMProvider so the two shapes are billed correctly without double-counting.
CacheCreationTokens carries Anthropic's cache_creation_input_tokens (ADDITIVE; not present in the OpenAI shape).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package pricing implements the embedded-default + override pricing table shared by middleware that converts LLM token usage into a USD cost estimate.
|
Package pricing implements the embedded-default + override pricing table shared by middleware that converts LLM token usage into a USD cost estimate. |