openaiprovider

package module
v0.1.0-preview.1 Latest Latest
Warning

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

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

README

Spice Agent OpenAI Provider

Unified documentation: spiceframework.dev/agent/providers/openai.

spice-agent-provider-openai is the explicit OpenAI Responses adapter for Spice Agent. It implements the exact model.Provider contract, owns no global state, and keeps model selection in each model.Request.

Install the provider and the exact Spice compiler tool:

go get github.com/spice-framework/spice-agent-provider-openai@<version>
go get -tool github.com/spice-framework/toolchain/cmd/spice@v0.1.0-preview.1.0.20260806203056-d0b9ac086bd6

Construct it directly when the application wants explicit ownership:

provider, err := openaiprovider.New(openaiprovider.Config{
	APIKey: os.Getenv("OPENAI_API_KEY"),
})

Construction validates configuration but performs no network request. The provider never reads environment variables itself; the example deliberately shows application-owned configuration. A request must choose its model through model.Request.Model. A zero timeout selects two minutes; configured request timeouts must be positive and no greater than thirty minutes.

BaseURL must normally be an absolute HTTPS URL without user information. Plain HTTP is accepted only for the exact localhost host or a parsed IPv4 or IPv6 loopback literal, which supports local OpenAI-compatible test bridges without weakening remote endpoint validation. Loopback HTTP is plaintext: use it only with a trusted local process and local-only credentials. Lookalike names, wildcard addresses, and non-loopback hosts fail validation.

Applications may opt into one replaceable fallback bean with an explicit blank import:

import _ "github.com/spice-framework/spice-agent-provider-openai/autoconfigure"

Importing the root package alone never activates a provider. There is no registry, service locator, package scan, or hidden install step.

Streaming contract

The adapter translates provider-neutral messages and function tools to the Responses API and returns text deltas, finalized function calls, usage, and a single completion event. Provider-hosted executable tools and unknown extension parts fail closed. Output text and tool calls use the core operation limits. The generated request sets store=false. Only a tool's model-facing name, description, and input schema cross the provider boundary. Its effect, replay safety, capabilities, and complete fingerprint remain host policy metadata and are never serialized into an OpenAI request, event, diagnostic, or log.

Failures before a stream exists are model.ProviderError; receive failures are model.StreamError. Provider retries are bounded and permitted only before the SDK has returned a stream. Spice never replays an observed or ambiguous stream. All public failures are redacted. One goroutine may call Recv while another calls Close; concurrent Recv calls are not supported.

Successful and failed terminal events can carry a small allowlisted metadata record. To retain it in engine observations, composition must explicitly allowlist openaiprovider.MetadataNamespace in agent.EngineOptions. The record is limited to response/request IDs, model, status, service tier, and HTTP status; it cannot contain prompts, results, tool arguments, headers, tokens, keys, URLs, or raw provider objects.

On a fresh clone, run make tools-bootstrap once to populate the exact product and tools module graphs without changing tracked module files. All ordinary quality targets remain offline. Run the offline suite with make verify.

Opt-in live acceptance

The live proof is excluded from ordinary test binaries by the openai_live build tag and remains disabled unless SPICE_OPENAI_LIVE is exactly 1. Choose the model explicitly so account owners retain cost and compatibility control. For PowerShell:

$env:SPICE_OPENAI_LIVE = "1"
$env:OPENAI_API_KEY = "<secret>"
$env:OPENAI_MODEL = "<supported-model>"
make live-acceptance

For Linux and macOS shells:

SPICE_OPENAI_LIVE=1 OPENAI_API_KEY='<secret>' OPENAI_MODEL='<supported-model>' make live-acceptance

This command makes one real, billable Responses API streaming request over the network. Pricing, rate limits, data handling, and model availability are those of the selected OpenAI account and model. The proof sends one short text prompt, declares no tools, sets store=false, disables SDK retries, uses a 90-second client/context timeout, caps observation at 128 events and 4 KiB of text, and requires exact spice-live-ok text followed by terminal completion. It never prints the key or upstream provider details. Remove the environment variables from the shell after the run.

See the dependency review, security review, and support matrix.

Release contract

