Documentation
¶
Overview ¶
Package freetheai is the official Go client for FreeTheAI, the free, OpenAI-compatible AI API. It uses only the standard library.
client, err := freetheai.NewClient() // reads FREETHEAI_API_KEY
if err != nil {
log.Fatal(err)
}
reply, err := client.Chat.Completions.New(ctx, freetheai.ChatCompletionParams{
Model: "fta/zai/glm-5.3",
Messages: []freetheai.Message{{Role: "user", Content: "Hello!"}},
})
Index ¶
- Constants
- type APIError
- type Annotation
- type AnswerResponse
- type AuthenticationError
- type BadRequestError
- type ChatChoice
- type ChatCompletion
- type ChatCompletionChunk
- type ChatCompletionParams
- type ChatCompletionStream
- type ChatService
- type CheckinRequiredError
- type ChunkChoice
- type ChunkDelta
- type ChunkToolCall
- type Client
- type CompletionsService
- func (s *CompletionsService) New(ctx context.Context, params ChatCompletionParams) (*ChatCompletion, error)
- func (s *CompletionsService) NewStreaming(ctx context.Context, params ChatCompletionParams) (*ChatCompletionStream, error)
- func (s *CompletionsService) StreamText(ctx context.Context, params ChatCompletionParams, onText func(string) error) error
- type ConcurrencyLimitError
- type ConnectionError
- type ContentFilterError
- type ContentPart
- type DailyLimitError
- type EmailNotVerifiedError
- type ImageGenerateParams
- type ImageURL
- type ImagesNotSupportedError
- type ImagesService
- type IncompleteKeyError
- type InternalServerError
- type Message
- type Model
- type ModelBusyError
- type ModelNotFoundError
- type ModelsService
- type NotFoundError
- type Option
- func WithAPIKey(key string) Option
- func WithBaseURL(base string) Option
- func WithFallbackModels(models ...string) Option
- func WithHTTPClient(hc *http.Client) Option
- func WithHeader(key, value string) Option
- func WithMaxConcurrency(n int) Option
- func WithMaxRetries(n int) Option
- func WithStreamTransport(on bool) Option
- func WithTimeout(d time.Duration) Option
- type PermissionDeniedError
- type ProviderBudgetError
- type RateLimitError
- type RequestTooLargeError
- type ResponseMessage
- type SearchParams
- type SearchResponse
- type SearchResult
- type StreamInterruptedError
- type Task
- type TaskError
- type TaskFailedError
- type TaskOutput
- type TasksService
- func (s *TasksService) Content(ctx context.Context, id string, index int) ([]byte, error)
- func (s *TasksService) Get(ctx context.Context, id string) (*Task, error)
- func (s *TasksService) List(ctx context.Context, limit int) ([]Task, error)
- func (s *TasksService) Wait(ctx context.Context, id string, opts WaitOptions) (*Task, error)
- type Tool
- type ToolCall
- type ToolCallFunction
- type ToolFunction
- type URLCitation
- type Usage
- type VideoCreateParams
- type VideosService
- type WaitOptions
Constants ¶
const ( CheckinURL = "https://freetheai.org/checkin" KeysURL = "https://freetheai.org/dashboard/api-keys" PlanURL = "https://freetheai.org/dashboard/plan" )
Public links the client mentions in its error messages.
const Version = "0.1.0"
Version is the module version, sent in the User-Agent header.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
StatusCode int
Code string
// Message is the message as the API wrote it.
Message string
// ErrorID identifies the failure. Quote it when you ask for help.
ErrorID string
// RetryAfter is the wait the API asked for, when it sent Retry-After.
RetryAfter time.Duration
// Body is the raw response body.
Body []byte
}
APIError is the base error for every answer the API gives with an error status. The specific types below embed it, so errors.As works with either.
type Annotation ¶
type Annotation struct {
Type string `json:"type"`
URLCitation *URLCitation `json:"url_citation,omitempty"`
}
Annotation is a web source a search-enabled model used (url_citation).
type AnswerResponse ¶
type AnswerResponse struct {
Query string `json:"query"`
Answer string `json:"answer"`
Sources []SearchResult `json:"sources"`
DailyUsed int `json:"daily_used,omitempty"`
DailyLimit int `json:"daily_limit,omitempty"`
}
AnswerResponse is the result of Client.Answer.
type AuthenticationError ¶
type AuthenticationError struct{ APIError }
AuthenticationError is a 401: the API key is missing, wrong, or revoked.
func (*AuthenticationError) Unwrap ¶
func (e *AuthenticationError) Unwrap() error
Unwrap returns the base APIError.
type BadRequestError ¶
type BadRequestError struct{ APIError }
BadRequestError is a 400: the request was invalid.
func (*BadRequestError) Unwrap ¶
func (e *BadRequestError) Unwrap() error
Unwrap returns the base APIError.
type ChatChoice ¶
type ChatChoice struct {
Index int `json:"index"`
Message ResponseMessage `json:"message"`
FinishReason string `json:"finish_reason"`
}
ChatChoice is one choice of a ChatCompletion.
type ChatCompletion ¶
type ChatCompletion struct {
ID string `json:"id,omitempty"`
Object string `json:"object,omitempty"`
Created int64 `json:"created,omitempty"`
Model string `json:"model,omitempty"`
Choices []ChatChoice `json:"choices"`
Usage *Usage `json:"usage,omitempty"`
}
ChatCompletion is a finished (non-streamed) chat reply.
type ChatCompletionChunk ¶
type ChatCompletionChunk struct {
ID string `json:"id,omitempty"`
Model string `json:"model,omitempty"`
Created int64 `json:"created,omitempty"`
Choices []ChunkChoice `json:"choices"`
Usage *Usage `json:"usage,omitempty"`
}
ChatCompletionChunk is one streamed piece of a reply.
type ChatCompletionParams ¶
type ChatCompletionParams struct {
// Model is an ID from Client.Models.List, such as "fta/zai/glm-5.3".
Model string `json:"-"`
Messages []Message `json:"messages"`
// FallbackModels overrides the client's fallback list for this call. Nil keeps the client's list.
FallbackModels []string `json:"-"`
Temperature *float64 `json:"temperature,omitempty"`
TopP *float64 `json:"top_p,omitempty"`
MaxTokens *int `json:"max_tokens,omitempty"`
Stop []string `json:"stop,omitempty"`
Seed *int64 `json:"seed,omitempty"`
Tools []Tool `json:"tools,omitempty"`
ToolChoice any `json:"tool_choice,omitempty"`
ResponseFormat any `json:"response_format,omitempty"`
ReasoningEffort string `json:"reasoning_effort,omitempty"`
WebSearch map[string]any `json:"web_search_options,omitempty"`
Extra map[string]any `json:"-"`
}
ChatCompletionParams is the request for a chat completion.
Known fields are typed; Extra holds any other Chat Completions field and is sent as it is.
type ChatCompletionStream ¶
type ChatCompletionStream struct {
// contains filtered or unexported fields
}
ChatCompletionStream reads a streamed reply chunk by chunk.
func (*ChatCompletionStream) Close ¶
func (s *ChatCompletionStream) Close() error
Close ends the stream and frees its concurrency slot. It is safe to call more than once.
func (*ChatCompletionStream) Current ¶
func (s *ChatCompletionStream) Current() ChatCompletionChunk
Current returns the chunk Next advanced to.
func (*ChatCompletionStream) Err ¶
func (s *ChatCompletionStream) Err() error
Err returns the error that ended the stream, if any. A reply that stops before the model finished returns a *StreamInterruptedError with the text so far in Partial.
func (*ChatCompletionStream) Next ¶
func (s *ChatCompletionStream) Next() bool
Next advances to the next chunk. It returns false at the end of the reply or on error.
func (*ChatCompletionStream) Text ¶
func (s *ChatCompletionStream) Text() string
Text returns the reply text received so far.
type ChatService ¶
type ChatService struct {
// Completions creates chat completions.
Completions *CompletionsService
}
ChatService groups the chat resources.
type CheckinRequiredError ¶
type CheckinRequiredError struct{ APIError }
CheckinRequiredError is a 403: free models need the daily check-in on the website first.
func (*CheckinRequiredError) CheckinURL ¶
func (e *CheckinRequiredError) CheckinURL() string
CheckinURL returns the page where the check-in is done.
func (*CheckinRequiredError) Unwrap ¶
func (e *CheckinRequiredError) Unwrap() error
Unwrap returns the base APIError.
type ChunkChoice ¶
type ChunkChoice struct {
Index int `json:"index"`
Delta ChunkDelta `json:"delta"`
FinishReason string `json:"finish_reason"`
}
ChunkChoice is one choice of a streamed chunk.
type ChunkDelta ¶
type ChunkDelta struct {
Role string `json:"role,omitempty"`
Content string `json:"content,omitempty"`
ReasoningContent string `json:"reasoning_content,omitempty"`
ToolCalls []ChunkToolCall `json:"tool_calls,omitempty"`
Annotations []Annotation `json:"annotations,omitempty"`
}
ChunkDelta is the new text or tool-call pieces in a chunk.
type ChunkToolCall ¶
type ChunkToolCall struct {
Index int `json:"index"`
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Function ToolCallFunction `json:"function"`
}
ChunkToolCall is a piece of a tool call; pieces with the same Index belong together.
type Client ¶
type Client struct {
// Chat holds the chat completion resource.
Chat *ChatService
// Models lists the models this key can use.
Models *ModelsService
// Tasks reads image and video tasks.
Tasks *TasksService
// Videos starts video tasks.
Videos *VideosService
// Images starts image tasks.
Images *ImagesService
// contains filtered or unexported fields
}
Client is a FreeTheAI API client. It is safe for concurrent use.
func NewClient ¶
NewClient creates a client. It fails when no key is given or the key is only part of a key.
func (*Client) Answer ¶
func (c *Client) Answer(ctx context.Context, params SearchParams) (*AnswerResponse, error)
Answer answers a question from current web sources and returns the answer and its sources.
func (*Client) Search ¶
func (c *Client) Search(ctx context.Context, params SearchParams) (*SearchResponse, error)
Search searches the web and returns results with title, url, and text.
type CompletionsService ¶
type CompletionsService struct {
// contains filtered or unexported fields
}
CompletionsService creates chat completions.
func (*CompletionsService) New ¶
func (s *CompletionsService) New(ctx context.Context, params ChatCompletionParams) (*ChatCompletion, error)
New creates a chat completion and returns the whole reply. Fallback models are tried in order when a model is busy, filtered, unknown, or still failing.
func (*CompletionsService) NewStreaming ¶
func (s *CompletionsService) NewStreaming(ctx context.Context, params ChatCompletionParams) (*ChatCompletionStream, error)
NewStreaming starts a streamed chat completion. It returns once the first piece of the reply has arrived, so a busy model can fall back before anything is shown. Read it with Next, then check Err, and Close it when you are done (Close is safe to call more than once).
func (*CompletionsService) StreamText ¶
func (s *CompletionsService) StreamText(ctx context.Context, params ChatCompletionParams, onText func(string) error) error
StreamText returns the reply text piece by piece, through the callback. It stops at the first error from the callback or from the stream.
type ConcurrencyLimitError ¶
type ConcurrencyLimitError struct{ APIError }
ConcurrencyLimitError is a 429: the account already has as many replies running as its plan allows.
func (*ConcurrencyLimitError) Unwrap ¶
func (e *ConcurrencyLimitError) Unwrap() error
Unwrap returns the base APIError.
type ConnectionError ¶
type ConnectionError struct{ Message string }
ConnectionError means no answer came back (network error or timeout).
func (*ConnectionError) Error ¶
func (e *ConnectionError) Error() string
type ContentFilterError ¶
type ContentFilterError struct{ APIError }
ContentFilterError is a 400: the model's content filter refused the request or its reply. Rephrasing or another model usually works.
func (*ContentFilterError) Unwrap ¶
func (e *ContentFilterError) Unwrap() error
Unwrap returns the base APIError.
type ContentPart ¶
type ContentPart struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
ImageURL *ImageURL `json:"image_url,omitempty"`
}
ContentPart is one piece of multimodal content: text, or an image URL.
type DailyLimitError ¶
type DailyLimitError struct{ APIError }
DailyLimitError is a 429: today's free requests are used up.
func (*DailyLimitError) ResetsAt ¶
func (e *DailyLimitError) ResetsAt() time.Time
ResetsAt returns the next 00:00 UTC, when the daily allowance resets.
func (*DailyLimitError) Unwrap ¶
func (e *DailyLimitError) Unwrap() error
Unwrap returns the base APIError.
type EmailNotVerifiedError ¶
type EmailNotVerifiedError struct{ APIError }
EmailNotVerifiedError is a 403: confirm the account's email address before using the API.
func (*EmailNotVerifiedError) Unwrap ¶
func (e *EmailNotVerifiedError) Unwrap() error
Unwrap returns the base APIError.
type ImageGenerateParams ¶
type ImageGenerateParams struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
// N is how many images, 1 to 4 (default 1).
N int `json:"n,omitempty"`
// Size is WIDTHxHEIGHT, such as "1024x1024".
Size string `json:"size,omitempty"`
// ResponseFormat is "b64_json" (default) or "url".
ResponseFormat string `json:"response_format,omitempty"`
// Image is an optional source image: an https URL or a base64 data URL.
Image string `json:"image,omitempty"`
}
ImageGenerateParams starts an image task.
type ImagesNotSupportedError ¶
type ImagesNotSupportedError struct{ APIError }
ImagesNotSupportedError is a 400: the model reads text only.
func (*ImagesNotSupportedError) Unwrap ¶
func (e *ImagesNotSupportedError) Unwrap() error
Unwrap returns the base APIError.
type ImagesService ¶
type ImagesService struct {
// contains filtered or unexported fields
}
ImagesService starts image tasks.
func (*ImagesService) Generate ¶
func (s *ImagesService) Generate(ctx context.Context, params ImageGenerateParams) (*Task, error)
Generate starts an image task. Wait for it with Tasks.Wait.
type IncompleteKeyError ¶
type IncompleteKeyError struct{ APIError }
IncompleteKeyError means the key is only part of a key. Keys are shown once.
func (*IncompleteKeyError) Unwrap ¶
func (e *IncompleteKeyError) Unwrap() error
Unwrap returns the base APIError.
type InternalServerError ¶
type InternalServerError struct{ APIError }
InternalServerError is a 5xx: the service is temporarily unavailable.
func (*InternalServerError) Unwrap ¶
func (e *InternalServerError) Unwrap() error
Unwrap returns the base APIError.
type Message ¶
type Message struct {
Role string `json:"role"`
Content any `json:"content,omitempty"`
Name string `json:"name,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
}
Message is one message you send. Content is a string, or a []ContentPart for models that read images.
type Model ¶
type Model struct {
ID string `json:"id"`
Object string `json:"object,omitempty"`
Created int64 `json:"created,omitempty"`
OwnedBy string `json:"owned_by,omitempty"`
}
Model is one entry from the models list. ID is what you pass as the model.
type ModelBusyError ¶
type ModelBusyError struct{ APIError }
ModelBusyError is a 503: every route for the model is busy.
func (*ModelBusyError) Unwrap ¶
func (e *ModelBusyError) Unwrap() error
Unwrap returns the base APIError.
type ModelNotFoundError ¶
ModelNotFoundError is a 404: no model has this ID. Suggestions lists close model IDs.
func (*ModelNotFoundError) Unwrap ¶
func (e *ModelNotFoundError) Unwrap() error
Unwrap returns the base APIError.
type ModelsService ¶
type ModelsService struct {
// contains filtered or unexported fields
}
ModelsService lists models.
type NotFoundError ¶
type NotFoundError struct{ APIError }
NotFoundError is a 404: unknown task or route.
func (*NotFoundError) Unwrap ¶
func (e *NotFoundError) Unwrap() error
Unwrap returns the base APIError.
type Option ¶
type Option func(*Client)
Option configures a Client. Pass options to NewClient.
func WithAPIKey ¶
WithAPIKey sets the API key. Without it, NewClient reads FREETHEAI_API_KEY.
func WithBaseURL ¶
WithBaseURL sets the API address. Without it, NewClient reads FREETHEAI_BASE_URL.
func WithFallbackModels ¶
WithFallbackModels sets the models tried in order after the first one fails.
func WithHTTPClient ¶
WithHTTPClient uses your own *http.Client (proxies, TLS, transports).
func WithHeader ¶
WithHeader adds a header to every request.
func WithMaxConcurrency ¶
WithMaxConcurrency caps the replies in flight. Without it, the client learns the account's limit.
func WithMaxRetries ¶
WithMaxRetries sets the retries per model for retryable errors. The default is 3.
func WithStreamTransport ¶
WithStreamTransport turns the stream transport on or off. It is on by default: non-streamed chats are fetched as a stream and assembled, so long replies never idle out.
func WithTimeout ¶
WithTimeout sets how long a plain (non-streamed) request may take. The default is 10 minutes.
type PermissionDeniedError ¶
type PermissionDeniedError struct{ APIError }
PermissionDeniedError is a 403: this key may not do this.
func (*PermissionDeniedError) Unwrap ¶
func (e *PermissionDeniedError) Unwrap() error
Unwrap returns the base APIError.
type ProviderBudgetError ¶
type ProviderBudgetError struct{ APIError }
ProviderBudgetError is a 429: today's token budget for this model is used up. Models from other providers still work.
func (*ProviderBudgetError) Unwrap ¶
func (e *ProviderBudgetError) Unwrap() error
Unwrap returns the base APIError.
type RateLimitError ¶
type RateLimitError struct{ APIError }
RateLimitError is a 429: too many requests.
func (*RateLimitError) Unwrap ¶
func (e *RateLimitError) Unwrap() error
Unwrap returns the base APIError.
type RequestTooLargeError ¶
type RequestTooLargeError struct{ APIError }
RequestTooLargeError is a 413: the request body is over the size limit.
func (*RequestTooLargeError) Unwrap ¶
func (e *RequestTooLargeError) Unwrap() error
Unwrap returns the base APIError.
type ResponseMessage ¶
type ResponseMessage struct {
Role string `json:"role"`
Content string `json:"content"`
ReasoningContent string `json:"reasoning_content,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
Annotations []Annotation `json:"annotations,omitempty"`
}
ResponseMessage is the assistant's reply.
type SearchParams ¶
type SearchParams struct {
Query string `json:"query"`
// NumResults is 1 to 25 (default 10).
NumResults int `json:"num_results,omitempty"`
}
SearchParams is the input for Search and Answer.
type SearchResponse ¶
type SearchResponse struct {
Query string `json:"query"`
Results []SearchResult `json:"results"`
Suggestions []string `json:"suggestions,omitempty"`
DailyUsed int `json:"daily_used,omitempty"`
DailyLimit int `json:"daily_limit,omitempty"`
}
SearchResponse is the result of Client.Search.
type SearchResult ¶
type SearchResult struct {
Title string `json:"title,omitempty"`
URL string `json:"url,omitempty"`
Text string `json:"text,omitempty"`
Highlights []string `json:"highlights,omitempty"`
PublishedDate string `json:"publishedDate,omitempty"`
Score float64 `json:"score,omitempty"`
}
SearchResult is one web page.
type StreamInterruptedError ¶
StreamInterruptedError means a streamed reply stopped before the model finished. Partial holds the text that arrived before the cut.
func (*StreamInterruptedError) Error ¶
func (e *StreamInterruptedError) Error() string
type Task ¶
type Task struct {
ID string `json:"id"`
Object string `json:"object,omitempty"`
Kind string `json:"kind,omitempty"`
Model string `json:"model,omitempty"`
Status string `json:"status"`
CreatedAt int64 `json:"created_at,omitempty"`
CompletedAt int64 `json:"completed_at,omitempty"`
ExpiresAt int64 `json:"expires_at,omitempty"`
ContentURL string `json:"content_url,omitempty"`
Data []TaskOutput `json:"data,omitempty"`
Error *TaskError `json:"error,omitempty"`
}
Task is an image or video task.
type TaskError ¶
type TaskError struct {
Code string `json:"code,omitempty"`
Message string `json:"message,omitempty"`
ErrorID string `json:"error_id,omitempty"`
}
TaskError says why a task failed.
type TaskFailedError ¶
TaskFailedError means an image or video task ended without output.
func (*TaskFailedError) Error ¶
func (e *TaskFailedError) Error() string
type TaskOutput ¶
type TaskOutput struct {
B64JSON string `json:"b64_json,omitempty"`
URL string `json:"url,omitempty"`
}
TaskOutput is one finished image: base64 bytes, or a download URL.
type TasksService ¶
type TasksService struct {
// contains filtered or unexported fields
}
TasksService reads image and video tasks.
func (*TasksService) Content ¶
Content downloads a finished task's output (image or video bytes). index picks one of several outputs.
func (*TasksService) List ¶
List returns your tasks, newest first. Limit 0 uses the API default (20).
func (*TasksService) Wait ¶
func (s *TasksService) Wait(ctx context.Context, id string, opts WaitOptions) (*Task, error)
Wait polls until the task finishes. It returns a *TaskFailedError when the task failed, and an error when the timeout passes first.
type Tool ¶
type Tool struct {
Type string `json:"type"`
Function ToolFunction `json:"function"`
}
Tool declares a function the model may call.
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"`
Type string `json:"type"`
Function ToolCallFunction `json:"function"`
}
ToolCall is a function call the model made.
type ToolCallFunction ¶
ToolCallFunction holds the name and JSON arguments of a call.
type ToolFunction ¶
type ToolFunction struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Parameters map[string]any `json:"parameters,omitempty"`
}
ToolFunction describes a callable function. Parameters is a JSON Schema object.
type URLCitation ¶
URLCitation is the page a web search answer came from.
type Usage ¶
type Usage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
}
Usage reports token counts. The final streamed chunk carries it.
type VideoCreateParams ¶
type VideoCreateParams struct {
Model string `json:"model"`
// Prompt says what should happen in the video (up to 7000 characters).
Prompt string `json:"prompt,omitempty"`
// InputReference is the first frame: an https image URL or a base64 data URL.
InputReference string `json:"input_reference,omitempty"`
// Seconds is the duration, as a string such as "6".
Seconds string `json:"seconds,omitempty"`
// Size is the output size as WIDTHxHEIGHT, such as "720x1280".
Size string `json:"size,omitempty"`
}
VideoCreateParams starts a video task.
type VideosService ¶
type VideosService struct {
// contains filtered or unexported fields
}
VideosService starts video tasks.
func (*VideosService) Create ¶
func (s *VideosService) Create(ctx context.Context, params VideoCreateParams) (*Task, error)
Create starts a video task. Wait for it with Tasks.Wait.
