diff --git a/go/plugins/compat_oai/anthropic/anthropic.go b/go/plugins/compat_oai/anthropic/anthropic.go index ed33a60fc3..0942f46846 100644 --- a/go/plugins/compat_oai/anthropic/anthropic.go +++ b/go/plugins/compat_oai/anthropic/anthropic.go @@ -18,6 +18,7 @@ import ( "context" "github.com/firebase/genkit/go/ai" + "github.com/firebase/genkit/go/core" "github.com/firebase/genkit/go/genkit" "github.com/firebase/genkit/go/plugins/compat_oai" "github.com/openai/openai-go/option" @@ -28,61 +29,59 @@ const ( baseURL = "https://api.anthropic.com/v1" ) -var ( - // Supported models: https://docs.anthropic.com/en/docs/about-claude/models/all-models - supportedModels = map[string]ai.ModelInfo{ - "claude-3-7-sonnet-20250219": { - Label: "Claude 3.7 Sonnet", - Supports: &ai.ModelSupports{ - Multiturn: true, - Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API - SystemRole: true, - Media: true, - }, - Versions: []string{"claude-3-7-sonnet-latest", "claude-3-7-sonnet-20250219"}, +// Supported models: https://docs.anthropic.com/en/docs/about-claude/models/all-models +var supportedModels = map[string]ai.ModelInfo{ + "claude-3-7-sonnet-20250219": { + Label: "Claude 3.7 Sonnet", + Supports: &ai.ModelSupports{ + Multiturn: true, + Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API + SystemRole: true, + Media: true, }, - "claude-3-5-haiku-20241022": { - Label: "Claude 3.5 Haiku", - Supports: &ai.ModelSupports{ - Multiturn: true, - Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API - SystemRole: true, - Media: true, - }, - Versions: []string{"claude-3-5-haiku-latest", "claude-3-5-haiku-20241022"}, + Versions: []string{"claude-3-7-sonnet-latest", "claude-3-7-sonnet-20250219"}, + }, + "claude-3-5-haiku-20241022": { + Label: "Claude 3.5 Haiku", + Supports: &ai.ModelSupports{ + Multiturn: true, + Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API + SystemRole: true, + Media: true, }, - "claude-3-5-sonnet-20240620": { - Label: "Claude 3.5 Sonnet", - Supports: &ai.ModelSupports{ - Multiturn: true, - Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API - SystemRole: false, // NOTE: This model does not support system role - Media: true, - }, - Versions: []string{"claude-3-5-sonnet-20240620"}, + Versions: []string{"claude-3-5-haiku-latest", "claude-3-5-haiku-20241022"}, + }, + "claude-3-5-sonnet-20240620": { + Label: "Claude 3.5 Sonnet", + Supports: &ai.ModelSupports{ + Multiturn: true, + Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API + SystemRole: false, // NOTE: This model does not support system role + Media: true, }, - "claude-3-opus-20240229": { - Label: "Claude 3 Opus", - Supports: &ai.ModelSupports{ - Multiturn: true, - Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API - SystemRole: false, // NOTE: This model does not support system role - Media: true, - }, - Versions: []string{"claude-3-opus-latest", "claude-3-opus-20240229"}, + Versions: []string{"claude-3-5-sonnet-20240620"}, + }, + "claude-3-opus-20240229": { + Label: "Claude 3 Opus", + Supports: &ai.ModelSupports{ + Multiturn: true, + Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API + SystemRole: false, // NOTE: This model does not support system role + Media: true, }, - "claude-3-haiku-20240307": { - Label: "Claude 3 Haiku", - Supports: &ai.ModelSupports{ - Multiturn: true, - Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API - SystemRole: false, // NOTE: This model does not support system role - Media: true, - }, - Versions: []string{"claude-3-haiku-20240307"}, + Versions: []string{"claude-3-opus-latest", "claude-3-opus-20240229"}, + }, + "claude-3-haiku-20240307": { + Label: "Claude 3 Haiku", + Supports: &ai.ModelSupports{ + Multiturn: true, + Tools: false, // NOTE: Anthropic supports tool use, but it's not compatible with the OpenAI API + SystemRole: false, // NOTE: This model does not support system role + Media: true, }, - } -) + Versions: []string{"claude-3-haiku-20240307"}, + }, +} type Anthropic struct { Opts []option.RequestOption @@ -100,6 +99,7 @@ func (a *Anthropic) Init(ctx context.Context, g *genkit.Genkit) error { // initialize OpenAICompatible a.openAICompatible.Opts = a.Opts + a.openAICompatible.Provider = provider if err := a.openAICompatible.Init(ctx, g); err != nil { return err } @@ -121,3 +121,11 @@ func (a *Anthropic) Model(g *genkit.Genkit, name string) ai.Model { func (a *Anthropic) DefineModel(g *genkit.Genkit, name string, info ai.ModelInfo) (ai.Model, error) { return a.openAICompatible.DefineModel(g, provider, name, info) } + +func (a *Anthropic) ListActions(ctx context.Context) []core.ActionDesc { + return a.openAICompatible.ListActions(ctx) +} + +func (a *Anthropic) ResolveAction(g *genkit.Genkit, atype core.ActionType, name string) error { + return a.openAICompatible.ResolveAction(g, atype, name) +} diff --git a/go/plugins/compat_oai/compat_oai.go b/go/plugins/compat_oai/compat_oai.go index 47c902fcde..762bb4e504 100644 --- a/go/plugins/compat_oai/compat_oai.go +++ b/go/plugins/compat_oai/compat_oai.go @@ -17,35 +17,34 @@ package compat_oai import ( "context" "errors" + "fmt" "strings" "sync" "github.com/firebase/genkit/go/ai" + "github.com/firebase/genkit/go/core" "github.com/firebase/genkit/go/genkit" + "github.com/openai/openai-go" openaiGo "github.com/openai/openai-go" "github.com/openai/openai-go/option" ) var ( // BasicText describes model capabilities for text-only GPT models. - BasicText = ai.ModelInfo{ - Supports: &ai.ModelSupports{ - Multiturn: true, - Tools: true, - SystemRole: true, - Media: false, - }, + BasicText = ai.ModelSupports{ + Multiturn: true, + Tools: true, + SystemRole: true, + Media: false, } // Multimodal describes model capabilities for multimodal GPT models. - Multimodal = ai.ModelInfo{ - Supports: &ai.ModelSupports{ - Multiturn: true, - Tools: true, - SystemRole: true, - Media: true, - ToolChoice: true, - }, + Multimodal = ai.ModelSupports{ + Multiturn: true, + Tools: true, + SystemRole: true, + Media: true, + ToolChoice: true, } ) @@ -110,7 +109,6 @@ func (o *OpenAICompatible) DefineModel(g *genkit.Genkit, provider, name string, input *ai.ModelRequest, cb func(context.Context, *ai.ModelResponseChunk) error, ) (*ai.ModelResponse, error) { - // Configure the response generator with input generator := NewModelGenerator(o.client, modelName).WithMessages(input.Messages).WithConfig(input.Config).WithTools(input.Tools, input.ToolChoice) @@ -184,3 +182,70 @@ func (o *OpenAICompatible) Model(g *genkit.Genkit, name string, provider string) func (o *OpenAICompatible) IsDefinedModel(g *genkit.Genkit, name string, provider string) bool { return genkit.LookupModel(g, provider, name) != nil } + +func (o *OpenAICompatible) ListActions(ctx context.Context) []core.ActionDesc { + actions := []core.ActionDesc{} + + models, err := listOpenAIModels(ctx, o.client) + if err != nil { + return nil + } + for _, name := range models { + metadata := map[string]any{ + "model": map[string]any{ + "supports": map[string]any{ + "media": true, + "multiturn": true, + "systemRole": true, + "tools": true, + "toolChoice": true, + "constrained": true, + }, + }, + "versions": []string{}, + "stage": string(ai.ModelStageStable), + } + metadata["label"] = fmt.Sprintf("%s - %s", o.Provider, name) + + actions = append(actions, core.ActionDesc{ + Type: core.ActionTypeModel, + Name: fmt.Sprintf("%s/%s", o.Provider, name), + Key: fmt.Sprintf("/%s/%s/%s", core.ActionTypeModel, o.Provider, name), + Metadata: metadata, + }) + } + + return actions +} + +func (o *OpenAICompatible) ResolveAction(g *genkit.Genkit, atype core.ActionType, name string) error { + switch atype { + case core.ActionTypeModel: + o.DefineModel(g, o.Provider, name, ai.ModelInfo{ + Label: fmt.Sprintf("%s - %s", o.Provider, name), + Stage: ai.ModelStageStable, + Versions: []string{}, + Supports: &Multimodal, + }) + } + + return nil +} + +func listOpenAIModels(ctx context.Context, client *openai.Client) ([]string, error) { + models := []string{} + iter := client.Models.ListAutoPaging(ctx) + for iter.Next() { + m := iter.Current() + if m.Object != "model" { + continue + } + fmt.Printf("(openai) model: %s\n", m.ID) + models = append(models, m.ID) + } + if err := iter.Err(); err != nil { + return nil, err + } + + return models, nil +} diff --git a/go/plugins/compat_oai/openai/openai.go b/go/plugins/compat_oai/openai/openai.go index 0db9c8636f..ae4bb47a40 100644 --- a/go/plugins/compat_oai/openai/openai.go +++ b/go/plugins/compat_oai/openai/openai.go @@ -20,6 +20,7 @@ import ( "os" "github.com/firebase/genkit/go/ai" + "github.com/firebase/genkit/go/core" "github.com/firebase/genkit/go/genkit" "github.com/firebase/genkit/go/plugins/compat_oai" openaiGo "github.com/openai/openai-go" @@ -33,27 +34,27 @@ var ( supportedModels = map[string]ai.ModelInfo{ "gpt-4.1": { Label: "OpenAI GPT-4.1", - Supports: compat_oai.Multimodal.Supports, + Supports: &compat_oai.Multimodal, Versions: []string{"gpt-4.1", "gpt-4.1-2025-04-14"}, }, "gpt-4.1-mini": { Label: "OpenAI GPT-4.1-mini", - Supports: compat_oai.Multimodal.Supports, + Supports: &compat_oai.Multimodal, Versions: []string{"gpt-4.1-mini", "gpt-4.1-mini-2025-04-14"}, }, "gpt-4.1-nano": { Label: "OpenAI GPT-4.1-nano", - Supports: compat_oai.Multimodal.Supports, + Supports: &compat_oai.Multimodal, Versions: []string{"gpt-4.1-nano", "gpt-4.1-nano-2025-04-14"}, }, openaiGo.ChatModelO3Mini: { Label: "OpenAI o3-mini", - Supports: compat_oai.BasicText.Supports, + Supports: &compat_oai.BasicText, Versions: []string{"o3-mini", "o3-mini-2025-01-31"}, }, openaiGo.ChatModelO1: { Label: "OpenAI o1", - Supports: compat_oai.BasicText.Supports, + Supports: &compat_oai.BasicText, Versions: []string{"o1", "o1-2024-12-17"}, }, openaiGo.ChatModelO1Preview: { @@ -78,22 +79,22 @@ var ( }, openaiGo.ChatModelGPT4_5Preview: { Label: "OpenAI GPT-4.5-preview", - Supports: compat_oai.Multimodal.Supports, + Supports: &compat_oai.Multimodal, Versions: []string{"gpt-4.5-preview", "gpt-4.5-preview-2025-02-27"}, }, openaiGo.ChatModelGPT4o: { Label: "OpenAI GPT-4o", - Supports: compat_oai.Multimodal.Supports, + Supports: &compat_oai.Multimodal, Versions: []string{"gpt-4o", "gpt-4o-2024-11-20", "gpt-4o-2024-08-06", "gpt-4o-2024-05-13"}, }, openaiGo.ChatModelGPT4oMini: { Label: "OpenAI GPT-4o-mini", - Supports: compat_oai.Multimodal.Supports, + Supports: &compat_oai.Multimodal, Versions: []string{"gpt-4o-mini", "gpt-4o-mini-2024-07-18"}, }, openaiGo.ChatModelGPT4Turbo: { Label: "OpenAI GPT-4-turbo", - Supports: compat_oai.Multimodal.Supports, + Supports: &compat_oai.Multimodal, Versions: []string{"gpt-4-turbo", "gpt-4-turbo-2024-04-09", "gpt-4-turbo-preview", "gpt-4-0125-preview"}, }, openaiGo.ChatModelGPT4: { @@ -167,6 +168,7 @@ func (o *OpenAI) Init(ctx context.Context, g *genkit.Genkit) error { o.openAICompatible.Opts = append(o.openAICompatible.Opts, o.Opts...) } + o.openAICompatible.Provider = provider if err := o.openAICompatible.Init(ctx, g); err != nil { return err } @@ -203,3 +205,11 @@ func (o *OpenAI) DefineEmbedder(g *genkit.Genkit, name string) (ai.Embedder, err func (o *OpenAI) Embedder(g *genkit.Genkit, name string) ai.Embedder { return o.openAICompatible.Embedder(g, name, provider) } + +func (o *OpenAI) ListActions(ctx context.Context) []core.ActionDesc { + return o.openAICompatible.ListActions(ctx) +} + +func (o *OpenAI) ResolveAction(g *genkit.Genkit, atype core.ActionType, name string) error { + return o.openAICompatible.ResolveAction(g, atype, name) +}