Skip to content

feat(py): add list_actions method to OpenAI compat plugin #3240

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions py/packages/genkit/src/genkit/ai/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from genkit.core.registry import ActionKind

from ..core.action import ActionMetadata
from ._registry import GenkitRegistry


Expand Down Expand Up @@ -75,14 +76,14 @@ def initialize(self, ai: GenkitRegistry) -> None:
"""
pass

def list_actions(self) -> list[dict[str, str]]:
def list_actions(self) -> list[ActionMetadata]:
"""Generate a list of available actions or models.

Returns:
list of actions dicts with the following shape:
{
'name': str,
'kind': ActionKind,
}
list[ActionMetadata]: A list of ActionMetadata objects, each with the following attributes:
- name (str): The name of the action or model.
- kind (ActionKind): The type or category of the action.
- info (dict): The metadata dictionary describing the model configuration and properties.
- config_schema (type): The schema class used for validating the model's configuration.
"""
return []
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@


"""OpenAI OpenAI API Compatible Plugin for Genkit."""
from functools import cached_property
from typing import Any, Callable

from openai import Client, OpenAI as OpenAIClient
from openai import OpenAI as OpenAIClient
from openai.types import Embedding, Model

from genkit.ai._plugin import Plugin
from genkit.ai._registry import GenkitRegistry
from genkit.blocks.embedding import embedder_action_metadata
from genkit.blocks.model import model_action_metadata
from genkit.core.action import ActionMetadata
from genkit.core.action.types import ActionKind
from genkit.core.typing import GenerationCommonConfig
from genkit.plugins.compat_oai.models import (
SUPPORTED_OPENAI_COMPAT_MODELS,
SUPPORTED_OPENAI_MODELS,
Expand Down Expand Up @@ -165,6 +171,53 @@ def _define_openai_model(self, ai: GenkitRegistry, name: str) -> None:
},
)

@cached_property
def list_actions(self) -> list[ActionMetadata]:
"""Generate a list of available actions or models.

Returns:
list[ActionMetadata]: A list of ActionMetadata objects, each with the following attributes:
- name (str): The name of the action or model.
- kind (ActionKind): The type or category of the action.
- info (dict): The metadata dictionary describing the model configuration and properties.
- config_schema (type): The schema class used for validating the model's configuration.
"""

actions = []
models_ = self._openai_client.models.list()
models: list[Model] = models_.data
# Print each model
for model in models:
_name = model.id
if 'embed' in _name:
actions.append(
embedder_action_metadata(
name=open_ai_name(_name),
config_schema=Embedding,
info={
'label': f'OpenAI Embedding - {_name}',
'dimensions': None,
'supports': {
'input': ['text'],
},
},
)
)
else:
actions.append(
model_action_metadata(
name=open_ai_name(_name),
config_schema=GenerationCommonConfig,
info={
'label': f'OpenAI - {_name}',
'multiturn': True,
'system_role': True,
'tools': False,
},
)
)
return actions




Expand Down
30 changes: 30 additions & 0 deletions py/plugins/compat-oai/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
from unittest.mock import ANY, MagicMock, patch

import pytest
from openai.types import Model

from genkit.ai._aio import Genkit
from genkit.core.action import ActionMetadata
from genkit.core.action.types import ActionKind
from genkit.plugins.compat_oai import OpenAIConfig
from genkit.plugins.compat_oai.models.model_info import SUPPORTED_OPENAI_MODELS
Expand Down Expand Up @@ -76,6 +78,34 @@ def test_openai_plugin_resolve_action(kind, name):
)


def test_openai_plugin_list_actions() -> None:
entries = [
Model(id='gpt-4-0613', created=1686588896, object='model', owned_by='openai'),
Model(id='gpt-4', created=1687882411, object='model', owned_by='openai'),
Model(id='gpt-3.5-turbo', created=1677610602, object='model', owned_by='openai'),
Model(id='o4-mini-deep-research-2025-06-26', created=1750866121, object='model', owned_by='system'),
Model(id='codex-mini-latest', created=1746673257, object='model', owned_by='system'),
Model(id='text-embedding-ada-002', created=1671217299, object='model', owned_by='openai-internal')
]
plugin = OpenAI(api_key='test-key')
mock_client = MagicMock()

mock_result_ = MagicMock()
mock_result_.data = entries
mock_client.models.list.return_value = mock_result_

plugin._openai_client = mock_client

actions: list[ActionMetadata ] = plugin.list_actions
mock_client.models.list.assert_called_once()
_ = plugin.list_actions
mock_client.models.list.assert_called_once()

assert len(actions) == len(entries)
assert actions[0].name == 'openai/gpt-4-0613'
assert actions[-1].name == 'openai/text-embedding-ada-002'


@pytest.mark.parametrize(
'kind, name',
[
Expand Down
25 changes: 13 additions & 12 deletions py/plugins/google-genai/src/genkit/plugins/google_genai/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from genkit.ai import GENKIT_CLIENT_HEADER, GenkitRegistry, Plugin
from genkit.blocks.embedding import embedder_action_metadata
from genkit.blocks.model import model_action_metadata
from genkit.core.action import ActionMetadata
from genkit.core.registry import ActionKind
from genkit.plugins.google_genai.models.embedder import (
Embedder,
Expand Down Expand Up @@ -218,15 +219,15 @@ def _resolve_embedder(self, ai: GenkitRegistry, name: str) -> None:
)

@cached_property
def list_actions(self) -> list[dict[str, str]]:
def list_actions(self) -> list[ActionMetadata]:
"""Generate a list of available actions or models.

