mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
1680316c7f
* refactor(agent): replace TypeScript agent gateway with in-process Go agent using twilight-ai SDK
- Remove apps/agent (Bun/Elysia gateway), packages/agent (@memoh/agent),
internal/bun runtime manager, and all embedded agent/bun assets
- Add internal/agent package powered by twilight-ai SDK for LLM calls,
tool execution, streaming, sential logic, tag extraction, and prompts
- Integrate ToolGatewayService in-process for both built-in and user MCP
tools, eliminating HTTP round-trips to the old gateway
- Update resolver to convert between sdk.Message and ModelMessage at the
boundary (resolver_messages.go), keeping agent package free of
persistence concerns
- Prepend user message before storeRound since SDK only returns output
messages (assistant + tool)
- Clean up all Docker configs, TOML configs, nginx proxy, Dockerfile.agent,
and Go config structs related to the removed agent gateway
- Update cmd/agent and cmd/memoh entry points with setter-based
ToolGateway injection to avoid FX dependency cycles
* fix(web): move form declaration before computed properties that reference it
The `form` reactive object was declared after computed properties like
`selectedMemoryProvider` and `isSelectedMemoryProviderPersisted` that
reference it, causing a TDZ ReferenceError during setup.
* fix: prevent UTF-8 character corruption in streaming text output
StreamTagExtractor.Push() used byte-level string slicing to hold back
buffer tails for tag detection, which could split multi-byte UTF-8
characters. After json.Marshal replaced invalid bytes with U+FFFD,
the corruption became permanent — causing garbled CJK characters (�)
in agent responses.
Add safeUTF8SplitIndex() to back up split points to valid character
boundaries. Also fix byte-level truncation in command/formatter.go
and command/fs.go to use rune-aware slicing.
* fix: add agent error logging and fix Gemini tool schema validation
- Log agent stream errors in both SSE and WebSocket paths with bot/model context
- Fix send tool `attachments` parameter: empty `items` schema rejected by
Google Gemini API (INVALID_ARGUMENT), now specifies `{"type": "string"}`
- Upgrade twilight-ai to d898f0b (includes raw body in API error messages)
* chore(ci): remove agent gateway from Docker build and release pipelines
Agent gateway has been replaced by in-process Go agent; remove the
obsolete Docker image matrix entry, Bun/UPX CI steps, and agent-binary
build logic from the release script.
* fix: preserve attachment filename, metadata, and container path through persistence
- Add `name` column to `bot_history_message_assets` (migration 0034) to
persist original filenames across page refreshes.
- Add `metadata` JSONB column (migration 0035) to store source_path,
source_url, and other context alongside each asset.
- Update SQL queries, sqlc-generated code, and all Go types (MessageAsset,
AssetRef, OutboundAssetRef, FileAttachment) to carry name and metadata
through the full lifecycle.
- Extract filenames from path/URL in AttachmentsResolver before clearing
raw paths; enrich streaming event metadata with name, source_path, and
source_url in both the WebSocket and channel inbound ingestion paths.
- Implement `LinkAssets` on message service and `LinkOutboundAssets` on
flow resolver so WebSocket-streamed bot attachments are persisted to the
correct assistant message after streaming completes.
- Frontend: update MessageAsset type with metadata field, pass metadata
through to attachment items, and reorder attachment-block.vue template
so container files (identified by metadata.source_path) open in the
sidebar file manager instead of triggering a download.
* refactor(agent): decouple built-in tools from MCP, load via ToolProvider interface
Migrate all 13 built-in tool providers from internal/mcp/providers/ to
internal/agent/tools/ using the twilight-ai sdk.Tool structure. The agent
now loads tools through a ToolProvider interface instead of the MCP
ToolGatewayService, which is simplified to only manage external federation
sources. This enables selective tool loading and removes the coupling
between business tools and the MCP protocol layer.
* refactor(flow): split monolithic resolver.go into focused modules
Break the 1959-line resolver.go into 12 files organized by concern:
- resolver.go: core orchestration (Resolver struct, resolve, Chat, prepareRunConfig)
- resolver_stream.go: streaming (StreamChat, StreamChatWS, tryStoreStream)
- resolver_trigger.go: schedule/heartbeat triggers
- resolver_attachments.go: attachment routing, inlining, encoding
- resolver_history.go: message loading, deduplication, token trimming
- resolver_store.go: persistence (storeRound, storeMessages, asset linking)
- resolver_memory.go: memory provider integration
- resolver_model_selection.go: model selection and candidate matching
- resolver_identity.go: display name and channel identity resolution
- resolver_settings.go: bot settings, loop detection, inbox
- user_header.go: YAML front-matter formatting
- resolver_util.go: shared utilities (sanitize, normalize, dedup, UUID)
* fix(agent): enable Anthropic extended thinking by passing ReasoningConfig to provider
Anthropic's thinking requires WithThinking() at provider creation time,
unlike OpenAI which uses per-request ReasoningEffort. The config was
never wired through, so Claude models could not trigger thinking.
* refactor(agent): extract prompts into embedded markdown templates
Move inline prompt strings from prompt.go into separate .md files under
internal/agent/prompts/, using {{key}} placeholders and a simple render
engine. Remove obsolete SystemPromptParams fields (Language,
MaxContextLoadTime, Channels, CurrentChannel) and their call-site usage.
* fix: lint
835 lines
22 KiB
Markdown
835 lines
22 KiB
Markdown
# Twilight AI API Reference
|
|
|
|
This file is the detailed API companion for `skill/SKILL.md`.
|
|
|
|
Use it when the task needs exact package names, exported types, function signatures, provider options, or stream/event shapes.
|
|
|
|
## Package Map
|
|
|
|
- `github.com/memohai/twilight-ai/sdk`
|
|
- `github.com/memohai/twilight-ai/provider/openai/completions`
|
|
- `github.com/memohai/twilight-ai/provider/openai/responses`
|
|
- `github.com/memohai/twilight-ai/provider/anthropic/messages`
|
|
- `github.com/memohai/twilight-ai/provider/google/generativeai`
|
|
- `github.com/memohai/twilight-ai/provider/openai/embedding`
|
|
- `github.com/memohai/twilight-ai/provider/google/embedding`
|
|
|
|
## Package `sdk`
|
|
|
|
### Client And Top-Level Helpers
|
|
|
|
```go
|
|
type Client struct{}
|
|
|
|
func NewClient() *Client
|
|
|
|
func (c *Client) GenerateText(ctx context.Context, options ...GenerateOption) (string, error)
|
|
func (c *Client) GenerateTextResult(ctx context.Context, options ...GenerateOption) (*GenerateResult, error)
|
|
func (c *Client) StreamText(ctx context.Context, options ...GenerateOption) (*StreamResult, error)
|
|
func (c *Client) Embed(ctx context.Context, value string, options ...EmbedOption) ([]float64, error)
|
|
func (c *Client) EmbedMany(ctx context.Context, values []string, options ...EmbedOption) (*EmbedResult, error)
|
|
|
|
func GenerateText(ctx context.Context, options ...GenerateOption) (string, error)
|
|
func GenerateTextResult(ctx context.Context, options ...GenerateOption) (*GenerateResult, error)
|
|
func StreamText(ctx context.Context, options ...GenerateOption) (*StreamResult, error)
|
|
func Embed(ctx context.Context, value string, options ...EmbedOption) ([]float64, error)
|
|
func EmbedMany(ctx context.Context, values []string, options ...EmbedOption) (*EmbedResult, error)
|
|
```
|
|
|
|
### Provider Contracts
|
|
|
|
```go
|
|
type Provider interface {
|
|
Name() string
|
|
ListModels(ctx context.Context) ([]Model, error)
|
|
Test(ctx context.Context) *ProviderTestResult
|
|
TestModel(ctx context.Context, modelID string) (*ModelTestResult, error)
|
|
DoGenerate(ctx context.Context, params GenerateParams) (*GenerateResult, error)
|
|
DoStream(ctx context.Context, params GenerateParams) (*StreamResult, error)
|
|
}
|
|
|
|
type ProviderStatus string
|
|
|
|
const (
|
|
ProviderStatusOK ProviderStatus = "ok"
|
|
ProviderStatusUnhealthy ProviderStatus = "unhealthy"
|
|
ProviderStatusUnreachable ProviderStatus = "unreachable"
|
|
)
|
|
|
|
type ProviderTestResult struct {
|
|
Status ProviderStatus
|
|
Message string
|
|
Error error
|
|
}
|
|
|
|
type ModelTestResult struct {
|
|
Supported bool
|
|
Message string
|
|
}
|
|
```
|
|
|
|
### Models
|
|
|
|
```go
|
|
type ModelType string
|
|
|
|
const ModelTypeChat ModelType = "chat"
|
|
|
|
type Model struct {
|
|
ID string
|
|
DisplayName string
|
|
Provider Provider
|
|
Type ModelType
|
|
MaxTokens int
|
|
}
|
|
|
|
func (m *Model) Test(ctx context.Context) (*ModelTestResult, error)
|
|
```
|
|
|
|
### Messages
|
|
|
|
```go
|
|
type MessageRole string
|
|
|
|
const (
|
|
MessageRoleUser MessageRole = "user"
|
|
MessageRoleAssistant MessageRole = "assistant"
|
|
MessageRoleSystem MessageRole = "system"
|
|
MessageRoleTool MessageRole = "tool"
|
|
)
|
|
|
|
type MessagePartType string
|
|
|
|
const (
|
|
MessagePartTypeText MessagePartType = "text"
|
|
MessagePartTypeReasoning MessagePartType = "reasoning"
|
|
MessagePartTypeImage MessagePartType = "image"
|
|
MessagePartTypeFile MessagePartType = "file"
|
|
MessagePartTypeToolCall MessagePartType = "tool-call"
|
|
MessagePartTypeToolResult MessagePartType = "tool-result"
|
|
)
|
|
|
|
type MessagePart interface {
|
|
PartType() MessagePartType
|
|
}
|
|
|
|
type TextPart struct {
|
|
Text string
|
|
}
|
|
|
|
type ReasoningPart struct {
|
|
Text string
|
|
Signature string
|
|
}
|
|
|
|
type ImagePart struct {
|
|
Image string
|
|
MediaType string
|
|
}
|
|
|
|
type FilePart struct {
|
|
Data string
|
|
MediaType string
|
|
Filename string
|
|
}
|
|
|
|
type ToolCallPart struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
Input any
|
|
}
|
|
|
|
type ToolResultPart struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
Result any
|
|
IsError bool
|
|
}
|
|
|
|
type Message struct {
|
|
Role MessageRole
|
|
Content []MessagePart
|
|
}
|
|
|
|
func UserMessage(text string, extra ...MessagePart) Message
|
|
func SystemMessage(text string) Message
|
|
func AssistantMessage(text string) Message
|
|
func ToolMessage(results ...ToolResultPart) Message
|
|
```
|
|
|
|
Notes:
|
|
|
|
- `UserMessage` accepts a text string plus optional extra parts such as `ImagePart`.
|
|
- `Message` supports JSON marshal and unmarshal with type discrimination.
|
|
|
|
### Generation
|
|
|
|
```go
|
|
type FinishReason string
|
|
|
|
const (
|
|
FinishReasonStop FinishReason = "stop"
|
|
FinishReasonLength FinishReason = "length"
|
|
FinishReasonContentFilter FinishReason = "content-filter"
|
|
FinishReasonToolCalls FinishReason = "tool-calls"
|
|
FinishReasonError FinishReason = "error"
|
|
FinishReasonOther FinishReason = "other"
|
|
FinishReasonUnknown FinishReason = "unknown"
|
|
)
|
|
|
|
type ResponseFormatType string
|
|
|
|
const (
|
|
ResponseFormatText ResponseFormatType = "text"
|
|
ResponseFormatJSONObject ResponseFormatType = "json_object"
|
|
ResponseFormatJSONSchema ResponseFormatType = "json_schema"
|
|
)
|
|
|
|
type ResponseFormat struct {
|
|
Type ResponseFormatType
|
|
JSONSchema any
|
|
}
|
|
|
|
type GenerateParams struct {
|
|
Model *Model
|
|
System string
|
|
Messages []Message
|
|
Tools []Tool
|
|
ToolChoice any
|
|
ResponseFormat *ResponseFormat
|
|
Temperature *float64
|
|
TopP *float64
|
|
MaxTokens *int
|
|
StopSequences []string
|
|
FrequencyPenalty *float64
|
|
PresencePenalty *float64
|
|
Seed *int
|
|
ReasoningEffort *string
|
|
}
|
|
|
|
type StepResult struct {
|
|
Text string
|
|
Reasoning string
|
|
FinishReason FinishReason
|
|
RawFinishReason string
|
|
Usage Usage
|
|
ToolCalls []ToolCall
|
|
ToolResults []ToolResult
|
|
Response ResponseMetadata
|
|
Messages []Message
|
|
}
|
|
|
|
type GenerateResult struct {
|
|
Text string
|
|
Reasoning string
|
|
FinishReason FinishReason
|
|
RawFinishReason string
|
|
Usage Usage
|
|
Sources []Source
|
|
Files []GeneratedFile
|
|
ToolCalls []ToolCall
|
|
ToolResults []ToolResult
|
|
Response ResponseMetadata
|
|
Steps []StepResult
|
|
Messages []Message
|
|
}
|
|
```
|
|
|
|
### Generate Options
|
|
|
|
```go
|
|
type GenerateOption func(*generateConfig)
|
|
|
|
func WithModel(model *Model) GenerateOption
|
|
func WithMessages(messages []Message) GenerateOption
|
|
func WithSystem(text string) GenerateOption
|
|
func WithTools(tools []Tool) GenerateOption
|
|
func WithToolChoice(choice any) GenerateOption
|
|
func WithResponseFormat(rf ResponseFormat) GenerateOption
|
|
func WithTemperature(t float64) GenerateOption
|
|
func WithTopP(topP float64) GenerateOption
|
|
func WithMaxTokens(n int) GenerateOption
|
|
func WithStopSequences(s []string) GenerateOption
|
|
func WithFrequencyPenalty(penalty float64) GenerateOption
|
|
func WithPresencePenalty(penalty float64) GenerateOption
|
|
func WithSeed(s int) GenerateOption
|
|
func WithReasoningEffort(effort string) GenerateOption
|
|
|
|
func WithMaxSteps(n int) GenerateOption
|
|
func WithOnFinish(fn func(*GenerateResult)) GenerateOption
|
|
func WithOnStep(fn func(*StepResult) *GenerateParams) GenerateOption
|
|
func WithPrepareStep(fn func(*GenerateParams) *GenerateParams) GenerateOption
|
|
func WithApprovalHandler(fn func(ctx context.Context, call ToolCall) (bool, error)) GenerateOption
|
|
```
|
|
|
|
Behavior notes:
|
|
|
|
- `WithMaxSteps(0)` is the default single-call mode.
|
|
- `WithMaxSteps(N)` enables automatic tool execution for up to `N` LLM calls.
|
|
- `WithMaxSteps(-1)` means unlimited loop until the model stops requesting tools.
|
|
- `WithToolChoice` accepts `"auto"`, `"none"`, or `"required"`.
|
|
|
|
### Tools
|
|
|
|
```go
|
|
type ToolExecuteFunc func(ctx *ToolExecContext, input any) (any, error)
|
|
|
|
type ToolExecContext struct {
|
|
context.Context
|
|
ToolCallID string
|
|
ToolName string
|
|
SendProgress func(content any)
|
|
}
|
|
|
|
type Tool struct {
|
|
Name string
|
|
Description string
|
|
Parameters any
|
|
Execute ToolExecuteFunc
|
|
RequireApproval bool
|
|
}
|
|
|
|
func NewTool[T any](
|
|
name, description string,
|
|
execute func(ctx *ToolExecContext, input T) (any, error),
|
|
) Tool
|
|
|
|
type ToolCall struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
Input any
|
|
}
|
|
|
|
type ToolResult struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
Input any
|
|
Output any
|
|
IsError bool
|
|
}
|
|
```
|
|
|
|
### MCP
|
|
|
|
```go
|
|
type MCPTransportType string
|
|
|
|
const (
|
|
MCPTransportHTTP MCPTransportType = "http"
|
|
MCPTransportSSE MCPTransportType = "sse"
|
|
)
|
|
|
|
type MCPClientConfig struct {
|
|
Type MCPTransportType
|
|
URL string
|
|
Headers map[string]string
|
|
Transport mcp.Transport
|
|
HTTPClient *http.Client
|
|
Name string
|
|
Version string
|
|
}
|
|
|
|
type MCPClient struct { /* unexported fields */ }
|
|
|
|
func CreateMCPClient(ctx context.Context, config *MCPClientConfig) (*MCPClient, error)
|
|
func (c *MCPClient) Tools(ctx context.Context) ([]Tool, error)
|
|
func (c *MCPClient) Close() error
|
|
```
|
|
|
|
Usage notes:
|
|
|
|
- `MCPTransportHTTP` is the default built-in transport and uses the official MCP Go SDK's streamable HTTP client transport.
|
|
- `MCPTransportSSE` uses the official MCP Go SDK's SSE client transport.
|
|
- For stdio or other custom transports, create the transport with `github.com/modelcontextprotocol/go-sdk/mcp` and pass it through `Transport`.
|
|
- `Tools(ctx)` converts remote MCP tools into ordinary `sdk.Tool` values suitable for `WithTools(...)`.
|
|
- MCP tool schemas are converted from MCP `InputSchema` into `*jsonschema.Schema`.
|
|
- MCP execution wrappers call `tools/call` and return concatenated text content to the model.
|
|
|
|
### Streaming
|
|
|
|
```go
|
|
type StreamPartType string
|
|
|
|
const (
|
|
StreamPartTypeTextStart StreamPartType = "text-start"
|
|
StreamPartTypeTextDelta StreamPartType = "text-delta"
|
|
StreamPartTypeTextEnd StreamPartType = "text-end"
|
|
StreamPartTypeReasoningStart StreamPartType = "reasoning-start"
|
|
StreamPartTypeReasoningDelta StreamPartType = "reasoning-delta"
|
|
StreamPartTypeReasoningEnd StreamPartType = "reasoning-end"
|
|
StreamPartTypeToolInputStart StreamPartType = "tool-input-start"
|
|
StreamPartTypeToolInputDelta StreamPartType = "tool-input-delta"
|
|
StreamPartTypeToolInputEnd StreamPartType = "tool-input-end"
|
|
StreamPartTypeToolCall StreamPartType = "tool-call"
|
|
StreamPartTypeToolResult StreamPartType = "tool-result"
|
|
StreamPartTypeToolError StreamPartType = "tool-error"
|
|
StreamPartTypeToolOutputDenied StreamPartType = "tool-output-denied"
|
|
StreamPartTypeToolApprovalRequest StreamPartType = "tool-approval-request"
|
|
StreamPartTypeToolProgress StreamPartType = "tool-progress"
|
|
StreamPartTypeSource StreamPartType = "source"
|
|
StreamPartTypeFile StreamPartType = "file"
|
|
StreamPartTypeStart StreamPartType = "start"
|
|
StreamPartTypeFinish StreamPartType = "finish"
|
|
StreamPartTypeStartStep StreamPartType = "start-step"
|
|
StreamPartTypeFinishStep StreamPartType = "finish-step"
|
|
StreamPartTypeError StreamPartType = "error"
|
|
StreamPartTypeAbort StreamPartType = "abort"
|
|
StreamPartTypeRaw StreamPartType = "raw"
|
|
)
|
|
|
|
type StreamPart interface {
|
|
Type() StreamPartType
|
|
}
|
|
|
|
type TextStartPart struct {
|
|
ID string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type TextDeltaPart struct {
|
|
ID string
|
|
Text string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type TextEndPart struct {
|
|
ID string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type ReasoningStartPart struct {
|
|
ID string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type ReasoningDeltaPart struct {
|
|
ID string
|
|
Text string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type ReasoningEndPart struct {
|
|
ID string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type ToolInputStartPart struct {
|
|
ID string
|
|
ToolName string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type ToolInputDeltaPart struct {
|
|
ID string
|
|
Delta string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type ToolInputEndPart struct {
|
|
ID string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type StreamToolCallPart struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
Input any
|
|
}
|
|
|
|
type StreamToolResultPart struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
Input any
|
|
Output any
|
|
}
|
|
|
|
type StreamToolErrorPart struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
Error error
|
|
}
|
|
|
|
type ToolOutputDeniedPart struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
}
|
|
|
|
type ToolApprovalRequestPart struct {
|
|
ApprovalID string
|
|
ToolCallID string
|
|
ToolName string
|
|
Input any
|
|
}
|
|
|
|
type ToolProgressPart struct {
|
|
ToolCallID string
|
|
ToolName string
|
|
Content any
|
|
}
|
|
|
|
type StreamSourcePart struct {
|
|
Source Source
|
|
}
|
|
|
|
type StreamFilePart struct {
|
|
File GeneratedFile
|
|
}
|
|
|
|
type StartPart struct{}
|
|
|
|
type FinishPart struct {
|
|
FinishReason FinishReason
|
|
RawFinishReason string
|
|
TotalUsage Usage
|
|
}
|
|
|
|
type StartStepPart struct{}
|
|
|
|
type FinishStepPart struct {
|
|
FinishReason FinishReason
|
|
RawFinishReason string
|
|
Usage Usage
|
|
Response ResponseMetadata
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type ErrorPart struct {
|
|
Error error
|
|
}
|
|
|
|
type AbortPart struct {
|
|
Reason string
|
|
}
|
|
|
|
type RawPart struct {
|
|
RawValue any
|
|
}
|
|
|
|
type StreamResult struct {
|
|
Stream <-chan StreamPart
|
|
Steps []StepResult
|
|
Messages []Message
|
|
}
|
|
|
|
func (sr *StreamResult) Text() (string, error)
|
|
func (sr *StreamResult) ToResult() (*GenerateResult, error)
|
|
```
|
|
|
|
### Usage, Sources, Files, Response Metadata
|
|
|
|
```go
|
|
type Usage struct {
|
|
InputTokens int
|
|
OutputTokens int
|
|
TotalTokens int
|
|
ReasoningTokens int
|
|
CachedInputTokens int
|
|
InputTokenDetails InputTokenDetail
|
|
OutputTokenDetails OutputTokenDetail
|
|
}
|
|
|
|
type InputTokenDetail struct {
|
|
CacheReadTokens int
|
|
CacheCreationTokens int
|
|
}
|
|
|
|
type OutputTokenDetail struct {
|
|
TextTokens int
|
|
ReasoningTokens int
|
|
AudioTokens int
|
|
}
|
|
|
|
type Source struct {
|
|
SourceType string
|
|
ID string
|
|
URL string
|
|
Title string
|
|
ProviderMetadata map[string]any
|
|
}
|
|
|
|
type GeneratedFile struct {
|
|
Data string
|
|
MediaType string
|
|
}
|
|
|
|
type ResponseMetadata struct {
|
|
ID string
|
|
ModelID string
|
|
Timestamp time.Time
|
|
Headers map[string]string
|
|
}
|
|
```
|
|
|
|
### Embeddings
|
|
|
|
```go
|
|
type EmbeddingProvider interface {
|
|
DoEmbed(ctx context.Context, params EmbedParams) (*EmbedResult, error)
|
|
}
|
|
|
|
type EmbeddingModel struct {
|
|
ID string
|
|
Provider EmbeddingProvider
|
|
MaxEmbeddingsPerCall int
|
|
}
|
|
|
|
type EmbedParams struct {
|
|
Model *EmbeddingModel
|
|
Values []string
|
|
Dimensions *int
|
|
}
|
|
|
|
type EmbedResult struct {
|
|
Embeddings [][]float64
|
|
Usage EmbeddingUsage
|
|
}
|
|
|
|
type EmbeddingUsage struct {
|
|
Tokens int
|
|
}
|
|
|
|
type EmbedOption func(*embedConfig)
|
|
|
|
func WithEmbeddingModel(model *EmbeddingModel) EmbedOption
|
|
func WithDimensions(d int) EmbedOption
|
|
```
|
|
|
|
## Package `provider/openai/completions`
|
|
|
|
Implements the OpenAI Chat Completions API and OpenAI-compatible `/chat/completions` backends.
|
|
|
|
```go
|
|
type Provider struct { /* unexported fields */ }
|
|
|
|
type Option func(*Provider)
|
|
|
|
func WithAPIKey(apiKey string) Option
|
|
func WithBaseURL(baseURL string) Option
|
|
func WithHTTPClient(client *http.Client) Option
|
|
func New(options ...Option) *Provider
|
|
|
|
func (p *Provider) Name() string
|
|
func (p *Provider) ListModels(ctx context.Context) ([]sdk.Model, error)
|
|
func (p *Provider) Test(ctx context.Context) *sdk.ProviderTestResult
|
|
func (p *Provider) TestModel(ctx context.Context, modelID string) (*sdk.ModelTestResult, error)
|
|
func (p *Provider) ChatModel(id string) *sdk.Model
|
|
func (p *Provider) DoGenerate(ctx context.Context, params sdk.GenerateParams) (*sdk.GenerateResult, error)
|
|
func (p *Provider) DoStream(ctx context.Context, params sdk.GenerateParams) (*sdk.StreamResult, error)
|
|
```
|
|
|
|
Default option values:
|
|
|
|
- `WithBaseURL`: `https://api.openai.com/v1`
|
|
- `WithHTTPClient`: `&http.Client{}`
|
|
|
|
Discovery endpoints:
|
|
|
|
- `ListModels`: `GET /models`
|
|
- `Test`: `GET /models?limit=1`
|
|
- `TestModel`: `GET /models/{id}`
|
|
|
|
## Package `provider/openai/responses`
|
|
|
|
Implements the OpenAI Responses API with reasoning summaries, annotations, and flat input mapping.
|
|
|
|
```go
|
|
type Provider struct { /* unexported fields */ }
|
|
|
|
type Option func(*Provider)
|
|
|
|
func WithAPIKey(apiKey string) Option
|
|
func WithBaseURL(baseURL string) Option
|
|
func WithHTTPClient(client *http.Client) Option
|
|
func New(options ...Option) *Provider
|
|
|
|
func (p *Provider) Name() string
|
|
func (p *Provider) ListModels(ctx context.Context) ([]sdk.Model, error)
|
|
func (p *Provider) Test(ctx context.Context) *sdk.ProviderTestResult
|
|
func (p *Provider) TestModel(ctx context.Context, modelID string) (*sdk.ModelTestResult, error)
|
|
func (p *Provider) ChatModel(id string) *sdk.Model
|
|
func (p *Provider) DoGenerate(ctx context.Context, params sdk.GenerateParams) (*sdk.GenerateResult, error)
|
|
func (p *Provider) DoStream(ctx context.Context, params sdk.GenerateParams) (*sdk.StreamResult, error)
|
|
```
|
|
|
|
Default option values:
|
|
|
|
- `WithBaseURL`: `https://api.openai.com/v1`
|
|
- `WithHTTPClient`: `&http.Client{}`
|
|
|
|
Discovery endpoints:
|
|
|
|
- `ListModels`: `GET /models`
|
|
- `Test`: `GET /models?limit=1`
|
|
- `TestModel`: `GET /models/{id}`
|
|
|
|
Responses-specific behavior:
|
|
|
|
- assistant reasoning maps to `GenerateResult.Reasoning`
|
|
- URL citation annotations map to `GenerateResult.Sources`
|
|
- function-call outputs map to tool-call and tool-result structures
|
|
|
|
## Package `provider/anthropic/messages`
|
|
|
|
Implements the Anthropic Messages API.
|
|
|
|
```go
|
|
type ThinkingConfig struct {
|
|
Type string
|
|
BudgetTokens int
|
|
}
|
|
|
|
type Provider struct { /* unexported fields */ }
|
|
|
|
type Option func(*Provider)
|
|
|
|
func WithAPIKey(apiKey string) Option
|
|
func WithAuthToken(token string) Option
|
|
func WithBaseURL(baseURL string) Option
|
|
func WithHTTPClient(client *http.Client) Option
|
|
func WithHeaders(headers map[string]string) Option
|
|
func WithThinking(cfg ThinkingConfig) Option
|
|
func New(options ...Option) *Provider
|
|
|
|
func (p *Provider) Name() string
|
|
func (p *Provider) ListModels(ctx context.Context) ([]sdk.Model, error)
|
|
func (p *Provider) Test(ctx context.Context) *sdk.ProviderTestResult
|
|
func (p *Provider) TestModel(ctx context.Context, modelID string) (*sdk.ModelTestResult, error)
|
|
func (p *Provider) ChatModel(id string) *sdk.Model
|
|
func (p *Provider) DoGenerate(ctx context.Context, params sdk.GenerateParams) (*sdk.GenerateResult, error)
|
|
func (p *Provider) DoStream(ctx context.Context, params sdk.GenerateParams) (*sdk.StreamResult, error)
|
|
```
|
|
|
|
Default option values:
|
|
|
|
- `WithBaseURL`: `https://api.anthropic.com/v1`
|
|
- default API version header: `2023-06-01`
|
|
- `WithHTTPClient`: `&http.Client{}`
|
|
|
|
Thinking config notes:
|
|
|
|
- `Type` supports `"enabled"`, `"adaptive"`, or `"disabled"`
|
|
- `BudgetTokens` is required when `Type == "enabled"`
|
|
|
|
Discovery endpoints:
|
|
|
|
- `ListModels`: `GET /v1/models`
|
|
- `Test`: `GET /v1/models?limit=1`
|
|
- `TestModel`: `GET /v1/models/{id}`
|
|
|
|
## Package `provider/google/generativeai`
|
|
|
|
Implements the Google Generative AI API for Gemini chat models.
|
|
|
|
```go
|
|
type Provider struct { /* unexported fields */ }
|
|
|
|
type Option func(*Provider)
|
|
|
|
func WithAPIKey(apiKey string) Option
|
|
func WithBaseURL(baseURL string) Option
|
|
func WithHTTPClient(client *http.Client) Option
|
|
func New(options ...Option) *Provider
|
|
|
|
func (p *Provider) Name() string
|
|
func (p *Provider) ListModels(ctx context.Context) ([]sdk.Model, error)
|
|
func (p *Provider) Test(ctx context.Context) *sdk.ProviderTestResult
|
|
func (p *Provider) TestModel(ctx context.Context, modelID string) (*sdk.ModelTestResult, error)
|
|
func (p *Provider) ChatModel(id string) *sdk.Model
|
|
func (p *Provider) DoGenerate(ctx context.Context, params sdk.GenerateParams) (*sdk.GenerateResult, error)
|
|
func (p *Provider) DoStream(ctx context.Context, params sdk.GenerateParams) (*sdk.StreamResult, error)
|
|
```
|
|
|
|
Default option values:
|
|
|
|
- `WithBaseURL`: `https://generativelanguage.googleapis.com/v1beta`
|
|
- `WithHTTPClient`: `&http.Client{}`
|
|
|
|
Model ID rules:
|
|
|
|
- plain names like `gemini-2.5-flash` are accepted
|
|
- full paths like `publishers/google/models/gemini-2.5-flash` are also accepted
|
|
|
|
Discovery endpoints:
|
|
|
|
- `ListModels`: `GET /v1beta/models`
|
|
- `Test`: `GET /v1beta/models?pageSize=1`
|
|
- `TestModel`: `GET /v1beta/models/{id}`
|
|
|
|
## Package `provider/openai/embedding`
|
|
|
|
Implements the OpenAI Embeddings API.
|
|
|
|
```go
|
|
type Provider struct { /* unexported fields */ }
|
|
|
|
type Option func(*Provider)
|
|
|
|
func WithAPIKey(apiKey string) Option
|
|
func WithBaseURL(baseURL string) Option
|
|
func WithHTTPClient(client *http.Client) Option
|
|
func New(options ...Option) *Provider
|
|
|
|
func (p *Provider) EmbeddingModel(id string) *sdk.EmbeddingModel
|
|
func (p *Provider) DoEmbed(ctx context.Context, params sdk.EmbedParams) (*sdk.EmbedResult, error)
|
|
```
|
|
|
|
Default option values:
|
|
|
|
- `WithBaseURL`: `https://api.openai.com/v1`
|
|
- `WithHTTPClient`: `&http.Client{}`
|
|
|
|
Behavior notes:
|
|
|
|
- `EmbeddingModel(id)` returns a model with `MaxEmbeddingsPerCall: 2048`
|
|
- `DoEmbed` calls `POST /embeddings` with `encoding_format: "float"`
|
|
|
|
## Package `provider/google/embedding`
|
|
|
|
Implements the Google embedding API.
|
|
|
|
```go
|
|
type Provider struct { /* unexported fields */ }
|
|
|
|
type Option func(*Provider)
|
|
|
|
func WithAPIKey(apiKey string) Option
|
|
func WithBaseURL(baseURL string) Option
|
|
func WithHTTPClient(client *http.Client) Option
|
|
func WithTaskType(taskType string) Option
|
|
func New(options ...Option) *Provider
|
|
|
|
func (p *Provider) EmbeddingModel(id string) *sdk.EmbeddingModel
|
|
func (p *Provider) DoEmbed(ctx context.Context, params sdk.EmbedParams) (*sdk.EmbedResult, error)
|
|
```
|
|
|
|
Default option values:
|
|
|
|
- `WithBaseURL`: `https://generativelanguage.googleapis.com/v1beta`
|
|
- `WithHTTPClient`: `&http.Client{}`
|
|
|
|
Task type values:
|
|
|
|
- `RETRIEVAL_QUERY`
|
|
- `RETRIEVAL_DOCUMENT`
|
|
- `SEMANTIC_SIMILARITY`
|
|
- `CLASSIFICATION`
|
|
- `CLUSTERING`
|
|
- `QUESTION_ANSWERING`
|
|
- `FACT_VERIFICATION`
|
|
- `CODE_RETRIEVAL_QUERY`
|
|
|
|
Behavior notes:
|
|
|
|
- `EmbeddingModel(id)` returns a model with `MaxEmbeddingsPerCall: 2048`
|
|
- single-value embedding uses `embedContent`
|
|
- multi-value embedding uses `batchEmbedContents`
|
|
|
|
## Selection Cheatsheet
|
|
|
|
- Broad OpenAI-compatible chat API: `provider/openai/completions`
|
|
- OpenAI Responses features such as reasoning summaries or citation annotations: `provider/openai/responses`
|
|
- Claude and extended thinking: `provider/anthropic/messages`
|
|
- Gemini chat and tool calling: `provider/google/generativeai`
|
|
- OpenAI-compatible embeddings: `provider/openai/embedding`
|
|
- Gemini embeddings with task-type tuning: `provider/google/embedding`
|