spice-release.json is inert, canonical metadata for the centrally authorized go-module-v1 release profile. make verify-release runs the repository's complete local gate. The organization release authority independently binds the repository name, module path, exact preview version, required module graph, commit, and tag before it creates any artifact or release. Tag pushes call the single-job, secret-free reusable workflow at audited organization commit 0fcd43dc8b41fad56c231d0e136ad8c762276ed5; repository verification rejects caller, module, permission, step, job, and secret drift before product tests.

Documentation

Overview

Package openaiprovider provides the instance-owned OpenAI Responses client used by the Spice Agent model adapter.

Index

Constants

View Source
const MetadataNamespace = "github.com/spice-framework/spice-agent-provider-openai"

MetadataNamespace is the exact provider extension namespace applications may allowlist in agent.EngineOptions. Its values never contain content, credentials, headers, URLs, or raw provider payloads.

Variables

This section is empty.

Functions

func Manifest

func Manifest() spicestarter.Manifest

Manifest returns OpenAI provider compatibility and review metadata.

Types

type Client

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

Client owns one configured OpenAI Responses service. Construction performs no network I/O and never consults ambient OpenAI environment variables.

func New

func New(config Config, options ...ClientOption) (*Client, error)

New validates configuration and constructs an instance-owned Responses client without making a request.

func (*Client) Stream

func (client *Client) Stream(ctx context.Context, request model.Request) (model.Stream, error)

Stream translates one provider-neutral request into an OpenAI Responses stream. Request.Model is authoritative; configuration never overrides it. The returned stream supports one Recv caller racing with Close. Concurrent Recv calls are outside the model.Stream contract.

type ClientOption

type ClientOption func(*clientOptions) error

ClientOption customizes client construction without adding hidden globals.

func WithHTTPClient

func WithHTTPClient(client *http.Client) ClientOption

WithHTTPClient supplies an instance-owned HTTP client, typically for tests or application-specific transport policy.

type Config

type Config struct {
	APIKey       string        `spice:"api-key,required,secret,env=OPENAI_API_KEY"`
	BaseURL      string        `spice:"base-url,default=https://api.openai.com/v1,env=OPENAI_BASE_URL"`
	Organization string        `spice:"organization,env=OPENAI_ORGANIZATION"`
	Project      string        `spice:"project,env=OPENAI_PROJECT"`
	Timeout      time.Duration `spice:"timeout,default=2m,env=OPENAI_TIMEOUT"`
	MaxRetries   int           `spice:"max-retries,default=0,env=OPENAI_MAX_RETRIES"`
}

Config is the typed, secret-aware configuration for one provider instance. APIKey is deliberately excluded from String output and validation errors. BaseURL requires HTTPS except for explicit localhost or IP-loopback HTTP test bridges; loopback HTTP provides no transport security. A zero Timeout selects two minutes; explicit values must not exceed thirty minutes.

func (Config) String

func (config Config) String() string

String returns a diagnostic-safe summary.

type Error

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

Error is bounded, redacted OpenAI failure metadata. It deliberately excludes response bodies, prompts, tool data, request URLs, and authorization headers.

func (*Error) Code

func (failure *Error) Code() string

Code returns the stable provider-owned category.

func (*Error) Error

func (failure *Error) Error() string

Error returns diagnostic-safe failure text.

func (*Error) RequestID

func (failure *Error) RequestID() string

RequestID returns the bounded OpenAI request identity when supplied.

func (*Error) Retryable

func (failure *Error) Retryable() bool

Retryable reports whether a failure happened before an observed stream and is safe to retry with the operation's stable idempotency key.

func (*Error) StatusCode

func (failure *Error) StatusCode() int

StatusCode returns an HTTP status, or zero when no response was received.

func (*Error) Unwrap

func (failure *Error) Unwrap() error

Unwrap preserves only context cancellation and deadline causes. Upstream SDK errors are intentionally not exposed because they can include request URLs or response bodies.

Directories

Path Synopsis
Package autoconfigure contributes the default OpenAI client only when an application explicitly blank-imports this package.
Package autoconfigure contributes the default OpenAI client only when an application explicitly blank-imports this package.
internal
qualitygate command
Command qualitygate runs this repository's cross-platform quality contract.
Command qualitygate runs this repository's cross-platform quality contract.

Jump to

Keyboard shortcuts

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