Returns:
list of actions dicts with the following shape:
{
'name': str,
'kind': ActionKind,
}
list[ActionMetadata]: A list of ActionMetadata objects, each with the following attributes:
- name (str): The name of the action or model.
- kind (ActionKind): The type or category of the action.
- info (dict): The metadata dictionary describing the model configuration and properties.
- config_schema (type): The schema class used for validating the model's configuration.
"""
actions_list = list()
for m in self._client.models.list():
Expand Down Expand Up @@ -413,15 +414,15 @@ def _resolve_embedder(self, ai: GenkitRegistry, name: str) -> None:
)

@cached_property
def list_actions(self) -> list[dict[str, str]]:
def list_actions(self) -> list[ActionMetadata]:
"""Generate a list of available actions or models.

Returns:
list of actions dicts with the following shape:
{
'name': str,
'kind': ActionKind,
}
list[ActionMetadata]: A list of ActionMetadata objects, each with the following attributes:
- name (str): The name of the action or model.
- kind (ActionKind): The type or category of the action.
- info (dict): The metadata dictionary describing the model configuration and properties.
- config_schema (type): The schema class used for validating the model's configuration.
"""
actions_list = list()
for m in self._client.models.list():
Expand Down
10 changes: 9 additions & 1 deletion py/plugins/ollama/src/genkit/plugins/ollama/plugin_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,15 @@ def _define_ollama_embedder(self, ai: GenkitRegistry, embedder_ref: EmbeddingDef

@cached_property
def list_actions(self) -> list[dict[str, str]]:
"""."""
"""Generate a list of available actions or models.

Returns:
list[ActionMetadata]: A list of ActionMetadata objects, each with the following attributes:
- name (str): The name of the action or model.
- kind (ActionKind): The type or category of the action.
- info (dict): The metadata dictionary describing the model configuration and properties.
- config_schema (type): The schema class used for validating the model's configuration.
"""
try:
loop = asyncio.get_running_loop()
except RuntimeError:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from genkit.ai import GenkitRegistry, Plugin
from genkit.blocks.model import model_action_metadata
from genkit.core.action import ActionMetadata
from genkit.core.action.types import ActionKind
from genkit.plugins.compat_oai.models import SUPPORTED_OPENAI_COMPAT_MODELS
from genkit.plugins.compat_oai.typing import OpenAIConfig
Expand Down Expand Up @@ -120,16 +121,17 @@ def _resolve_model(self, ai: GenkitRegistry, name: str) -> None:
model_proxy.define_model()

@cached_property
def list_actions(self) -> list[dict[str, str]]:
def list_actions(self) -> list[ActionMetadata]:
"""Generate a list of available actions or models.

Returns:
list of actions dicts with the following shape:
{
'name': str,
'kind': ActionKind,
}
list[ActionMetadata]: A list of ActionMetadata objects, each with the following attributes:
- name (str): The name of the action or model.
- kind (ActionKind): The type or category of the action.
- info (dict): The metadata dictionary describing the model configuration and properties.
- config_schema (type): The schema class used for validating the model's configuration.
"""

actions_list = []
for model, model_info in SUPPORTED_OPENAI_COMPAT_MODELS.items():
actions_list.append(
Expand Down
Loading