From 220e055591146242f0e179aa2fe77bdd2e9f9a9b Mon Sep 17 00:00:00 2001 From: Michael Doyle Date: Tue, 24 Feb 2026 17:17:41 -0500 Subject: [PATCH] feat(py): minify JSON output and update configuration signatures --- py/packages/genkit/src/genkit/ai/_aio.py | 14 ++++++------ py/packages/genkit/src/genkit/ai/_registry.py | 10 ++++----- .../genkit/src/genkit/blocks/prompt.py | 18 +++++++-------- py/packages/genkit/src/genkit/codec.py | 3 ++- py/packages/genkit/src/genkit/model_types.py | 4 ++-- .../genkit/tests/genkit/blocks/prompt_test.py | 10 ++++----- py/packages/genkit/tests/genkit/codec_test.py | 6 ++--- .../genkit/tests/genkit/core/action_test.py | 4 ++-- .../genkit/tests/genkit/veneer/veneer_test.py | 22 +++++++++---------- py/plugins/flask/tests/flask_test.py | 8 +++---- 10 files changed, 50 insertions(+), 49 deletions(-) diff --git a/py/packages/genkit/src/genkit/ai/_aio.py b/py/packages/genkit/src/genkit/ai/_aio.py index 7feaf06738..fb8e6ee65a 100644 --- a/py/packages/genkit/src/genkit/ai/_aio.py +++ b/py/packages/genkit/src/genkit/ai/_aio.py @@ -153,7 +153,7 @@ async def generate( return_tool_requests: bool | None = None, tool_choice: ToolChoice | None = None, tool_responses: list[Part] | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, max_turns: int | None = None, on_chunk: ModelStreamingCallback | None = None, context: dict[str, object] | None = None, @@ -178,7 +178,7 @@ async def generate( return_tool_requests: bool | None = None, tool_choice: ToolChoice | None = None, tool_responses: list[Part] | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, max_turns: int | None = None, on_chunk: ModelStreamingCallback | None = None, context: dict[str, object] | None = None, @@ -201,7 +201,7 @@ async def generate( return_tool_requests: bool | None = None, tool_choice: ToolChoice | None = None, tool_responses: list[Part] | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, max_turns: int | None = None, on_chunk: ModelStreamingCallback | None = None, context: dict[str, object] | None = None, @@ -358,7 +358,7 @@ def generate_stream( tools: list[str] | None = None, return_tool_requests: bool | None = None, tool_choice: ToolChoice | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, max_turns: int | None = None, context: dict[str, object] | None = None, output_format: str | None = None, @@ -385,7 +385,7 @@ def generate_stream( tools: list[str] | None = None, return_tool_requests: bool | None = None, tool_choice: ToolChoice | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, max_turns: int | None = None, context: dict[str, object] | None = None, output_format: str | None = None, @@ -410,7 +410,7 @@ def generate_stream( tools: list[str] | None = None, return_tool_requests: bool | None = None, tool_choice: ToolChoice | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, max_turns: int | None = None, context: dict[str, object] | None = None, output_format: str | None = None, @@ -1003,7 +1003,7 @@ async def generate_operation( tools: list[str] | None = None, return_tool_requests: bool | None = None, tool_choice: ToolChoice | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, max_turns: int | None = None, context: dict[str, object] | None = None, output_format: str | None = None, diff --git a/py/packages/genkit/src/genkit/ai/_registry.py b/py/packages/genkit/src/genkit/ai/_registry.py index 12f6f57d1a..d5cc80bc54 100644 --- a/py/packages/genkit/src/genkit/ai/_registry.py +++ b/py/packages/genkit/src/genkit/ai/_registry.py @@ -1186,7 +1186,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, object] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -1216,7 +1216,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, object] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -1246,7 +1246,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, object] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -1276,7 +1276,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, object] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -1303,7 +1303,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, object] | None = None, + config: dict[str, object] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, object] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, diff --git a/py/packages/genkit/src/genkit/blocks/prompt.py b/py/packages/genkit/src/genkit/blocks/prompt.py index 4fd19a3d8e..838580c73c 100644 --- a/py/packages/genkit/src/genkit/blocks/prompt.py +++ b/py/packages/genkit/src/genkit/blocks/prompt.py @@ -394,7 +394,7 @@ def on_chunk(chunk): """ model: str | None - config: GenerationCommonConfig | dict[str, Any] | None + config: dict[str, Any] | GenerationCommonConfig | None messages: list[Message] | None docs: list[DocumentData] | None tools: list[str] | None @@ -554,7 +554,7 @@ class PromptConfig(BaseModel): variant: str | None = None model: str | None = None - config: GenerationCommonConfig | dict[str, Any] | None = None + config: dict[str, Any] | GenerationCommonConfig | None = None description: str | None = None input_schema: type | dict[str, Any] | str | None = None system: str | Part | list[Part] | Callable[..., Any] | None = None @@ -677,7 +677,7 @@ def __init__( registry: Registry, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, Any] | None = None, + config: dict[str, Any] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, Any] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -731,7 +731,7 @@ def __init__( self._registry: Registry = registry self._variant: str | None = variant self._model: str | None = model - self._config: GenerationCommonConfig | dict[str, Any] | None = config + self._config: dict[str, Any] | GenerationCommonConfig | None = config self._description: str | None = description self._input_schema: type | dict[str, Any] | str | None = input_schema self._system: str | Part | list[Part] | Callable[..., Any] | None = system @@ -1185,7 +1185,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, Any] | None = None, + config: dict[str, Any] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, Any] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -1216,7 +1216,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, Any] | None = None, + config: dict[str, Any] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, Any] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -1247,7 +1247,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, Any] | None = None, + config: dict[str, Any] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, Any] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -1278,7 +1278,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, Any] | None = None, + config: dict[str, Any] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, Any] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, @@ -1307,7 +1307,7 @@ def define_prompt( name: str | None = None, variant: str | None = None, model: str | None = None, - config: GenerationCommonConfig | dict[str, Any] | None = None, + config: dict[str, Any] | GenerationCommonConfig | None = None, description: str | None = None, input_schema: type | dict[str, Any] | str | None = None, system: str | Part | list[Part] | Callable[..., Any] | None = None, diff --git a/py/packages/genkit/src/genkit/codec.py b/py/packages/genkit/src/genkit/codec.py index 9bbc8063d3..70d69849a8 100644 --- a/py/packages/genkit/src/genkit/codec.py +++ b/py/packages/genkit/src/genkit/codec.py @@ -150,4 +150,5 @@ def dump_json( if isinstance(obj, BaseModel): return obj.model_dump_json(by_alias=True, exclude_none=True, indent=indent, fallback=fallback) else: - return json.dumps(obj, indent=indent, default=fallback or default_serializer) + separators = (',', ':') if indent is None else None + return json.dumps(obj, indent=indent, default=fallback or default_serializer, separators=separators) diff --git a/py/packages/genkit/src/genkit/model_types.py b/py/packages/genkit/src/genkit/model_types.py index 874ba12479..2bf9cad3b3 100644 --- a/py/packages/genkit/src/genkit/model_types.py +++ b/py/packages/genkit/src/genkit/model_types.py @@ -38,7 +38,7 @@ class GenerationCommonConfig(CoreGenerationCommonConfig): ) -def get_request_api_key(config: GenerationCommonConfig | Mapping[str, object] | object | None) -> str | None: +def get_request_api_key(config: Mapping[str, object] | GenerationCommonConfig | object | None) -> str | None: """Extract a request-scoped API key from config. Supports both typed config objects and dict payloads with either snake_case @@ -66,7 +66,7 @@ def get_request_api_key(config: GenerationCommonConfig | Mapping[str, object] | def get_effective_api_key( - config: GenerationCommonConfig | Mapping[str, object] | object | None, + config: Mapping[str, object] | GenerationCommonConfig | object | None, plugin_api_key: str | None, ) -> str | None: """Resolve effective API key using request-over-plugin precedence.""" diff --git a/py/packages/genkit/tests/genkit/blocks/prompt_test.py b/py/packages/genkit/tests/genkit/blocks/prompt_test.py index 25434bed2a..01b5e54538 100644 --- a/py/packages/genkit/tests/genkit/blocks/prompt_test.py +++ b/py/packages/genkit/tests/genkit/blocks/prompt_test.py @@ -64,7 +64,7 @@ async def test_simple_prompt() -> None: """Test simple prompt rendering.""" ai, *_ = setup_test() - want_txt = '[ECHO] user: "hi" {"temperature":11.0}' + want_txt = '[ECHO] user: "hi" {"temperature":11}' my_prompt = ai.define_prompt(prompt='hi', config={'temperature': 11}) @@ -87,7 +87,7 @@ async def test_simple_prompt_with_override_config() -> None: ai, *_ = setup_test() # Config is MERGED: prompt config (banana: true) + opts config (temperature: 12) - want_txt = '[ECHO] user: "hi" {"banana": true, "temperature": 12}' + want_txt = '[ECHO] user: "hi" {"banana":true,"temperature":12}' my_prompt = ai.define_prompt(prompt='hi', config={'banana': True}) @@ -236,7 +236,7 @@ async def docs_resolver(input: dict[str, Any], context: object) -> list[Document GenerationCommonConfig.model_validate({'temperature': 11}), {}, # Config is MERGED: prompt config (banana: ripe) + opts config (temperature: 11) - """[ECHO] system: "hello foo (bar)" {"banana": "ripe", "temperature": 11.0}""", + """[ECHO] system: "hello foo (bar)" {"banana":"ripe","temperature":11.0}""", ), ( 'renders user prompt', @@ -256,7 +256,7 @@ async def docs_resolver(input: dict[str, Any], context: object) -> list[Document GenerationCommonConfig.model_validate({'temperature': 11}), {}, # Config is MERGED: prompt config (banana: ripe) + opts config (temperature: 11) - """[ECHO] user: "hello foo (bar_system)" {"banana": "ripe", "temperature": 11.0}""", + """[ECHO] user: "hello foo (bar_system)" {"banana":"ripe","temperature":11.0}""", ), ( 'renders user prompt with context', @@ -276,7 +276,7 @@ async def docs_resolver(input: dict[str, Any], context: object) -> list[Document GenerationCommonConfig.model_validate({'temperature': 11}), {'auth': {'email': 'a@b.c'}}, # Config is MERGED: prompt config (banana: ripe) + opts config (temperature: 11) - """[ECHO] user: "hello foo (bar, a@b.c)" {"banana": "ripe", "temperature": 11.0}""", + """[ECHO] user: "hello foo (bar, a@b.c)" {"banana":"ripe","temperature":11.0}""", ), ] diff --git a/py/packages/genkit/tests/genkit/codec_test.py b/py/packages/genkit/tests/genkit/codec_test.py index f4a407fd93..97e61f870e 100644 --- a/py/packages/genkit/tests/genkit/codec_test.py +++ b/py/packages/genkit/tests/genkit/codec_test.py @@ -24,13 +24,13 @@ def test_dump_json_basic() -> None: """Test basic JSON serialization.""" # Test dictionary - assert dump_json({'a': 1, 'b': 'test'}) == '{"a": 1, "b": "test"}' + assert dump_json({'a': 1, 'b': 'test'}) == '{"a":1,"b":"test"}' # Test list - assert dump_json([1, 2, 3]) == '[1, 2, 3]' + assert dump_json([1, 2, 3]) == '[1,2,3]' # Test nested structures - assert dump_json({'a': [1, 2], 'b': {'c': 3}}) == '{"a": [1, 2], "b": {"c": 3}}' + assert dump_json({'a': [1, 2], 'b': {'c': 3}}) == '{"a":[1,2],"b":{"c":3}}' def test_dump_json_special_types() -> None: diff --git a/py/packages/genkit/tests/genkit/core/action_test.py b/py/packages/genkit/tests/genkit/core/action_test.py index 6476a69593..406857be7c 100644 --- a/py/packages/genkit/tests/genkit/core/action_test.py +++ b/py/packages/genkit/tests/genkit/core/action_test.py @@ -275,8 +275,8 @@ async def baz() -> str: first = baz_action.arun(context={'foo': 'bar'}) second = baz_action.arun(context={'bar': 'baz'}) - assert (await second).response == '{"bar": "baz"}' - assert (await first).response == '{"foo": "bar"}' + assert (await second).response == '{"bar":"baz"}' + assert (await first).response == '{"foo":"bar"}' @pytest.mark.asyncio diff --git a/py/packages/genkit/tests/genkit/veneer/veneer_test.py b/py/packages/genkit/tests/genkit/veneer/veneer_test.py index 8d7ee00e3e..ef06e03502 100644 --- a/py/packages/genkit/tests/genkit/veneer/veneer_test.py +++ b/py/packages/genkit/tests/genkit/veneer/veneer_test.py @@ -73,7 +73,7 @@ async def test_generate_uses_default_model(setup_test: SetupFixture) -> None: """Test that the generate function uses the default model.""" ai, *_ = setup_test - want_txt = '[ECHO] user: "hi" {"temperature":11.0}' + want_txt = '[ECHO] user: "hi" {"temperature":11}' response = await ai.generate(prompt='hi', config={'temperature': 11}) @@ -123,11 +123,11 @@ async def test_generate_with_explicit_model(setup_test: SetupFixture) -> None: response = await ai.generate(model='echoModel', prompt='hi', config={'temperature': 11}) - assert response.text == '[ECHO] user: "hi" {"temperature":11.0}' + assert response.text == '[ECHO] user: "hi" {"temperature":11}' _, response = ai.generate_stream(model='echoModel', prompt='hi', config={'temperature': 11}) - assert (await response).text == '[ECHO] user: "hi" {"temperature":11.0}' + assert (await response).text == '[ECHO] user: "hi" {"temperature":11}' @pytest.mark.asyncio @@ -137,7 +137,7 @@ async def test_generate_with_str_prompt(setup_test: SetupFixture) -> None: response = await ai.generate(prompt='hi', config={'temperature': 11}) - assert response.text == '[ECHO] user: "hi" {"temperature":11.0}' + assert response.text == '[ECHO] user: "hi" {"temperature":11}' @pytest.mark.asyncio @@ -145,7 +145,7 @@ async def test_generate_with_part_prompt(setup_test: SetupFixture) -> None: """Test that the generate function with a part prompt works.""" ai, *_ = setup_test - want_txt = '[ECHO] user: "hi" {"temperature":11.0}' + want_txt = '[ECHO] user: "hi" {"temperature":11}' response = await ai.generate(prompt=Part(root=TextPart(text='hi')), config={'temperature': 11}) @@ -161,7 +161,7 @@ async def test_generate_with_part_list_prompt(setup_test: SetupFixture) -> None: """Test that the generate function with a list of parts prompt works.""" ai, *_ = setup_test - want_txt = '[ECHO] user: "hello","world" {"temperature":11.0}' + want_txt = '[ECHO] user: "hello","world" {"temperature":11}' response = await ai.generate( prompt=[Part(root=TextPart(text='hello')), Part(root=TextPart(text='world'))], @@ -183,7 +183,7 @@ async def test_generate_with_str_system(setup_test: SetupFixture) -> None: """Test that the generate function with a string system works.""" ai, *_ = setup_test - want_txt = '[ECHO] system: "talk like pirate" user: "hi" {"temperature":11.0}' + want_txt = '[ECHO] system: "talk like pirate" user: "hi" {"temperature":11}' response = await ai.generate(system='talk like pirate', prompt='hi', config={'temperature': 11}) @@ -199,7 +199,7 @@ async def test_generate_with_part_system(setup_test: SetupFixture) -> None: """Test that the generate function with a part system works.""" ai, *_ = setup_test - want_txt = '[ECHO] system: "talk like pirate" user: "hi" {"temperature":11.0}' + want_txt = '[ECHO] system: "talk like pirate" user: "hi" {"temperature":11}' response = await ai.generate( system=Part(root=TextPart(text='talk like pirate')), @@ -223,7 +223,7 @@ async def test_generate_with_part_list_system(setup_test: SetupFixture) -> None: """Test that the generate function with a list of parts system works.""" ai, *_ = setup_test - want_txt = '[ECHO] system: "talk","like pirate" user: "hi" {"temperature":11.0}' + want_txt = '[ECHO] system: "talk","like pirate" user: "hi" {"temperature":11}' response = await ai.generate( system=[Part(root=TextPart(text='talk')), Part(root=TextPart(text='like pirate'))], @@ -257,7 +257,7 @@ async def test_generate_with_messages(setup_test: SetupFixture) -> None: config={'temperature': 11}, ) - assert response.text == '[ECHO] user: "hi" {"temperature":11.0}' + assert response.text == '[ECHO] user: "hi" {"temperature":11}' _, response = ai.generate_stream( messages=[ @@ -269,7 +269,7 @@ async def test_generate_with_messages(setup_test: SetupFixture) -> None: config={'temperature': 11}, ) - assert (await response).text == '[ECHO] user: "hi" {"temperature":11.0}' + assert (await response).text == '[ECHO] user: "hi" {"temperature":11}' @pytest.mark.asyncio diff --git a/py/plugins/flask/tests/flask_test.py b/py/plugins/flask/tests/flask_test.py index 5bf38d53f0..99f0fd841b 100644 --- a/py/plugins/flask/tests/flask_test.py +++ b/py/plugins/flask/tests/flask_test.py @@ -81,8 +81,8 @@ def test_streaming() -> None: chunks.append(chunk) assert chunks == [ - b'data: {"message": 1}\n\n', - b'data: {"message": {"username": "Pavel"}}\n\n', - b'data: {"message": {"foo": "bar"}}\n\n', - b'data: {"result": {"bar": "baz"}}\n\n', + b'data: {"message":1}\n\n', + b'data: {"message":{"username":"Pavel"}}\n\n', + b'data: {"message":{"foo":"bar"}}\n\n', + b'data: {"result":{"bar":"baz"}}\n\n', ]