From d217e5465ccadd51c0378146859d1149d3d348e9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 7 Aug 2026 15:33:03 +0000 Subject: [PATCH] Add --json-mode flag to vlmrun gw chat Introduce --json-mode as a shorthand for response_format json_object on the gateway chat command. The flag is mutually exclusive with --response-format. Bump SDK version to 0.7.3. Co-authored-by: Sudeep Pillai --- tests/test_gateway.py | 35 +++++++++++++++++++++++++++++++++++ vlmrun/cli/_cli/gateway.py | 23 +++++++++++++++++++++-- vlmrun/version.py | 2 +- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/tests/test_gateway.py b/tests/test_gateway.py index cf82f3c..811ba21 100644 --- a/tests/test_gateway.py +++ b/tests/test_gateway.py @@ -1060,6 +1060,41 @@ def test_chat_response_format_sent_as_top_level_kwarg( assert call["response_format"] == {"type": "json_object"} assert "response_format" not in call.get("extra_body", {}) + def test_chat_json_mode_sent_as_top_level_kwarg( + self, runner, patched_cli, tmp_path + ): + f = tmp_path / "img.png" + f.write_bytes(b"fakepng") + result = runner.invoke( + app, + ["gw", "chat", str(f), "-m", "pp-ocrv6", "--json-mode", "--no-stream"], + ) + assert result.exit_code == 0, result.stdout + call = patched_cli["client"].gateway.completions.calls[-1] + assert call["response_format"] == {"type": "json_object"} + assert "response_format" not in call.get("extra_body", {}) + + def test_chat_json_mode_and_response_format_mutually_exclusive( + self, runner, patched_cli, tmp_path + ): + f = tmp_path / "img.png" + f.write_bytes(b"fakepng") + result = runner.invoke( + app, + [ + "gw", + "chat", + str(f), + "-m", + "pp-ocrv6", + "--json-mode", + "--response-format", + "json_object", + ], + ) + assert result.exit_code == 1 + assert "mutually exclusive" in result.stdout.lower() + def test_chat_response_format_invalid(self, runner, patched_cli, tmp_path): f = tmp_path / "img.png" f.write_bytes(b"fakepng") diff --git a/vlmrun/cli/_cli/gateway.py b/vlmrun/cli/_cli/gateway.py index bf0ba50..dacca9e 100644 --- a/vlmrun/cli/_cli/gateway.py +++ b/vlmrun/cli/_cli/gateway.py @@ -70,6 +70,7 @@ vlmrun gw chat img.jpg -m paddleocr/pp-ocrv6 --method detect vlmrun gw chat img.jpg -m paddleocr/pp-ocrv6 --method ocr \\ --method-params '{"lang": "en", "score_threshold": 0.5}' + vlmrun gw chat img.jpg -m paddleocr/pp-ocrv6 --json-mode \b NOTES: @@ -621,6 +622,14 @@ def chat( "--method-params", help='JSON object of method arguments, e.g. \'{"lang": "en"}\'.', ), + json_mode: bool = typer.Option( + False, + "--json-mode", + help=( + "Enable JSON mode (response_format json_object). Mutually exclusive " + "with --response-format." + ), + ), response_format: Optional[str] = typer.Option( None, "--response-format", @@ -628,7 +637,8 @@ def chat( "Ask the MODEL to constrain its output: 'text', 'json_object' (JSON " 'mode), or a JSON object like \'{"type":"json_schema",...}\'. ' "Sent to the gateway as `response_format`; not yet honored server-side. " - "(Distinct from --json, which formats the CLI's own output.)" + "(Distinct from --json, which formats the CLI's own output. Use " + "--json-mode as a shorthand for json_object.)" ), ), extra: Optional[List[str]] = typer.Option( @@ -676,7 +686,16 @@ def chat( raise typer.Exit(1) extra_body["method_params"] = parsed_params - if response_format: + if json_mode and response_format: + console.print( + "[red]Error:[/] --json-mode and --response-format are mutually " + "exclusive. Use one or the other." + ) + raise typer.Exit(1) + + if json_mode: + create_kwargs["response_format"] = {"type": "json_object"} + elif response_format: # A standard OpenAI create() field, so it rides as a top-level kwarg. create_kwargs["response_format"] = _parse_response_format(response_format) diff --git a/vlmrun/version.py b/vlmrun/version.py index bc8c296..4910b9e 100644 --- a/vlmrun/version.py +++ b/vlmrun/version.py @@ -1 +1 @@ -__version__ = "0.7.2" +__version__ = "0.7.3"