Skip to content

OpenAI plugin

The OpenAI plugin provides access to OpenAI models. It is one of the OpenAI-compatible plugins, so it shares that family’s model catalog behavior and response handling.

import "github.com/firebase/genkit/go/plugins/compat_oai/openai"
g := genkit.Init(context.Background(),
genkit.WithPlugins(&openai.OpenAI{
APIKey: "YOUR_OPENAI_API_KEY", // or set OPENAI_API_KEY
}),
genkit.WithDefaultModel("openai/gpt-5.4"),
)

genkit.Init panics when neither the APIKey field nor OPENAI_API_KEY carries a key. OPENAI_ORG_ID and OPENAI_PROJECT_ID are read too, and sent as the OpenAI-Organization and OpenAI-Project headers; option.WithOrganization or option.WithProject in Opts wins over them. There is no base URL environment variable; to reach a proxy or a compatible endpoint, pass option.WithBaseURL through Opts:

g := genkit.Init(ctx, genkit.WithPlugins(&openai.OpenAI{
Opts: []option.RequestOption{
option.WithBaseURL("https://your-proxy.example.com/v1"),
},
}))

The plugin also takes Models map[string]ai.ModelOptions and Embedders map[string]ai.EmbedderOptions to correct or extend what it knows about a model. See model catalogs.

The plugin curates capabilities for these chat models. The list is a starting point, not a limit: any other OpenAI chat model resolves on demand under the openai/ prefix and takes generic multimodal defaults.

  • gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna
  • gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.4-nano, gpt-5.2, gpt-5.1
  • gpt-5, gpt-5-mini, gpt-5-nano
  • gpt-4.1, gpt-4.1-mini, gpt-4.1-nano
  • gpt-4o, gpt-4o-mini
  • o3, o4-mini, o3-mini, o1
  • gpt-4-turbo, gpt-4, gpt-3.5-turbo

Dated snapshots are folded into their model’s versions rather than curated separately, so ask for gpt-4o and pin the snapshot with the config’s Model field when you need one.

Curated embedders:

  • text-embedding-3-large, 3072 dimensions
  • text-embedding-3-small, 1536 dimensions
  • text-embedding-ada-002, 1536 dimensions

Image, audio, realtime, transcription, and moderation models are not chat models, so the plugin does not curate them.

OpenAI models take the OpenAI SDK’s own request type, *openai.ChatCompletionNewParams, as their config, under OpenAI’s wire names. There is no openai.ChatConfig. Genkit validates the config against the SDK schema before the request goes out, so a field the API does not have fails before it is billed.

The schema hides the fields Genkit builds from the request itself, so a config that sets messages, tools, tool_choice, or response_format is refused with the name of the Genkit option to use instead. n is hidden too, since the response path serves the first choice only.

import (
"github.com/firebase/genkit/go/ai"
"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/compat_oai/openai"
openaiGo "github.com/openai/openai-go"
)
resp, err := genkit.Generate(ctx, g,
ai.WithModel(openai.ModelRef("gpt-5.4", &openaiGo.ChatCompletionNewParams{
Temperature: openaiGo.Float(0.2),
MaxCompletionTokens: openaiGo.Int(1024),
})),
ai.WithPrompt("Explain quantum computing."),
)

The compat_oai/openai sample is this pattern as a runnable streaming flow.

Embedders take openai.TextEmbeddingConfig, shared with the rest of the OpenAI-compatible family:

resp, err := genkit.Embed(ctx, g,
ai.WithEmbedder(openai.NewEmbedderRef("text-embedding-3-small", &openai.TextEmbeddingConfig{
Dimensions: 256,
})),
ai.WithTextDocs("Hello, world!"),
)

OpenAI models support tool calling:

weatherTool := genkit.DefineTool(g, "get_weather", "Get the current weather",
func(ctx *ai.ToolContext, input struct {
City string `json:"city"`
}) (string, error) {
return fmt.Sprintf("It is sunny in %s.", input.City), nil
})
resp, err := genkit.Generate(ctx, g,
ai.WithModel(openai.ModelRef("gpt-5.4", nil)),
ai.WithPrompt("What is the weather like in San Francisco?"),
ai.WithTools(weatherTool),
)

OpenAI models support vision:

resp, err := genkit.Generate(ctx, g,
ai.WithModel(openai.ModelRef("gpt-5.4", nil)),
ai.WithMessages(
ai.NewUserMessage(
ai.NewTextPart("What do you see in this image?"),
ai.NewMediaPart("image/jpeg", imageDataURI),
),
),
)

OpenAI models support streaming responses, and streamed responses report token usage:

resp, err := genkit.Generate(ctx, g,
ai.WithModel(openai.ModelRef("gpt-5.4", nil)),
ai.WithPrompt("Write a long explanation."),
ai.WithStreaming(func(ctx context.Context, chunk *ai.ModelResponseChunk) error {
for _, content := range chunk.Content {
fmt.Print(content.Text)
}
return nil
}),
)

For a service with no plugin of its own, register the base compat_oai.OpenAICompatible plugin instead. See custom provider.