From a4d625a7856985e1435211e7ffcce9287399747f Mon Sep 17 00:00:00 2001 From: Shruti Padamata Date: Thu, 17 Jul 2025 09:43:28 -0700 Subject: [PATCH] fix(js): Export RessourcePartSchema through genkit-tools --- genkit-tools/common/src/types/document.ts | 15 ++++ genkit-tools/common/src/types/model.ts | 5 ++ genkit-tools/genkit-schema.json | 69 +++++++++++++++++++ js/testapps/flow-simple-ai/src/index.ts | 2 +- py/packages/genkit/src/genkit/core/typing.py | 43 +++++++++++- .../plugins/compat_oai/models/model_info.py | 6 +- .../plugins/compat_oai/openai_plugin.py | 9 +-- py/plugins/compat-oai/tests/test_plugin.py | 10 +-- 8 files changed, 139 insertions(+), 20 deletions(-) diff --git a/genkit-tools/common/src/types/document.ts b/genkit-tools/common/src/types/document.ts index c21fbd9362..b389cd4d4e 100644 --- a/genkit-tools/common/src/types/document.ts +++ b/genkit-tools/common/src/types/document.ts @@ -28,6 +28,7 @@ const EmptyPartSchema = z.object({ metadata: z.record(z.unknown()).optional(), custom: z.record(z.unknown()).optional(), reasoning: z.never().optional(), + resource: z.never().optional(), }); /** @@ -147,6 +148,20 @@ export const CustomPartSchema = EmptyPartSchema.extend({ */ export type CustomPart = z.infer; +/** + * Zod schema of a resource part. + */ +export const ResourcePartSchema = EmptyPartSchema.extend({ + resource: z.object({ + uri: z.string(), + }), +}); + +/** + * Resource part. + */ +export type ResourcePart = z.infer; + // Disclaimer: genkit/js/ai/document.ts defines the following schema, type pair // as PartSchema and Part, respectively. genkit-tools cannot retain those names // due to it clashing with similar schema in model.ts, and genkit-tools diff --git a/genkit-tools/common/src/types/model.ts b/genkit-tools/common/src/types/model.ts index 57079ddfc4..41cfc074cb 100644 --- a/genkit-tools/common/src/types/model.ts +++ b/genkit-tools/common/src/types/model.ts @@ -20,12 +20,14 @@ import { DocumentDataSchema, MediaPartSchema, ReasoningPartSchema, + ResourcePartSchema, TextPartSchema, ToolRequestPartSchema, ToolResponsePartSchema, type CustomPart, type DataPart, type MediaPart, + type ResourcePart, type TextPart, type ToolRequestPart, type ToolResponsePart, @@ -34,12 +36,14 @@ export { CustomPartSchema, DataPartSchema, MediaPartSchema, + ResourcePartSchema, TextPartSchema, ToolRequestPartSchema, ToolResponsePartSchema, type CustomPart, type DataPart, type MediaPart, + type ResourcePart, type TextPart, type ToolRequestPart, type ToolResponsePart, @@ -77,6 +81,7 @@ export const PartSchema = z.union([ DataPartSchema, CustomPartSchema, ReasoningPartSchema, + ResourcePartSchema, ]); /** diff --git a/genkit-tools/genkit-schema.json b/genkit-tools/genkit-schema.json index bc637c7551..e3238e2952 100644 --- a/genkit-tools/genkit-schema.json +++ b/genkit-tools/genkit-schema.json @@ -27,6 +27,9 @@ }, "reasoning": { "not": {} + }, + "resource": { + "not": {} } }, "required": [ @@ -59,6 +62,9 @@ }, "reasoning": { "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" } }, "additionalProperties": false @@ -118,6 +124,9 @@ }, "reasoning": { "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" } }, "required": [ @@ -166,6 +175,9 @@ }, "reasoning": { "type": "string" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" } }, "required": [ @@ -173,6 +185,51 @@ ], "additionalProperties": false }, + "ResourcePart": { + "type": "object", + "properties": { + "text": { + "$ref": "#/$defs/CustomPart/properties/text" + }, + "media": { + "$ref": "#/$defs/CustomPart/properties/media" + }, + "toolRequest": { + "$ref": "#/$defs/CustomPart/properties/toolRequest" + }, + "toolResponse": { + "$ref": "#/$defs/CustomPart/properties/toolResponse" + }, + "data": { + "$ref": "#/$defs/CustomPart/properties/data" + }, + "metadata": { + "$ref": "#/$defs/CustomPart/properties/metadata" + }, + "custom": { + "$ref": "#/$defs/DataPart/properties/custom" + }, + "reasoning": { + "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "type": "object", + "properties": { + "uri": { + "type": "string" + } + }, + "required": [ + "uri" + ], + "additionalProperties": false + } + }, + "required": [ + "resource" + ], + "additionalProperties": false + }, "TextPart": { "type": "object", "properties": { @@ -199,6 +256,9 @@ }, "reasoning": { "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" } }, "required": [ @@ -232,6 +292,9 @@ }, "reasoning": { "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" } }, "required": [ @@ -281,6 +344,9 @@ }, "reasoning": { "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" } }, "required": [ @@ -1138,6 +1204,9 @@ }, { "$ref": "#/$defs/ReasoningPart" + }, + { + "$ref": "#/$defs/ResourcePart" } ] }, diff --git a/js/testapps/flow-simple-ai/src/index.ts b/js/testapps/flow-simple-ai/src/index.ts index 3d8d95cb95..c0a100f987 100644 --- a/js/testapps/flow-simple-ai/src/index.ts +++ b/js/testapps/flow-simple-ai/src/index.ts @@ -1264,7 +1264,7 @@ ai.defineResource( description: 'provides my resource', }, async (input) => { - return { content: [{ text: `resource ${input}` }] }; + return { content: [{ text: `resource ${input.uri}` }] }; } ); diff --git a/py/packages/genkit/src/genkit/core/typing.py b/py/packages/genkit/src/genkit/core/typing.py index 4f7a8877df..10871339fd 100644 --- a/py/packages/genkit/src/genkit/core/typing.py +++ b/py/packages/genkit/src/genkit/core/typing.py @@ -56,6 +56,7 @@ class CustomPart(BaseModel): metadata: dict[str, Any] | None = None custom: dict[str, Any] reasoning: Any | None = None + resource: Any | None = None class Media(BaseModel): @@ -66,6 +67,13 @@ class Media(BaseModel): url: str +class Resource1(BaseModel): + """Model for resource1 data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + uri: str + + class ToolRequest(BaseModel): """Model for toolrequest data.""" @@ -505,6 +513,12 @@ class Reasoning(RootModel[Any]): root: Any +class Resource(RootModel[Any]): + """Root model for resource.""" + + root: Any + + class Text(RootModel[Any]): """Root model for text.""" @@ -601,6 +615,7 @@ class DataPart(BaseModel): metadata: Metadata | None = None custom: dict[str, Any] | None = None reasoning: Reasoning | None = None + resource: Resource | None = None class MediaPart(BaseModel): @@ -615,6 +630,7 @@ class MediaPart(BaseModel): metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None + resource: Resource | None = None class ReasoningPart(BaseModel): @@ -629,6 +645,22 @@ class ReasoningPart(BaseModel): metadata: Metadata | None = None custom: Custom | None = None reasoning: str + resource: Resource | None = None + + +class ResourcePart(BaseModel): + """Model for resourcepart data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + text: Text | None = None + media: MediaModel | None = None + tool_request: ToolRequestModel | None = Field(None, alias='toolRequest') + tool_response: ToolResponseModel | None = Field(None, alias='toolResponse') + data: Data | None = None + metadata: Metadata | None = None + custom: Custom | None = None + reasoning: Reasoning | None = None + resource: Resource1 class TextPart(BaseModel): @@ -643,6 +675,7 @@ class TextPart(BaseModel): metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None + resource: Resource | None = None class ToolRequestPart(BaseModel): @@ -657,6 +690,7 @@ class ToolRequestPart(BaseModel): metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None + resource: Resource | None = None class ToolResponsePart(BaseModel): @@ -671,6 +705,7 @@ class ToolResponsePart(BaseModel): metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None + resource: Resource | None = None class EmbedResponse(BaseModel): @@ -719,11 +754,15 @@ class Resume(BaseModel): class Part( - RootModel[TextPart | MediaPart | ToolRequestPart | ToolResponsePart | DataPart | CustomPart | ReasoningPart] + RootModel[ + TextPart | MediaPart | ToolRequestPart | ToolResponsePart | DataPart | CustomPart | ReasoningPart | ResourcePart + ] ): """Root model for part.""" - root: TextPart | MediaPart | ToolRequestPart | ToolResponsePart | DataPart | CustomPart | ReasoningPart + root: ( + TextPart | MediaPart | ToolRequestPart | ToolResponsePart | DataPart | CustomPart | ReasoningPart | ResourcePart + ) class Link(BaseModel): diff --git a/py/plugins/compat-oai/src/genkit/plugins/compat_oai/models/model_info.py b/py/plugins/compat-oai/src/genkit/plugins/compat_oai/models/model_info.py index 80253b9ab3..374deaf41a 100644 --- a/py/plugins/compat-oai/src/genkit/plugins/compat_oai/models/model_info.py +++ b/py/plugins/compat-oai/src/genkit/plugins/compat_oai/models/model_info.py @@ -183,9 +183,7 @@ def get_default_model_info(name: str) -> ModelInfo: supports=DEFAULT_SUPPORTS, ) + def get_default_openai_model_info(name: str) -> ModelInfo: """Gets the default model info given a name.""" - return ModelInfo( - label=f"OpenAI - {name}", - supports={'multiturn': True} - ) + return ModelInfo(label=f'OpenAI - {name}', supports={'multiturn': True}) diff --git a/py/plugins/compat-oai/src/genkit/plugins/compat_oai/openai_plugin.py b/py/plugins/compat-oai/src/genkit/plugins/compat_oai/openai_plugin.py index 6016ddef43..d8096d0634 100644 --- a/py/plugins/compat-oai/src/genkit/plugins/compat_oai/openai_plugin.py +++ b/py/plugins/compat-oai/src/genkit/plugins/compat_oai/openai_plugin.py @@ -50,13 +50,11 @@ def open_ai_name(name: str) -> str: """ return f'openai/{name}' + def default_openai_metadata(name: str) -> dict[str, Any]: return { - 'model': { - 'label': f"OpenAI - {name}", - 'supports': {'multiturn': True} - }, - } + 'model': {'label': f'OpenAI - {name}', 'supports': {'multiturn': True}}, + } class OpenAI(Plugin): @@ -131,7 +129,6 @@ def resolve_action( # noqa: B027 kind: ActionKind, name: str, ) -> None: - if kind is not ActionKind.MODEL: return None diff --git a/py/plugins/compat-oai/tests/test_plugin.py b/py/plugins/compat-oai/tests/test_plugin.py index 68f07bc784..e6311a0e63 100644 --- a/py/plugins/compat-oai/tests/test_plugin.py +++ b/py/plugins/compat-oai/tests/test_plugin.py @@ -44,9 +44,7 @@ def test_openai_plugin_initialize() -> None: @pytest.mark.parametrize( 'kind, name', - [ - (ActionKind.MODEL, 'gpt-3.5-turbo') - ], + [(ActionKind.MODEL, 'gpt-3.5-turbo')], ) def test_openai_plugin_resolve_action(kind, name): """Unit Tests for resolve action method.""" @@ -72,7 +70,7 @@ def test_openai_plugin_resolve_action(kind, name): ], 'system_role': True, 'tools': True, - } + }, }, }, ) @@ -108,9 +106,7 @@ def test_openai_plugin_list_actions() -> None: @pytest.mark.parametrize( 'kind, name', - [ - (ActionKind.MODEL, "model_doesnt_exist") - ], + [(ActionKind.MODEL, 'model_doesnt_exist')], ) def test_openai_plugin_resolve_action_not_found(kind, name): """Unit Tests for resolve action method."""