chat

package
v2.3.1 Latest Latest
Warning

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

Go to latest
Published: May 2, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package chat is stroma's OpenAI-compatible chat completion primitive, the sibling of embed.OpenAI. It ships the narrow HTTP surface — request shape, retry / Retry-After, classified errors, response-size bounding — plus a product-neutral JSON object decoding helper. Prompt templating, semantic validation of model outputs, and runtime-specific labelling stay at the caller.

Constructed like embed.OpenAI:

client := chat.NewOpenAI(chat.OpenAIConfig{
    BaseURL:    "https://api.openai.com/v1",
    Model:      "gpt-4o-mini",
    APIToken:   os.Getenv("OPENAI_API_KEY"),
    Timeout:    30 * time.Second,
    MaxRetries: 2,
})
text, err := client.ChatCompletionText(ctx, []chat.Message{
    {Role: "system", Content: "..."},
    {Role: "user", Content: question},
}, 0, 512)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractJSONObject added in v2.3.0

func ExtractJSONObject(text string) (json.RawMessage, error)

ExtractJSONObject extracts a single JSON object from assistant text. It accepts a bare object, a Markdown-fenced object, or prose wrapped around an object. Valid JSON whose root is not an object is rejected rather than mining nested objects out of the wrong shape.

func ExtractMessageText

func ExtractMessageText(raw json.RawMessage) (string, bool)

ExtractMessageText returns the text content of a chat choice message and whether the content had a recognised shape. The chat protocol defines content as either a plain string ({"content":"..."}) or a multi-part array used by tool-capable models ({"content":[{"type":"text","text":"..."}]}); any other shape (object, number, bool, null) returns ("", false) so the caller can classify the response as schema_mismatch rather than persist raw JSON as assistant text.

Types

type JSONCallRequest added in v2.3.0

type JSONCallRequest struct {
	Messages    []Message
	Temperature float64
	MaxTokens   int
	Schema      json.RawMessage
	Retry       JSONRetryPolicy
}

JSONCallRequest configures one structured JSON chat completion call.

Schema is optional JSON Schema. When present, it is sent to the OpenAI-compatible endpoint as response_format.type=json_schema with a neutral schema name; Stroma still validates the assistant response client-side and returns schema_mismatch for malformed, missing, or non-object JSON.

type JSONRetryPolicy added in v2.3.0

type JSONRetryPolicy struct {
	MaxRepairs int
	// RepairMessage overrides the generic repair instruction appended
	// after a malformed JSON response.
	RepairMessage string
}

JSONRetryPolicy controls the bounded client-side repair pass for ChatCompletionJSON. MaxRepairs values above one are capped at one so a malformed response cannot turn into an autonomous loop.

type Message

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

Message is one item in a chat completion request. Matches the OpenAI chat-completion protocol.

type OpenAI

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

OpenAI is an OpenAI-compatible chat completion client. Safe for concurrent use; callers may share a single *OpenAI across a long-lived service.

func NewOpenAI

func NewOpenAI(cfg OpenAIConfig) *OpenAI

NewOpenAI returns a client bound to cfg.

func (*OpenAI) ChatCompletionJSON added in v2.3.0

func (c *OpenAI) ChatCompletionJSON(ctx context.Context, req JSONCallRequest, target any) error

ChatCompletionJSON sends messages to the chat completion endpoint, extracts a JSON object from the assistant response, and decodes it into target. Invalid JSON, missing JSON, non-object JSON, and typed decode failures are classified as provider.FailureClassSchemaMismatch.

The helper is deliberately product-neutral: callers own prompts, schema design, and any semantic validation after decoding.

func (*OpenAI) ChatCompletionText

func (c *OpenAI) ChatCompletionText(ctx context.Context, messages []Message, temperature float64, maxTokens int) (string, error)

ChatCompletionText sends messages to the chat completion endpoint and returns the assistant text. Retries, Retry-After, and failure classification are handled by the shared provider core. Decode failures, empty choices, and empty message text are all reported as FailureClassSchemaMismatch — they are chat-protocol invariants, not product-JSON-shape concerns.

func (*OpenAI) Config

func (c *OpenAI) Config() OpenAIConfig

Config returns the normalized config.

func (*OpenAI) Unconfigured

func (c *OpenAI) Unconfigured() bool

Unconfigured reports whether the client is missing a base URL or model.

type OpenAIConfig

type OpenAIConfig struct {
	BaseURL string
	Model   string

	// Timeout bounds a single chat completion request. A zero or
	// negative value selects defaultChatTimeout (30s) at NewOpenAI
	// time. Callers that want a tighter global cap should pass a ctx
	// with their own deadline; the client honours whichever deadline
	// trips first.
	Timeout  time.Duration
	APIToken string

	// MaxRetries caps the number of retry attempts after a retryable
	// failure (429, 5xx, connection reset, timeout). Zero disables
	// retries; negative values normalize to zero. Retry-After is always
	// honoured when present.
	MaxRetries int

	// MaxResponseBytes bounds the response body; zero selects the
	// provider default (4 MiB). Chat completions fit comfortably in
	// the default.
	MaxResponseBytes int64
}

OpenAIConfig configures an OpenAI-compatible chat completion client.

APIToken is redacted from every log/display representation — String, GoString, and slog.LogValuer all render the token as "[REDACTED]". Direct field access still yields the raw value so the client can sign requests.

json.Marshal and encoding.TextMarshaler stay canonical: OpenAIConfig is a public configuration type, and overriding either would silently break callers that persist or round-trip the config. Callers that need a redacted JSON view should marshal cfg.String() or build a dedicated view type.

func (OpenAIConfig) Enabled

func (c OpenAIConfig) Enabled() bool

Enabled reports whether the config is usable for requests.

func (OpenAIConfig) GoString

func (c OpenAIConfig) GoString() string

GoString returns a redacted Go-syntax rendering for %#v. Timeout is emitted as time.Duration(ns) so the result stays a valid Go literal.

func (OpenAIConfig) LogValue

func (c OpenAIConfig) LogValue() slog.Value

LogValue implements slog.LogValuer so slog handlers render the config with APIToken redacted.

func (OpenAIConfig) String

func (c OpenAIConfig) String() string

String returns a redacted, human-readable rendering of the config.

Jump to

Keyboard shortcuts

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