Documentation
¶
Index ¶
- Constants
- Variables
- func BuildOpenAIResponsesParams(model Model[API], modelContext ModelContext, options *OpenAIResponseOptions) (responses.ResponseNewParams, error)
- func CleanupSessionResources(sessionID *string) error
- func ClearApiProviders()
- func ConvertResponsesMessages(model Model[API], modelContext ModelContext, providers map[Provider]struct{}, ...) (responses.ResponseInputParam, error)
- func ConvertResponsesTools(tools []*Tool, options *ConvertResponsesToolsOptions) ([]responses.ToolUnionParam, error)
- func CreateOpenAIResponsesClient(model Model[API], modelContext ModelContext, apiKey *string, ...) (responses.ResponseService, error)
- func DefaultProviderAuth() map[Provider]ProviderAuth
- func EncodeTextSignatureV1(id string, phase *TextSignaturePhase) string
- func GetPromptCacheRetention(compat ResolvedOpenAIResponsesCompat, cacheRetention CacheRetention) responses.ResponseNewParamsPromptCacheRetention
- func IsContextOverflow(message AssistantMessage, contextWindow int) bool
- func MergeHeaders(layers ...map[string]string) map[string]string
- func ModelsAreEqual[TApi API](a *Model[TApi], b *Model[TApi]) bool
- func RegisterApiProvider[TApi API](provider ApiProvider[TApi, StreamOptions], sourceID *string)
- func RegisterSessionResourceCleanup(cleanup SessionResourceCleanup) func()
- func UnregisterApiProvider(sourceID string)
- func ValidateToolArguments(tool Tool, toolCall ToolCall) (any, error)
- func ValidateToolCall(tools []*Tool, toolCall ToolCall) (any, error)
- type API
- type APIKeyAuth
- type ApiProvider
- type ApiProviderInternal
- type ApiStreamFunction
- type ApiStreamSimpleFunction
- type AssistantContent
- type AssistantMessage
- type AssistantMessageDiagnostic
- type AssistantMessageEvent
- type AssistantMessageEventStream
- func NewAssistantMessageEventStream(buffer int) *AssistantMessageEventStream
- func Stream(model Model[API], modelContext ModelContext, options *StreamOptions) (*AssistantMessageEventStream, error)
- func StreamOpenAIResponse(ctx context.Context, model Model[API], modelContext ModelContext, ...) (*AssistantMessageEventStream, error)
- func StreamOpenAIResponses(model Model[API], modelContext ModelContext, options *StreamOptions) (*AssistantMessageEventStream, error)
- func StreamSimple(model Model[API], modelContext ModelContext, options *SimpleStreamOptions) (*AssistantMessageEventStream, error)
- func StreamSimpleOpenAIResponses(model Model[API], modelContext ModelContext, options *SimpleStreamOptions) (*AssistantMessageEventStream, error)
- type AssistantMessageEventType
- type AuthCheck
- type AuthContext
- type AuthError
- type AuthErrorCode
- type AuthEvent
- type AuthEventType
- type AuthInteraction
- type AuthPrompt
- type AuthPromptOption
- type AuthPromptType
- type AuthResolutionOverrides
- type AuthResult
- type CacheRetention
- type ContentType
- type ConvertResponseMessagesOptions
- type ConvertResponsesToolsOptions
- type Cost
- type Credential
- type CredentialInfo
- type CredentialStore
- type CredentialType
- type DiagnosticErrorInfo
- type DoneEvent
- type ErrorEvent
- type EventStream
- type ImageContent
- type InMemoryCredentialStore
- func (s *InMemoryCredentialStore) Delete(ctx context.Context, provider Provider) error
- func (s *InMemoryCredentialStore) List(ctx context.Context) ([]CredentialInfo, error)
- func (s *InMemoryCredentialStore) Modify(ctx context.Context, provider Provider, ...) (*Credential, error)
- func (s *InMemoryCredentialStore) Read(ctx context.Context, provider Provider) (*Credential, error)
- type Message
- type Model
- type ModelAuth
- type ModelContext
- type ModelThinkingLevel
- type OAuthAuth
- type OAuthToken
- type OpenAIResponseOptions
- type OpenAIResponsesCompat
- type ParsedTextSignature
- type Provider
- type ProviderAuth
- type ProviderResponse
- type RegisteredApiProvider
- type ResolvedOpenAIResponsesCompat
- type Role
- type SessionResourceCleanup
- type SimpleStreamOptions
- type StartEvent
- type StopReason
- type StreamFunction
- type StreamOptions
- type TextContent
- type TextDeltaEvent
- type TextEndEvent
- type TextSignaturePhase
- type TextStartEvent
- type ThinkingBudgets
- type ThinkingContent
- type ThinkingDeltaEvent
- type ThinkingEndEvent
- type ThinkingLevelMap
- type ThinkingStartEvent
- type Tool
- type ToolCall
- type ToolCallDeltaEvent
- type ToolCallEndEvent
- type ToolCallStartEvent
- type ToolResultContent
- type ToolResultMessage
- type Transport
- type Usage
- type UserContent
- type UserMessage
Constants ¶
const ( // DefaultMaxRetries is how many times a failed request is retried when // StreamOptions.MaxRetries is nil. It matches the OpenAI SDKs' default. DefaultMaxRetries = 2 // DefaultTimeout is how long a request waits for its response to start when // StreamOptions.TimeoutMs is nil. It matches the OpenAI Node SDK's default. DefaultTimeout = 10 * time.Minute // DefaultMaxRetriesDelay is the longest server-requested retry delay waited // out when StreamOptions.MaxRetriesDelayMs is nil. DefaultMaxRetriesDelay = 60 * time.Second )
const NonVisionToolImagePlaceholder = "(tool image omitted: model does not support images)"
const NonVisionUserImagePlaceholder = "(image omitted: model does not support images)"
Variables ¶
var Models = map[Provider]map[string]Model[API]{ ProviderOpenAI: { "gpt-4": { ID: "gpt-4", Name: "GPT-4", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text"}, Cost: Cost{ Input: decimal.MustParse("30"), Output: decimal.MustParse("60"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 8192, MaxTokens: 8192, }, "gpt-4-turbo": { ID: "gpt-4-turbo", Name: "GPT-4 Turbo", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("10"), Output: decimal.MustParse("30"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 4096, }, "gpt-4.1": { ID: "gpt-4.1", Name: "GPT-4.1", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2"), Output: decimal.MustParse("8"), CacheRead: decimal.MustParse("0.5"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 1047576, MaxTokens: 32768, }, "gpt-4.1-mini": { ID: "gpt-4.1-mini", Name: "GPT-4.1 mini", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.4"), Output: decimal.MustParse("1.6"), CacheRead: decimal.MustParse("0.1"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 1047576, MaxTokens: 32768, }, "gpt-4.1-nano": { ID: "gpt-4.1-nano", Name: "GPT-4.1 nano", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.1"), Output: decimal.MustParse("0.4"), CacheRead: decimal.MustParse("0.025"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 1047576, MaxTokens: 32768, }, "gpt-4o": { ID: "gpt-4o", Name: "GPT-4o", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2.5"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("1.25"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 16384, }, "gpt-4o-2024-05-13": { ID: "gpt-4o-2024-05-13", Name: "GPT-4o (2024-05-13)", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("5"), Output: decimal.MustParse("15"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 4096, }, "gpt-4o-2024-08-06": { ID: "gpt-4o-2024-08-06", Name: "GPT-4o (2024-08-06)", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2.5"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("1.25"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 16384, }, "gpt-4o-2024-11-20": { ID: "gpt-4o-2024-11-20", Name: "GPT-4o (2024-11-20)", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2.5"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("1.25"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 16384, }, "gpt-4o-mini": { ID: "gpt-4o-mini", Name: "GPT-4o mini", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.15"), Output: decimal.MustParse("0.6"), CacheRead: decimal.MustParse("0.075"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 16384, }, "gpt-5": { ID: "gpt-5", Name: "GPT-5", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.25"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("0.125"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5-chat-latest": { ID: "gpt-5-chat-latest", Name: "GPT-5 Chat Latest", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.25"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("0.125"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 16384, }, "gpt-5-mini": { ID: "gpt-5-mini", Name: "GPT-5 Mini", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.25"), Output: decimal.MustParse("2"), CacheRead: decimal.MustParse("0.025"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5-nano": { ID: "gpt-5-nano", Name: "GPT-5 Nano", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.05"), Output: decimal.MustParse("0.4"), CacheRead: decimal.MustParse("0.005"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5-pro": { ID: "gpt-5-pro", Name: "GPT-5 Pro", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("15"), Output: decimal.MustParse("120"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 272000, }, "gpt-5.1": { ID: "gpt-5.1", Name: "GPT-5.1", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.25"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("0.125"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5.1-codex": { ID: "gpt-5.1-codex", Name: "GPT-5.1 Codex", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.25"), Output: decimal.MustParse("5"), CacheRead: decimal.MustParse("0.125"), CacheWrite: decimal.MustParse("1.25"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5.1-codex-max": { ID: "gpt-5.1-codex-max", Name: "GPT-5.1 Codex Max", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.25"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("0.125"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5.2": { ID: "gpt-5.2", Name: "GPT-5.2", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.75"), Output: decimal.MustParse("14"), CacheRead: decimal.MustParse("0.175"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5.2-chat-latest": { ID: "gpt-5.2-chat-latest", Name: "GPT-5.2 Chat", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.75"), Output: decimal.MustParse("14"), CacheRead: decimal.MustParse("0.175"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 16384, }, "gpt-5.2-pro": { ID: "gpt-5.2-pro", Name: "GPT-5.2 Pro", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("21"), Output: decimal.MustParse("168"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5.3-chat-latest": { ID: "gpt-5.3-chat-latest", Name: "GPT-5.3 Chat (latest)", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: false, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.75"), Output: decimal.MustParse("14"), CacheRead: decimal.MustParse("0.175"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 16384, }, "gpt-5.3-codex": { ID: "gpt-5.3-codex", Name: "GPT-5.3 Codex", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.75"), Output: decimal.MustParse("14"), CacheRead: decimal.MustParse("0.175"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5.3-codex-spark": { ID: "gpt-5.3-codex-spark", Name: "GPT-5.3 Codex Spark", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.75"), Output: decimal.MustParse("14"), CacheRead: decimal.MustParse("0.175"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 32000, }, "gpt-5.4": { ID: "gpt-5.4", Name: "GPT-5.4", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2.5"), Output: decimal.MustParse("15"), CacheRead: decimal.MustParse("0.25"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 272000, MaxTokens: 128000, }, "gpt-5.4-mini": { ID: "gpt-5.4-mini", Name: "GPT-5.4 mini", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.75"), Output: decimal.MustParse("4.5"), CacheRead: decimal.MustParse("0.075"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5.4-nano": { ID: "gpt-5.4-nano", Name: "GPT-5.4 nano", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.2"), Output: decimal.MustParse("1.25"), CacheRead: decimal.MustParse("0.02"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-5.4-pro": { ID: "gpt-5.4-pro", Name: "GPT-5.4 Pro", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("30"), Output: decimal.MustParse("180"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-5.5": { ID: "gpt-5.5", Name: "GPT-5.5", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("5"), Output: decimal.MustParse("30"), CacheRead: decimal.MustParse("0.5"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 272000, MaxTokens: 128000, }, "gpt-5.5-pro": { ID: "gpt-5.5-pro", Name: "GPT-5.5 Pro", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, ThinkingLevelXHigh: modelThinkingLevel("xhigh"), }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("30"), Output: decimal.MustParse("180"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-5.6": { ID: "gpt-5.6", Name: "GPT-5.6", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("4"), Output: decimal.MustParse("20"), CacheRead: decimal.MustParse("0.4"), CacheWrite: decimal.MustParse("5"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-5.6-luna": { ID: "gpt-5.6-luna", Name: "GPT-5.6 Luna", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.2"), Output: decimal.MustParse("1.2"), CacheRead: decimal.MustParse("0.02"), CacheWrite: decimal.MustParse("0.25"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-5.6-sol": { ID: "gpt-5.6-sol", Name: "GPT-5.6 Sol", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("4"), Output: decimal.MustParse("20"), CacheRead: decimal.MustParse("0.4"), CacheWrite: decimal.MustParse("5"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-5.6-terra": { ID: "gpt-5.6-terra", Name: "GPT-5.6 Terra", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, ThinkingLevelMap: ThinkingLevelMap{ ThinkingLevelOff: nil, }, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2"), Output: decimal.MustParse("12"), CacheRead: decimal.MustParse("0.2"), CacheWrite: decimal.MustParse("2.5"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-6-astra": { ID: "gpt-6-astra", Name: "GPT-6 Astra", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("10"), Output: decimal.MustParse("50"), CacheRead: decimal.MustParse("1"), CacheWrite: decimal.MustParse("12.5"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-6-luna": { ID: "gpt-6-luna", Name: "GPT-6 Luna", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("0.1"), Output: decimal.MustParse("0.5"), CacheRead: decimal.MustParse("0.01"), CacheWrite: decimal.MustParse("0.125"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-6-sol": { ID: "gpt-6-sol", Name: "GPT-6 Sol", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("0.2"), CacheWrite: decimal.MustParse("2.5"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-6.1-sol": { ID: "gpt-6.1-sol", Name: "GPT-6.1 Sol", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2"), Output: decimal.MustParse("10"), CacheRead: decimal.MustParse("0.1"), CacheWrite: decimal.MustParse("2.5"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-daybreak-blue-latest": { ID: "gpt-daybreak-blue-latest", Name: "Daybreak Blue", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("4"), Output: decimal.MustParse("20"), CacheRead: decimal.MustParse("0.4"), CacheWrite: decimal.MustParse("5"), }, ContextWindow: 1050000, MaxTokens: 128000, }, "gpt-daybreak-red-latest": { ID: "gpt-daybreak-red-latest", Name: "Daybreak Red", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("12.5"), Output: decimal.MustParse("75"), CacheRead: decimal.MustParse("1.25"), CacheWrite: decimal.MustParse("15.625"), }, ContextWindow: 400000, MaxTokens: 128000, }, "gpt-realtime-2.1": { ID: "gpt-realtime-2.1", Name: "GPT-Realtime-2.1", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("4"), Output: decimal.MustParse("24"), CacheRead: decimal.MustParse("0.4"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 128000, MaxTokens: 32000, }, "o1": { ID: "o1", Name: "o1", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("15"), Output: decimal.MustParse("60"), CacheRead: decimal.MustParse("7.5"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 200000, MaxTokens: 100000, }, "o1-pro": { ID: "o1-pro", Name: "o1-pro", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("150"), Output: decimal.MustParse("600"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 200000, MaxTokens: 100000, }, "o3": { ID: "o3", Name: "o3", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("2"), Output: decimal.MustParse("8"), CacheRead: decimal.MustParse("0.5"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 200000, MaxTokens: 100000, }, "o3-mini": { ID: "o3-mini", Name: "o3-mini", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text"}, Cost: Cost{ Input: decimal.MustParse("1.1"), Output: decimal.MustParse("4.4"), CacheRead: decimal.MustParse("0.55"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 200000, MaxTokens: 100000, }, "o3-pro": { ID: "o3-pro", Name: "o3-pro", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("20"), Output: decimal.MustParse("80"), CacheRead: decimal.MustParse("0"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 200000, MaxTokens: 100000, }, "o4-mini": { ID: "o4-mini", Name: "o4-mini", API: APIOpenAIResponses, Provider: ProviderOpenAI, BaseURL: "https://api.openai.com/v1", Reasoning: true, Input: []string{"text", "image"}, Cost: Cost{ Input: decimal.MustParse("1.1"), Output: decimal.MustParse("4.4"), CacheRead: decimal.MustParse("0.275"), CacheWrite: decimal.MustParse("0"), }, ContextWindow: 200000, MaxTokens: 100000, }, }, }
var OpenAIToolCallProviders = map[Provider]struct{}{
ProviderOpenAI: {},
}
Functions ¶
func BuildOpenAIResponsesParams ¶
func BuildOpenAIResponsesParams( model Model[API], modelContext ModelContext, options *OpenAIResponseOptions, ) (responses.ResponseNewParams, error)
func CleanupSessionResources ¶
func ClearApiProviders ¶
func ClearApiProviders()
func ConvertResponsesMessages ¶
func ConvertResponsesMessages(model Model[API], modelContext ModelContext, providers map[Provider]struct{}, options ConvertResponseMessagesOptions) (responses.ResponseInputParam, error)
func ConvertResponsesTools ¶
func ConvertResponsesTools( tools []*Tool, options *ConvertResponsesToolsOptions, ) ([]responses.ToolUnionParam, error)
func CreateOpenAIResponsesClient ¶
func CreateOpenAIResponsesClient( model Model[API], modelContext ModelContext, apiKey *string, optionHeaders *map[string]string, sessionID *string, ) (responses.ResponseService, error)
CreateOpenAIResponsesClient returns a Responses client configured only from its arguments. Unlike openai.NewClient, it reads no environment variables, so a server's OPENAI_BASE_URL, OPENAI_ORG_ID or OPENAI_PROJECT_ID cannot leak into a request made with a user's key.
func DefaultProviderAuth ¶ added in v0.6.0
func DefaultProviderAuth() map[Provider]ProviderAuth
DefaultProviderAuth returns the auth of the built-in providers. Each call returns a new map, so callers may change it.
func EncodeTextSignatureV1 ¶
func EncodeTextSignatureV1(id string, phase *TextSignaturePhase) string
func GetPromptCacheRetention ¶
func GetPromptCacheRetention( compat ResolvedOpenAIResponsesCompat, cacheRetention CacheRetention, ) responses.ResponseNewParamsPromptCacheRetention
func IsContextOverflow ¶ added in v0.3.0
func IsContextOverflow(message AssistantMessage, contextWindow int) bool
IsContextOverflow reports whether message indicates that the input exceeded the model's context window. It recognizes known provider errors, successful stops with Input + CacheRead greater than contextWindow, and length stops with zero output and Input + CacheRead filling at least 99% of contextWindow.
A non-positive contextWindow disables usage-based checks, but not error matching. Rate-limit, throttling, and service-unavailable errors are not context overflow. Silent input truncation without one of these signals cannot be detected.
func MergeHeaders ¶ added in v0.6.0
MergeHeaders merges header maps into a new map. Later maps win, and names compare case-insensitively, so "authorization" replaces "Authorization". The winning spelling is kept. It returns nil when there are no headers.
func RegisterApiProvider ¶
func RegisterApiProvider[TApi API](provider ApiProvider[TApi, StreamOptions], sourceID *string)
func RegisterSessionResourceCleanup ¶
func RegisterSessionResourceCleanup(cleanup SessionResourceCleanup) func()
func UnregisterApiProvider ¶
func UnregisterApiProvider(sourceID string)
func ValidateToolArguments ¶
ValidateToolArguments validates tool call arguments against the tool's JSON schema.
Types ¶
type APIKeyAuth ¶ added in v0.6.0
type APIKeyAuth struct {
// Name is shown to the user, such as "OpenAI API key".
Name string
// Login asks the user for a key and returns the credential to store. Nil
// means the provider only uses ambient auth.
Login func(ctx context.Context, in AuthInteraction) (*Credential, error)
// Check optionally reports whether auth is configured without request-time
// work. Set it when Resolve runs commands or makes network calls; without
// it, checks call Resolve.
Check func(ctx context.Context, env AuthContext, cred *Credential) (*AuthCheck, error)
// Resolve builds request auth from cred, which may be nil, and env. It
// returns nil, nil when the provider is not configured.
Resolve func(ctx context.Context, env AuthContext, cred *Credential) (*AuthResult, error)
}
APIKeyAuth is API key auth: a stored key or provider config, plus ambient sources such as environment variables.
func EnvAPIKeyAuth ¶ added in v0.6.0
func EnvAPIKeyAuth(name string, envVars ...string) *APIKeyAuth
EnvAPIKeyAuth is standard API key auth: a stored key wins, otherwise the first of envVars that is set. Login asks for the key. Providers that resolve differently, such as from provider config, credential files or IAM, write their own APIKeyAuth.
type ApiProvider ¶
type ApiProvider[TApi API, TOptions any] struct { Api TApi Stream StreamFunction[TApi, TOptions] StreamSimple StreamFunction[TApi, SimpleStreamOptions] }
type ApiProviderInternal ¶
type ApiProviderInternal struct {
Api API
Stream ApiStreamFunction
StreamSimple ApiStreamSimpleFunction
}
func GetApiProvider ¶
func GetApiProvider(api API) (ApiProviderInternal, bool)
func GetApiProviders ¶
func GetApiProviders() []ApiProviderInternal
func ResolveAPIProvider ¶
func ResolveAPIProvider(api API) (ApiProviderInternal, error)
type ApiStreamFunction ¶
type ApiStreamFunction func( Model Model[API], ModelContext ModelContext, Options *StreamOptions, ) (*AssistantMessageEventStream, error)
type ApiStreamSimpleFunction ¶
type ApiStreamSimpleFunction func( model Model[API], ModelContext ModelContext, options *SimpleStreamOptions, ) (*AssistantMessageEventStream, error)
type AssistantContent ¶
type AssistantContent interface {
// contains filtered or unexported methods
}
type AssistantMessage ¶
type AssistantMessage struct {
Role Role `json:"role"`
Content []AssistantContent `json:"content"`
Api API `json:"api"`
Provider Provider `json:"provider"`
Model string `json:"model"`
ResponseModel *string `json:"responseModel,omitempty"`
ResponseID *string `json:"responseId,omitempty"`
Diagnostics []AssistantMessageDiagnostic `json:"diagnostics,omitempty"`
Usage Usage `json:"usage"`
StopReason StopReason `json:"stopReason"`
ErrorMessage string `json:"errorMessage,omitempty"`
Timestamp int64 `json:"timestamp"` // Unix timestamp in milliseconds
}
func Complete ¶
func Complete(model Model[API], modelContext ModelContext, options *StreamOptions) (AssistantMessage, error)
func CompleteSimple ¶
func CompleteSimple(model Model[API], modelContext ModelContext, options *SimpleStreamOptions) (AssistantMessage, error)
func (AssistantMessage) AgentMessageType ¶
func (AssistantMessage) AgentMessageType() string
type AssistantMessageDiagnostic ¶
type AssistantMessageDiagnostic struct {
Type string `json:"type"`
Timestamp int64 `json:"timestamp"`
Error *DiagnosticErrorInfo `json:"error,omitempty"`
Details any `json:"details,omitempty"`
}
type AssistantMessageEvent ¶
type AssistantMessageEvent interface {
EventType() string
}
type AssistantMessageEventStream ¶
type AssistantMessageEventStream struct {
// contains filtered or unexported fields
}
func NewAssistantMessageEventStream ¶
func NewAssistantMessageEventStream(buffer int) *AssistantMessageEventStream
func Stream ¶
func Stream(model Model[API], modelContext ModelContext, options *StreamOptions) (*AssistantMessageEventStream, error)
func StreamOpenAIResponse ¶
func StreamOpenAIResponse(ctx context.Context, model Model[API], modelContext ModelContext, options *OpenAIResponseOptions) (*AssistantMessageEventStream, error)
func StreamOpenAIResponses ¶ added in v0.2.0
func StreamOpenAIResponses(model Model[API], modelContext ModelContext, options *StreamOptions) (*AssistantMessageEventStream, error)
func StreamSimple ¶
func StreamSimple(model Model[API], modelContext ModelContext, options *SimpleStreamOptions) (*AssistantMessageEventStream, error)
func StreamSimpleOpenAIResponses ¶
func StreamSimpleOpenAIResponses(model Model[API], modelContext ModelContext, options *SimpleStreamOptions) (*AssistantMessageEventStream, error)
StreamSimpleOpenAIResponses streams a response. It never reads the environment: the API key comes from options.ApiKey, which callers resolve with ResolveProviderAuth and apply with ApplyModelAuth.
func (*AssistantMessageEventStream) End ¶
func (s *AssistantMessageEventStream) End(err error)
func (*AssistantMessageEventStream) Events ¶
func (s *AssistantMessageEventStream) Events() <-chan AssistantMessageEvent
func (*AssistantMessageEventStream) Push ¶
func (s *AssistantMessageEventStream) Push(event AssistantMessageEvent)
func (*AssistantMessageEventStream) Result ¶
func (s *AssistantMessageEventStream) Result() (AssistantMessage, error)
type AssistantMessageEventType ¶
type AssistantMessageEventType string
const ( AssistantMessageEventText AssistantMessageEventType = "text" AssistantMessageEventDone AssistantMessageEventType = "done" AssistantMessageEventError AssistantMessageEventType = "error" )
type AuthCheck ¶ added in v0.6.0
type AuthCheck struct {
Type CredentialType
Source string
}
AuthCheck reports that a provider has auth configured, found without refreshing tokens or doing other request-time work.
func CheckProviderAuth ¶ added in v0.6.0
func CheckProviderAuth( ctx context.Context, provider Provider, auth ProviderAuth, store CredentialStore, env AuthContext, ) (*AuthCheck, error)
CheckProviderAuth reports whether provider has auth configured, and from where, without refreshing tokens. It returns nil, nil when the provider is not configured. Use it for status UI and model lists; requests use ResolveProviderAuth.
It follows ResolveProviderAuth's precedence: a stored OAuth credential counts as configured even when expired, and a stored credential whose type has no handler in auth means unconfigured. API key auth is checked with auth.APIKey.Check when set, otherwise by resolving it. A nil env means no ambient auth.
type AuthContext ¶ added in v0.6.0
type AuthContext interface {
// Env returns the named variable, and false when it is unset or blank.
Env(name string) (string, bool)
// FileExists reports whether path exists. A leading ~ is the user's home
// directory.
FileExists(path string) bool
}
AuthContext is where ambient auth comes from: environment variables and credential files. It is injectable so that multi-tenant apps can turn ambient auth off with NoAmbientAuth.
func DefaultAuthContext ¶ added in v0.6.0
func DefaultAuthContext() AuthContext
DefaultAuthContext reads the process environment and file system.
func NoAmbientAuth ¶ added in v0.6.0
func NoAmbientAuth() AuthContext
NoAmbientAuth is an AuthContext with no variables and no files, so only stored credentials and overrides configure a provider.
type AuthError ¶ added in v0.6.0
type AuthError struct {
Code AuthErrorCode
Provider Provider
Message string
Err error
}
AuthError is returned when auth resolution fails, as pi's ModelsError is.
type AuthErrorCode ¶ added in v0.6.0
type AuthErrorCode string
AuthErrorCode says which part of auth resolution failed.
const ( // AuthErrorStore means the credential store or API key resolution failed. // Retrying may succeed. AuthErrorStore AuthErrorCode = "auth" // AuthErrorOAuth means an OAuth refresh failed. The stored credential is // kept, but the user likely has to log in again. AuthErrorOAuth AuthErrorCode = "oauth" )
type AuthEvent ¶ added in v0.6.0
type AuthEvent struct {
Type AuthEventType
Message string
}
AuthEvent tells the user about login progress. It needs no answer.
type AuthEventType ¶ added in v0.6.0
type AuthEventType string
AuthEventType is the kind of an AuthEvent.
const ( AuthEventInfo AuthEventType = "info" AuthEventProgress AuthEventType = "progress" )
type AuthInteraction ¶ added in v0.6.0
type AuthInteraction struct {
// Prompt returns the entered text, or the chosen option's ID for a select
// prompt. It returns an error if the user cancels or ctx is done.
Prompt func(ctx context.Context, prompt AuthPrompt) (string, error)
// Notify shows event to the user. It may be nil.
Notify func(event AuthEvent)
}
AuthInteraction is how a login flow talks to the user, for both API key and OAuth logins. The app provides it: a TUI prompts in the terminal, a web app renders a form.
type AuthPrompt ¶ added in v0.6.0
type AuthPrompt struct {
Type AuthPromptType
Message string
Placeholder string
// Options are the choices of a select prompt.
Options []AuthPromptOption
}
AuthPrompt asks the user for input during login.
type AuthPromptOption ¶ added in v0.6.0
AuthPromptOption is one choice of a select prompt.
type AuthPromptType ¶ added in v0.6.0
type AuthPromptType string
AuthPromptType is the kind of input an AuthPrompt asks for.
const ( AuthPromptText AuthPromptType = "text" AuthPromptSecret AuthPromptType = "secret" AuthPromptSelect AuthPromptType = "select" )
type AuthResolutionOverrides ¶ added in v0.6.0
type AuthResolutionOverrides struct {
// APIKey replaces stored and ambient auth when set, even to "".
APIKey *string
// Env is laid over the ambient environment and a stored credential's Env.
Env map[string]string
// MinOAuthValidity, when longer than the default five minutes, is how long
// an OAuth token must stay valid; a refresh that leaves less is an error.
MinOAuthValidity time.Duration
}
AuthResolutionOverrides changes how ResolveProviderAuth resolves one request.
type AuthResult ¶ added in v0.6.0
type AuthResult struct {
Auth ModelAuth
// Env holds provider-scoped config resolved from the credential and
// ambient sources.
Env map[string]string
// Source labels where the auth came from for status UI, such as
// "OPENAI_API_KEY" or "OAuth".
Source string
}
AuthResult is resolved request auth for a provider.
func ResolveProviderAuth ¶ added in v0.6.0
func ResolveProviderAuth( ctx context.Context, provider Provider, auth ProviderAuth, store CredentialStore, env AuthContext, overrides *AuthResolutionOverrides, ) (*AuthResult, error)
ResolveProviderAuth resolves the request auth for provider. It returns nil, nil when the provider is not configured.
A stored credential owns the provider: env is consulted only when nothing is stored. There is no fallback to env after a failed refresh, or when the stored credential's type has no handler in auth, so a broken login never silently switches to an ambient key. The order is:
- overrides.APIKey, when auth has API key support
- a stored OAuth credential, refreshed when it expires within five minutes (or overrides.MinOAuthValidity, if longer)
- a stored API key credential
- ambient auth from env, such as environment variables
overrides.Env is laid over env and over a stored API key credential's Env. A nil env means no ambient auth.
type CacheRetention ¶
type CacheRetention string
const ( CacheRetentionNone CacheRetention = "none" CacheRetentionShort CacheRetention = "short" CacheRetentionLong CacheRetention = "long" )
func ResolveCacheRetention ¶
func ResolveCacheRetention(cacheRetention CacheRetention) CacheRetention
ResolveCacheRetention returns cacheRetention, or CacheRetentionShort when it is unset. CacheRetentionNone is kept, so callers can turn caching off.
type ContentType ¶
type ContentType string
const ( ContentTypeText ContentType = "text" ContentTypeThinking ContentType = "thinking" ContentTypeImage ContentType = "image" ContentTypeToolCall ContentType = "toolCall" )
type ConvertResponseMessagesOptions ¶
type ConvertResponseMessagesOptions struct {
IncludeSystemPrompt *bool `json:"includeSystemPrompt,omitempty"`
}
type ConvertResponsesToolsOptions ¶
type ConvertResponsesToolsOptions struct {
Strict *bool
}
type Credential ¶ added in v0.6.0
type Credential struct {
Type CredentialType
// Key is the API key of an api_key credential.
Key string
// Env holds provider-scoped config of an api_key credential, such as an
// account ID.
Env map[string]string
// OAuth is the token set of an oauth credential.
OAuth *OAuthToken
}
Credential is one stored credential for a provider: an API key or an OAuth token set, as Type says.
func RefreshStoredOAuthCredential ¶ added in v0.6.0
func RefreshStoredOAuthCredential( ctx context.Context, store CredentialStore, provider Provider, oauth OAuthAuth, needsRefresh func(*Credential) bool, ) (*Credential, error)
RefreshStoredOAuthCredential refreshes provider's stored OAuth credential under the store's lock and stores the result before the lock is released. needsRefresh is checked again under the lock, so when several requests or processes find the token expired, only the first refreshes and the rest use its result.
ctx cancels only the wait for the lock. Once the refresh starts, the provider may already have rotated the refresh token, so the refresh and its write ignore ctx and are bounded by oauthRefreshTimeout; otherwise a cancelled caller could throw away the only valid refresh token. A caller cancelled during the refresh gets ctx.Err() at once while the refresh finishes in the background.
It returns the stored OAuth credential afterwards, or nil if the provider no longer has one, such as after a logout.
func (*Credential) Clone ¶ added in v0.6.0
func (c *Credential) Clone() *Credential
Clone returns a deep copy of c, so a store can hand out credentials without sharing its own. Clone of nil is nil.
type CredentialInfo ¶ added in v0.6.0
type CredentialInfo struct {
Provider Provider
Type CredentialType
}
CredentialInfo is credential metadata for listing, without secrets.
type CredentialStore ¶ added in v0.6.0
type CredentialStore interface {
Read(ctx context.Context, provider Provider) (*Credential, error)
List(ctx context.Context) ([]CredentialInfo, error)
Modify(ctx context.Context, provider Provider, fn func(current *Credential) (*Credential, error)) (*Credential, error)
Delete(ctx context.Context, provider Provider) error
}
CredentialStore stores one credential per provider, for one user. Apps provide persistent stores; NewInMemoryCredentialStore is the default.
Modify is the only write path, so every change is a serialized read-modify-write. ResolveProviderAuth refreshes OAuth tokens inside Modify, so concurrent requests cannot refresh a rotated token twice.
- Read returns nil, nil when nothing is stored. The credential may be expired; request auth comes from ResolveProviderAuth.
- List returns metadata only. It must not resolve or expose secrets.
- Modify runs fn with the current credential (nil if none) while holding a lock on the provider, across processes too where the backing store supports it. fn may make a network call; hold the lock across it. fn returning nil leaves the credential unchanged. Modify returns the credential after the write. An error from fn stores nothing and is returned, wrapped or not, so errors.As still finds it. If ctx is done before the lock is acquired, Modify returns ctx.Err() without running fn.
- Delete removes the credential, serialized against Modify. Deleting nothing succeeds.
Methods return errors only when storage fails. Stores must not keep the credentials passed to them, nor return ones they keep; see Credential.Clone.
type CredentialType ¶ added in v0.6.0
type CredentialType string
CredentialType is the kind of a stored credential.
const ( CredentialAPIKey CredentialType = "api_key" CredentialOAuth CredentialType = "oauth" )
type DiagnosticErrorInfo ¶
type DoneEvent ¶
type DoneEvent struct {
Type string `json:"type"`
Reason StopReason `json:"reason"`
Message AssistantMessage `json:"message"`
}
type ErrorEvent ¶
type ErrorEvent struct {
Type string `json:"type"`
Reason StopReason `json:"reason"`
Message AssistantMessage `json:"message"`
}
func (ErrorEvent) EventType ¶
func (ErrorEvent) EventType() string
type EventStream ¶
func NewEventStream ¶
func NewEventStream[T any, R any]( buffer int, isComplete func(T) bool, extractResult func(T) R, ) *EventStream[T, R]
func (*EventStream[T, R]) End ¶
func (s *EventStream[T, R]) End(result R)
func (*EventStream[T, R]) Events ¶
func (s *EventStream[T, R]) Events() <-chan T
func (*EventStream[T, R]) Push ¶
func (s *EventStream[T, R]) Push(event T)
func (*EventStream[T, R]) Result ¶
func (s *EventStream[T, R]) Result() R
type ImageContent ¶
type ImageContent struct {
Type ContentType `json:"type"`
Image string `json:"image"`
MimeType string `json:"mimeType"`
}
type InMemoryCredentialStore ¶ added in v0.6.0
type InMemoryCredentialStore struct {
// contains filtered or unexported fields
}
InMemoryCredentialStore is a CredentialStore that keeps credentials in memory, for tests and apps that do not persist auth. Modify and Delete are serialized per provider, within this process only.
func NewInMemoryCredentialStore ¶ added in v0.6.0
func NewInMemoryCredentialStore() *InMemoryCredentialStore
NewInMemoryCredentialStore returns an empty InMemoryCredentialStore.
func (*InMemoryCredentialStore) Delete ¶ added in v0.6.0
func (s *InMemoryCredentialStore) Delete(ctx context.Context, provider Provider) error
func (*InMemoryCredentialStore) List ¶ added in v0.6.0
func (s *InMemoryCredentialStore) List(ctx context.Context) ([]CredentialInfo, error)
func (*InMemoryCredentialStore) Modify ¶ added in v0.6.0
func (s *InMemoryCredentialStore) Modify(ctx context.Context, provider Provider, fn func(current *Credential) (*Credential, error)) (*Credential, error)
func (*InMemoryCredentialStore) Read ¶ added in v0.6.0
func (s *InMemoryCredentialStore) Read(ctx context.Context, provider Provider) (*Credential, error)
type Model ¶
type Model[tApi API] struct { ID string `json:"id"` Name string `json:"name"` API tApi `json:"api"` Provider Provider `json:"provider"` BaseURL string `json:"baseUrl"` Reasoning bool `json:"reasoning"` ThinkingLevelMap ThinkingLevelMap `json:"thinkingLevelMap"` Input []string `json:"input"` Cost Cost `json:"cost"` // $/million tokens ContextWindow int `json:"contextWindow"` MaxTokens int `json:"maxTokens"` Headers *map[string]string `json:"headers"` Compat *OpenAIResponsesCompat `json:"compat"` }
func ApplyModelAuth ¶ added in v0.6.0
func ApplyModelAuth[T API](model Model[T], options *StreamOptions, auth ModelAuth) Model[T]
ApplyModelAuth applies auth to a request: it sets options.ApiKey, lays auth.Headers under options.Headers, and returns model with auth.BaseURL. The caller's headers win, so an app can still override a header per request. It changes neither the caller's header map nor model's.
type ModelAuth ¶ added in v0.6.0
ModelAuth is the auth for a single model request. Anything that cannot be expressed as an API key, headers, or a base URL is provider config, not auth.
type ModelContext ¶
type ModelThinkingLevel ¶
type ModelThinkingLevel string
const ( ThinkingLevelOff ModelThinkingLevel = "off" ThinkingLevelMinimal ModelThinkingLevel = "minimal" ThinkingLevelLow ModelThinkingLevel = "low" ThinkingLevelMedium ModelThinkingLevel = "medium" ThinkingLevelHigh ModelThinkingLevel = "high" ThinkingLevelXHigh ModelThinkingLevel = "xhigh" )
func ClampThinkingLevel ¶
func ClampThinkingLevel[TApi API](model Model[TApi], level ModelThinkingLevel) ModelThinkingLevel
func GetSupportedThinkingLevels ¶
func GetSupportedThinkingLevels[TApi API](model Model[TApi]) []ModelThinkingLevel
type OAuthAuth ¶ added in v0.6.0
type OAuthAuth struct {
// Name is shown to the user, such as "OpenAI (ChatGPT subscription)".
Name string
// IsSubscription reports whether access is backed by a provider
// subscription rather than API billing.
IsSubscription bool
// Login runs the provider's login flow and returns the credential to store.
Login func(ctx context.Context, in AuthInteraction) (*Credential, error)
// Refresh exchanges cred's refresh token over the network. It runs under
// the store's lock with its own timeout. It must return the complete new
// credential, keeping the old refresh token if the provider sent none.
Refresh func(ctx context.Context, cred *Credential) (*Credential, error)
// ToAuth derives request auth from a valid credential, including a base
// URL or headers specific to the credential. It must have no side effects.
ToAuth func(cred *Credential) (ModelAuth, error)
}
OAuthAuth is OAuth auth. Refresh and ToAuth are separate so that ResolveProviderAuth can refresh under the store's lock: Refresh produces a credential, and ToAuth derives request auth from whichever credential ends up stored.
type OAuthToken ¶ added in v0.6.0
type OAuthToken struct {
Access string
Refresh string
Expires time.Time
// Extra keeps provider fields, such as the Codex account ID, through a
// round trip.
Extra map[string]json.RawMessage
}
OAuthToken is the token set of an OAuth credential.
type OpenAIResponseOptions ¶
type OpenAIResponseOptions struct {
StreamOptions
ReasoningEffort *string `json:"reasoningEffort,omitempty"`
ReasoningSummary *string `json:"reasoningSummary,omitempty"`
ServiceTier *string `json:"serviceTier,omitempty"`
}
type OpenAIResponsesCompat ¶
type ParsedTextSignature ¶
type ParsedTextSignature struct {
ID string
Phase *TextSignaturePhase
}
func ParseTextSignature ¶
func ParseTextSignature(signature *string) *ParsedTextSignature
type Provider ¶
type Provider string
const (
ProviderOpenAI Provider = "openai"
)
func GetProviders ¶
func GetProviders() []Provider
type ProviderAuth ¶ added in v0.6.0
type ProviderAuth struct {
APIKey *APIKeyAuth
OAuth *OAuthAuth
}
ProviderAuth is how a provider authenticates. At least one of APIKey and OAuth is set; even providers that only use ambient auth or no key at all have APIKey auth, whose Resolve reports whether they are configured.
type ProviderResponse ¶
type RegisteredApiProvider ¶
type RegisteredApiProvider struct {
Provider ApiProviderInternal
SourceID *string
}
type SessionResourceCleanup ¶
type SimpleStreamOptions ¶
type SimpleStreamOptions struct {
StreamOptions
Reasoning *ModelThinkingLevel
ThinkingBudgets *ThinkingBudgets
}
type StartEvent ¶
type StartEvent struct {
Type string `json:"type"`
Partial AssistantMessage `json:"partial"`
}
func (StartEvent) EventType ¶
func (StartEvent) EventType() string
type StopReason ¶
type StopReason string
const ( StopReasonStop StopReason = "stop" StopReasonLength StopReason = "length" StopReasonToolUse StopReason = "toolUse" StopReasonError StopReason = "error" StopReasonAborted StopReason = "aborted" )
func MapOpenAIResponseStopReason ¶
func MapOpenAIResponseStopReason(status responses.ResponseStatus) (StopReason, error)
type StreamFunction ¶
type StreamFunction[TApi API, TOptions any] func( model Model[TApi], ModelContext ModelContext, options *TOptions, ) (*AssistantMessageEventStream, error)
type StreamOptions ¶
type StreamOptions struct {
Temperature *decimal.Decimal `json:"temperature,omitempty"`
MaxTokens *int64 `json:"max_tokens,omitempty"`
Signal context.Context `json:"signal,omitempty"`
ApiKey *string `json:"api_key,omitempty"`
Transport *Transport `json:"transport,omitempty"`
Cache *CacheRetention `json:"cache,omitempty"`
SessionId *string `json:"session_id,omitempty"`
OnPayload func(payload any, model Model[API]) (any, error) `json:"on_payload,omitempty"`
OnResponse func(response ProviderResponse, model Model[API]) error `json:"on_response,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
TimeoutMs *int64 `json:"timeout_ms,omitempty"`
MaxRetries *int64 `json:"max_retries,omitempty"`
MaxRetriesDelayMs *int64 `json:"max_retries_delay_ms,omitempty"`
HTTPClient *http.Client `json:"-"`
Metadata map[string]any `json:"metadata,omitempty"`
}
StreamOptions configures one model request.
TimeoutMs bounds how long each attempt waits for the response to start; it does not limit a stream that has started. Nil means DefaultTimeout (10 minutes). MaxRetries is how many times a failed request is retried; nil means DefaultMaxRetries (2). MaxRetriesDelayMs fails a request at once, instead of retrying, when the server asks for a longer retry delay. Nil means DefaultMaxRetriesDelay (60 seconds). Zero TimeoutMs or MaxRetriesDelayMs means no limit. Negative values are an error, as are durations over about 292 years, the most a time.Duration can hold.
type TextContent ¶
type TextContent struct {
Type ContentType `json:"type"`
Text string `json:"text"`
TextSignature *string `json:"textSignature,omitempty"`
}
type TextDeltaEvent ¶
type TextDeltaEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
Delta string `json:"delta"`
Partial AssistantMessage `json:"partial"`
}
func (TextDeltaEvent) EventType ¶
func (TextDeltaEvent) EventType() string
type TextEndEvent ¶
type TextEndEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
Content string `json:"content"`
Partial AssistantMessage `json:"partial"`
}
func (TextEndEvent) EventType ¶
func (TextEndEvent) EventType() string
type TextSignaturePhase ¶
type TextSignaturePhase string
const ( PhaseCommentary TextSignaturePhase = "commentary" PhaseFinalAnswer TextSignaturePhase = "final_answer" )
type TextStartEvent ¶
type TextStartEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
Partial AssistantMessage `json:"partial"`
}
func (TextStartEvent) EventType ¶
func (TextStartEvent) EventType() string
type ThinkingBudgets ¶
type ThinkingContent ¶
type ThinkingContent struct {
Type ContentType `json:"type"`
Thinking string `json:"thinking"`
ThinkingSignature *string `json:"thinkingSignature,omitempty"`
Redacted *bool `json:"redacted,omitempty"`
}
type ThinkingDeltaEvent ¶
type ThinkingDeltaEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
Delta string `json:"delta"`
Partial AssistantMessage `json:"partial"`
}
func (ThinkingDeltaEvent) EventType ¶
func (ThinkingDeltaEvent) EventType() string
type ThinkingEndEvent ¶
type ThinkingEndEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
Content string `json:"content"`
Partial AssistantMessage `json:"partial"`
}
func (ThinkingEndEvent) EventType ¶
func (ThinkingEndEvent) EventType() string
type ThinkingLevelMap ¶
type ThinkingLevelMap map[ModelThinkingLevel]*string
type ThinkingStartEvent ¶
type ThinkingStartEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
Partial AssistantMessage `json:"partial"`
}
func (ThinkingStartEvent) EventType ¶
func (ThinkingStartEvent) EventType() string
type ToolCallDeltaEvent ¶
type ToolCallDeltaEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
Delta string `json:"delta"`
Partial AssistantMessage `json:"partial"`
}
func (ToolCallDeltaEvent) EventType ¶
func (ToolCallDeltaEvent) EventType() string
type ToolCallEndEvent ¶
type ToolCallEndEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
ToolCall ToolCall `json:"toolCall"`
Partial AssistantMessage `json:"partial"`
}
func (ToolCallEndEvent) EventType ¶
func (ToolCallEndEvent) EventType() string
type ToolCallStartEvent ¶
type ToolCallStartEvent struct {
Type string `json:"type"`
ContentIndex int64 `json:"contentIndex"`
Partial AssistantMessage `json:"partial"`
}
func (ToolCallStartEvent) EventType ¶
func (ToolCallStartEvent) EventType() string
type ToolResultContent ¶
type ToolResultContent interface {
// contains filtered or unexported methods
}
func ReplaceToolResultImagesWithPlaceholder ¶
func ReplaceToolResultImagesWithPlaceholder(content []ToolResultContent, placeholder string) []ToolResultContent
type ToolResultMessage ¶
type ToolResultMessage struct {
Role Role `json:"role"`
ToolCallID string `json:"toolCallId"`
ToolName string `json:"toolName"`
Content []ToolResultContent `json:"content"`
Details any `json:"details,omitempty"`
IsError bool `json:"isError"`
Timestamp int64 `json:"timestamp"` // Unix timestamp in milliseconds
}
func (ToolResultMessage) AgentMessageType ¶
func (ToolResultMessage) AgentMessageType() string
type Usage ¶
type UserContent ¶
type UserContent interface {
// contains filtered or unexported methods
}
func ReplaceUserImagesWithPlaceholder ¶
func ReplaceUserImagesWithPlaceholder(content []UserContent, placeholder string) []UserContent
type UserMessage ¶
type UserMessage struct {
Role Role `json:"role"`
Content []UserContent `json:"content"`
Timestamp int64 `json:"timestamp"` // Unix timestamp in milliseconds
}
func (UserMessage) AgentMessageType ¶
func (UserMessage) AgentMessageType() string
AgentMessageType returns the message type as a string for use in the agent loop.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package providertest fakes model provider APIs in tests.
|
Package providertest fakes model provider APIs in tests. |
|
openairesponses
Package openairesponses builds OpenAI Responses API fixtures for providertest servers.
|
Package openairesponses builds OpenAI Responses API fixtures for providertest servers. |