openai is a Go client for the OpenAI API. It implements the
github.com/goloop/ai interface, so it looks and works like every other goloop
AI provider, and exposes OpenAI's native endpoints with their full options on
top.
- Chat completions:
Generatefor a single response,Streamfor token-by-token output throughiter.Seq2. - Tool use (function calling), multimodal image input and system prompts.
- Structured output:
ai.Formatmaps onto the provider's ownresponse_format(JSON mode or a JSON Schema); read it back withresp.JSON(&v). - Native
ChatCompletionandChatCompletionStreamwith the full option set (response_format, seed, n, ...), plus the responses API. - Image generation fitted to the model, with
ImageData.Bytes()for the image. - Embeddings, image generation, audio (transcription, translation, speech), moderations, models, files and batches.
- Retries on 429 and 5xx with backoff; normalized, typed API errors.
- Depends only on
github.com/goloop/aiand the standard library. - Hosted web search:
ai.Request.Hostedroutes to the responses endpoint, which is where that tool lives, and normalizes the result back to the chat vocabulary.
go get github.com/goloop/openaipackage main
import (
"context"
"fmt"
"os"
"github.com/goloop/ai"
"github.com/goloop/openai"
)
func main() {
c := openai.New(os.Getenv("OPENAI_API_KEY"))
resp, err := c.Generate(context.Background(), &ai.Request{
Model: openai.ModelGPT4oMini,
Messages: []ai.Message{ai.UserText("Say hello in one word.")},
})
if err != nil {
panic(err)
}
fmt.Println(resp.Text())
}for chunk, err := range c.Stream(ctx, req) {
if err != nil {
break
}
fmt.Print(chunk.Text)
if chunk.Done && chunk.Usage != nil {
fmt.Printf("\n[%d in / %d out]\n",
chunk.Usage.InputTokens, chunk.Usage.OutputTokens)
}
}Tools, images and system prompts use the same shared ai types as every other
provider (see the reference). For OpenAI-only options such as
structured output, build a native ChatRequest:
resp, _ := c.ChatCompletion(ctx, &openai.ChatRequest{
Model: openai.ModelGPT4oMini,
Messages: []openai.ChatMessage{{Role: "user", Content: "List two colors as JSON."}},
ResponseFormat: json.RawMessage(`{"type":"json_object"}`),
})c.Embed(ctx, "text-embedding-3-small", "hello", "world")
c.GenerateImage(ctx, &openai.ImageRequest{Model: "gpt-image-1", Prompt: "a cat"})
c.Transcribe(ctx, &openai.TranscriptionRequest{Model: "whisper-1", File: wav, Filename: "a.wav"})
c.Speech(ctx, &openai.SpeechRequest{Model: "gpt-4o-mini-tts", Input: "hi", Voice: "alloy"})
c.Moderate(ctx, "some text")
c.Models(ctx)
c.UploadFile(ctx, "in.jsonl", data, "batch")
c.CreateBatch(ctx, fileID, "/v1/chat/completions", "24h")
c.CreateResponse(ctx, &openai.ResponsesRequest{Model: "gpt-4o-mini", Input: "hi"})The responses API also streams. Range over ResponsesStream and read text from
response.output_text.delta events; the final response.completed event carries
the whole result and token usage:
for ev, err := range c.ResponsesStream(ctx, &openai.ResponsesRequest{
Model: "gpt-4o-mini", Input: "Tell me a joke.",
}) {
if err != nil {
break
}
if ev.Type == "response.output_text.delta" {
fmt.Print(ev.Delta)
}
}Full reference: DOC.md (Ukrainian: DOC.UK.md).
See CONTRIBUTING.md.
MIT - see LICENSE.
Preserve plain transcripts, reduce response text allocations, and support speech instructions.