From 2cd5f7069c73b0930bd5e9fad941064a88fc3ed9 Mon Sep 17 00:00:00 2001 From: Denis Pajaziti Date: Wed, 12 Nov 2025 12:48:20 +0100 Subject: [PATCH 1/4] Enhance tool transformation logic in RequestAdapter to handle non-list inputs and invalid tool structures. Added logging for skipped transformations to improve debugging. --- app/azure/request_adapter.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/app/azure/request_adapter.py b/app/azure/request_adapter.py index 697db1e..30ace59 100644 --- a/app/azure/request_adapter.py +++ b/app/azure/request_adapter.py @@ -92,8 +92,31 @@ class RequestAdapter: def _transform_tools_for_responses(self, tools: Any) -> Any: out: List[Dict[str, Any]] = [] - for tool in tools: + if not isinstance(tools, list): + current_app.logger.debug( + "Skipping tool transformation because tools payload is not a list: %r", + tools, + ) + return out + + for idx, tool in enumerate(tools): + if not isinstance(tool, dict): + current_app.logger.warning( + "Skipping tool at index %s because it is not a dict (got %s).", + idx, + type(tool).__name__, + ) + continue + function = tool.get("function") + if not isinstance(function, dict): + current_app.logger.warning( + "Skipping tool at index %s because function payload is missing or invalid: %r", + idx, + function, + ) + continue + transformed: Dict[str, Any] = { "type": "function", "name": function.get("name"), From 28499689c019a0776c28d946ef9a7415bba82cde Mon Sep 17 00:00:00 2001 From: Denis Pajaziti Date: Wed, 12 Nov 2025 12:50:47 +0100 Subject: [PATCH 2/4] Remove development service from docker-compose.yml and update production service port from 8080 to 9090. --- docker-compose.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 62be134..73b5d8e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,17 +6,6 @@ x-default-volumes: &default_volumes - ./:/app services: - flask-dev: - build: - context: . - target: development - args: - <<: *build_args - image: "app-development" - ports: - - "8080:5000" - <<: *default_volumes - flask-prod: build: context: . @@ -25,7 +14,7 @@ services: <<: *build_args image: "app-production" ports: - - "8080:5000" + - "9090:5000" environment: FLASK_ENV: production FLASK_DEBUG: 0 From c32056709f7269eee12e612a2f1b856c1d34bc9a Mon Sep 17 00:00:00 2001 From: Gabriel Gavilan Date: Fri, 21 Nov 2025 13:54:06 +0100 Subject: [PATCH 3/4] Partially revert 7b6c640f91bae6f451d38779e4e7d8878b0460f8 --- app/azure/request_adapter.py | 18 +----------------- docker-compose.yml | 13 ++++++++++++- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/app/azure/request_adapter.py b/app/azure/request_adapter.py index 30ace59..ac2f849 100644 --- a/app/azure/request_adapter.py +++ b/app/azure/request_adapter.py @@ -99,24 +99,8 @@ class RequestAdapter: ) return out - for idx, tool in enumerate(tools): - if not isinstance(tool, dict): - current_app.logger.warning( - "Skipping tool at index %s because it is not a dict (got %s).", - idx, - type(tool).__name__, - ) - continue - + for tool in tools: function = tool.get("function") - if not isinstance(function, dict): - current_app.logger.warning( - "Skipping tool at index %s because function payload is missing or invalid: %r", - idx, - function, - ) - continue - transformed: Dict[str, Any] = { "type": "function", "name": function.get("name"), diff --git a/docker-compose.yml b/docker-compose.yml index 73b5d8e..62be134 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,6 +6,17 @@ x-default-volumes: &default_volumes - ./:/app services: + flask-dev: + build: + context: . + target: development + args: + <<: *build_args + image: "app-development" + ports: + - "8080:5000" + <<: *default_volumes + flask-prod: build: context: . @@ -14,7 +25,7 @@ services: <<: *build_args image: "app-production" ports: - - "9090:5000" + - "8080:5000" environment: FLASK_ENV: production FLASK_DEBUG: 0 From b7947fba0b76ce0896c350cd33e0a3e81863bb5f Mon Sep 17 00:00:00 2001 From: Gabriel Gavilan Date: Fri, 21 Nov 2025 13:59:55 +0100 Subject: [PATCH 4/4] Add test for empty tools scenario --- app/common/logging.py | 2 +- .../empty_tools/downstream_request.json | 22 +++++++++++ .../empty_tools/downstream_response.sse | 10 +++++ .../empty_tools/upstream_request.json | 37 +++++++++++++++++++ .../empty_tools/upstream_response.sse | 33 +++++++++++++++++ tests/test_replays.py | 6 +++ 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 tests/recordings/empty_tools/downstream_request.json create mode 100644 tests/recordings/empty_tools/downstream_response.sse create mode 100644 tests/recordings/empty_tools/upstream_request.json create mode 100644 tests/recordings/empty_tools/upstream_response.sse diff --git a/app/common/logging.py b/app/common/logging.py index dbb6aaf..021b203 100644 --- a/app/common/logging.py +++ b/app/common/logging.py @@ -205,7 +205,7 @@ def log_request(req: Request) -> str: ) messages = json_payload.get("messages", []) - tools = json_payload.get("tools", []) + tools = json_payload.get("tools", []) or [] # Render tools section once (no duplicate panels) table = Table( diff --git a/tests/recordings/empty_tools/downstream_request.json b/tests/recordings/empty_tools/downstream_request.json new file mode 100644 index 0000000..b5a92c1 --- /dev/null +++ b/tests/recordings/empty_tools/downstream_request.json @@ -0,0 +1,22 @@ +{ + "model": "gpt-minimal", + "temperature": 0, + "user": "REDACTED", + "messages": [ + { + "role": "system", + "content": "REDACTED" + }, + { + "role": "user", + "content": "REDACTED" + }, + { + "role": "user", + "content": "REDACTED" + } + ], + "tools": null, + "tool_choice": "auto", + "stream": true +} \ No newline at end of file diff --git a/tests/recordings/empty_tools/downstream_response.sse b/tests/recordings/empty_tools/downstream_response.sse new file mode 100644 index 0000000..e459820 --- /dev/null +++ b/tests/recordings/empty_tools/downstream_response.sse @@ -0,0 +1,10 @@ +data: {"id":"chatcmpl-ERO7qkefORSgjuOmbThzZoG8","object":"chat.completion.chunk","created":1758093803,"model":"gpt-minimal","choices":[{"index":0,"delta":{"role":"assistant","content":"\n\n"},"finish_reason":null}]} + +data: {"id":"chatcmpl-ERO7qkefORSgjuOmbThzZoG8","object":"chat.completion.chunk","created":1758093804,"model":"gpt-minimal","choices":[{"index":0,"delta":{"role":"assistant","content":"\n\n"},"finish_reason":null}]} + +data: {"id":"chatcmpl-ERO7qkefORSgjuOmbThzZoG8","object":"chat.completion.chunk","created":1758093804,"model":"gpt-minimal","choices":[{"index":0,"delta":{"role":"assistant","content":"pong"},"finish_reason":null}]} + +data: {"id":"chatcmpl-ERO7qkefORSgjuOmbThzZoG8","object":"chat.completion.chunk","created":1758093806,"model":"gpt-minimal","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]} + +data: [DONE] + diff --git a/tests/recordings/empty_tools/upstream_request.json b/tests/recordings/empty_tools/upstream_request.json new file mode 100644 index 0000000..2dea819 --- /dev/null +++ b/tests/recordings/empty_tools/upstream_request.json @@ -0,0 +1,37 @@ +{ + "instructions": "REDACTED", + "input": [ + { + "role": "user", + "content": [ + { + "type": "input_text", + "text": "REDACTED" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "input_text", + "text": "REDACTED" + } + ] + } + ], + "model": "gpt-5", + "tools": [], + "tool_choice": "auto", + "prompt_cache_key": "REDACTED", + "stream": true, + "reasoning": { + "effort": "minimal", + "summary": "detailed" + }, + "store": false, + "stream_options": { + "include_obfuscation": false + }, + "truncation": "auto" +} \ No newline at end of file diff --git a/tests/recordings/empty_tools/upstream_response.sse b/tests/recordings/empty_tools/upstream_response.sse new file mode 100644 index 0000000..03731da --- /dev/null +++ b/tests/recordings/empty_tools/upstream_response.sse @@ -0,0 +1,33 @@ +event: response.created +data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68ca61ea133c8190a25851b67c2dc1fa000638fabbdbe241","object":"response","created_at":1758093802,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":"REDACTED","max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":"REDACTED","reasoning":{"effort":"minimal","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"explanation":{"type":"string","description":"REDACTED"},"query":{"type":"string","description":"REDACTED"},"target_directories":{"type":"array","items":{"type":"string"},"description":"REDACTED"},"search_only_prs":{"type":"boolean","description":"REDACTED"}},"required":["explanation","query","target_directories"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"command":{"type":"string","description":"REDACTED"},"is_background":{"type":"boolean","description":"REDACTED"},"explanation":{"type":"string","description":"REDACTED"}},"required":["command","is_background"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"pattern":{"type":"string","description":"REDACTED"},"path":{"type":"string","description":"REDACTED"},"glob":{"type":"string","description":"REDACTED"},"output_mode":{"type":"string","description":"REDACTED","enum":["content","files_with_matches","count"]},"-B":{"type":"number","description":"REDACTED"},"-A":{"type":"number","description":"REDACTED"},"-C":{"type":"number","description":"REDACTED"},"-i":{"type":"boolean","description":"REDACTED"},"type":{"type":"string","description":"REDACTED"},"head_limit":{"type":"number","description":"REDACTED"},"multiline":{"type":"boolean","description":"REDACTED"}},"required":["pattern"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"explanation":{"type":"string","description":"REDACTED"}},"required":["target_file"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"paths":{"description":"REDACTED","type":"array","items":{"type":"string"}}},"required":[]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_notebook":{"type":"string","description":"REDACTED"},"cell_idx":{"type":"number","description":"REDACTED"},"is_new_cell":{"type":"boolean","description":"REDACTED"},"cell_language":{"type":"string","description":"REDACTED"},"old_string":{"type":"string","description":"REDACTED"},"new_string":{"type":"string","description":"REDACTED"}},"required":["target_notebook","cell_idx","is_new_cell","cell_language","old_string","new_string"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"merge":{"type":"boolean","description":"REDACTED"},"todos":{"type":"array","description":"REDACTED","items":{"type":"object","properties":{"content":{"type":"string","description":"REDACTED"},"status":{"type":"string","enum":["pending","in_progress","completed","cancelled"],"description":"REDACTED"},"id":{"type":"string","description":"REDACTED"}},"required":["content","status","id"]},"minItems":2}},"required":["merge","todos"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"instructions":{"type":"string","description":"REDACTED"},"code_edit":{"type":"string","description":"REDACTED"}},"required":["target_file","instructions","code_edit"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"offset":{"type":"integer","description":"REDACTED"},"limit":{"type":"integer","description":"REDACTED"}},"required":["target_file"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_directory":{"type":"string","description":"REDACTED"},"ignore_globs":{"type":"array","items":{"type":"string"},"description":"REDACTED"}},"required":["target_directory"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_directory":{"type":"string","description":"REDACTED"},"glob_pattern":{"type":"string","description":"REDACTED"}},"required":["glob_pattern"]},"strict":false}],"top_p":1.0,"truncation":"auto","usage":null,"user":null,"metadata":{}}} + +event: response.in_progress +data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68ca61ea133c8190a25851b67c2dc1fa000638fabbdbe241","object":"response","created_at":1758093802,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":"REDACTED","max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":"REDACTED","reasoning":{"effort":"minimal","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"explanation":{"type":"string","description":"REDACTED"},"query":{"type":"string","description":"REDACTED"},"target_directories":{"type":"array","items":{"type":"string"},"description":"REDACTED"},"search_only_prs":{"type":"boolean","description":"REDACTED"}},"required":["explanation","query","target_directories"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"command":{"type":"string","description":"REDACTED"},"is_background":{"type":"boolean","description":"REDACTED"},"explanation":{"type":"string","description":"REDACTED"}},"required":["command","is_background"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"pattern":{"type":"string","description":"REDACTED"},"path":{"type":"string","description":"REDACTED"},"glob":{"type":"string","description":"REDACTED"},"output_mode":{"type":"string","description":"REDACTED","enum":["content","files_with_matches","count"]},"-B":{"type":"number","description":"REDACTED"},"-A":{"type":"number","description":"REDACTED"},"-C":{"type":"number","description":"REDACTED"},"-i":{"type":"boolean","description":"REDACTED"},"type":{"type":"string","description":"REDACTED"},"head_limit":{"type":"number","description":"REDACTED"},"multiline":{"type":"boolean","description":"REDACTED"}},"required":["pattern"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"explanation":{"type":"string","description":"REDACTED"}},"required":["target_file"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"paths":{"description":"REDACTED","type":"array","items":{"type":"string"}}},"required":[]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_notebook":{"type":"string","description":"REDACTED"},"cell_idx":{"type":"number","description":"REDACTED"},"is_new_cell":{"type":"boolean","description":"REDACTED"},"cell_language":{"type":"string","description":"REDACTED"},"old_string":{"type":"string","description":"REDACTED"},"new_string":{"type":"string","description":"REDACTED"}},"required":["target_notebook","cell_idx","is_new_cell","cell_language","old_string","new_string"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"merge":{"type":"boolean","description":"REDACTED"},"todos":{"type":"array","description":"REDACTED","items":{"type":"object","properties":{"content":{"type":"string","description":"REDACTED"},"status":{"type":"string","enum":["pending","in_progress","completed","cancelled"],"description":"REDACTED"},"id":{"type":"string","description":"REDACTED"}},"required":["content","status","id"]},"minItems":2}},"required":["merge","todos"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"instructions":{"type":"string","description":"REDACTED"},"code_edit":{"type":"string","description":"REDACTED"}},"required":["target_file","instructions","code_edit"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"offset":{"type":"integer","description":"REDACTED"},"limit":{"type":"integer","description":"REDACTED"}},"required":["target_file"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_directory":{"type":"string","description":"REDACTED"},"ignore_globs":{"type":"array","items":{"type":"string"},"description":"REDACTED"}},"required":["target_directory"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_directory":{"type":"string","description":"REDACTED"},"glob_pattern":{"type":"string","description":"REDACTED"}},"required":["glob_pattern"]},"strict":false}],"top_p":1.0,"truncation":"auto","usage":null,"user":null,"metadata":{}}} + +event: response.output_item.added +data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_68ca61eb7cf481909660df840351bf9d000638fabbdbe241","type":"reasoning","summary":[]}} + +event: response.output_item.done +data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_68ca61eb7cf481909660df840351bf9d000638fabbdbe241","type":"reasoning","summary":[]}} + +event: response.output_item.added +data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_68ca61ecbbe881909418900fa3ecd3e7000638fabbdbe241","type":"message","status":"in_progress","content":[],"role":"assistant"}} + +event: response.content_part.added +data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_68ca61ecbbe881909418900fa3ecd3e7000638fabbdbe241","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"text":""}} + +event: response.output_text.delta +data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_68ca61ecbbe881909418900fa3ecd3e7000638fabbdbe241","output_index":1,"content_index":0,"delta":"pong"} + +event: response.output_text.done +data: {"type":"response.output_text.done","sequence_number":7,"item_id":"msg_68ca61ecbbe881909418900fa3ecd3e7000638fabbdbe241","output_index":1,"content_index":0,"text":"REDACTED"} + +event: response.content_part.done +data: {"type":"response.content_part.done","sequence_number":8,"item_id":"msg_68ca61ecbbe881909418900fa3ecd3e7000638fabbdbe241","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"text":"REDACTED"}} + +event: response.output_item.done +data: {"type":"response.output_item.done","sequence_number":9,"output_index":1,"item":{"id":"msg_68ca61ecbbe881909418900fa3ecd3e7000638fabbdbe241","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"text":"REDACTED"}],"role":"assistant"}} + +event: response.completed +data: {"type":"response.completed","sequence_number":10,"response":{"id":"resp_68ca61ea133c8190a25851b67c2dc1fa000638fabbdbe241","object":"response","created_at":1758093802,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":"REDACTED","max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5","output":[{"id":"rs_68ca61eb7cf481909660df840351bf9d000638fabbdbe241","type":"reasoning","summary":[]},{"id":"msg_68ca61ecbbe881909418900fa3ecd3e7000638fabbdbe241","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"text":"REDACTED"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":"REDACTED","reasoning":{"effort":"minimal","summary":"detailed"},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"explanation":{"type":"string","description":"REDACTED"},"query":{"type":"string","description":"REDACTED"},"target_directories":{"type":"array","items":{"type":"string"},"description":"REDACTED"},"search_only_prs":{"type":"boolean","description":"REDACTED"}},"required":["explanation","query","target_directories"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"command":{"type":"string","description":"REDACTED"},"is_background":{"type":"boolean","description":"REDACTED"},"explanation":{"type":"string","description":"REDACTED"}},"required":["command","is_background"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"pattern":{"type":"string","description":"REDACTED"},"path":{"type":"string","description":"REDACTED"},"glob":{"type":"string","description":"REDACTED"},"output_mode":{"type":"string","description":"REDACTED","enum":["content","files_with_matches","count"]},"-B":{"type":"number","description":"REDACTED"},"-A":{"type":"number","description":"REDACTED"},"-C":{"type":"number","description":"REDACTED"},"-i":{"type":"boolean","description":"REDACTED"},"type":{"type":"string","description":"REDACTED"},"head_limit":{"type":"number","description":"REDACTED"},"multiline":{"type":"boolean","description":"REDACTED"}},"required":["pattern"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"explanation":{"type":"string","description":"REDACTED"}},"required":["target_file"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"paths":{"description":"REDACTED","type":"array","items":{"type":"string"}}},"required":[]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_notebook":{"type":"string","description":"REDACTED"},"cell_idx":{"type":"number","description":"REDACTED"},"is_new_cell":{"type":"boolean","description":"REDACTED"},"cell_language":{"type":"string","description":"REDACTED"},"old_string":{"type":"string","description":"REDACTED"},"new_string":{"type":"string","description":"REDACTED"}},"required":["target_notebook","cell_idx","is_new_cell","cell_language","old_string","new_string"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"merge":{"type":"boolean","description":"REDACTED"},"todos":{"type":"array","description":"REDACTED","items":{"type":"object","properties":{"content":{"type":"string","description":"REDACTED"},"status":{"type":"string","enum":["pending","in_progress","completed","cancelled"],"description":"REDACTED"},"id":{"type":"string","description":"REDACTED"}},"required":["content","status","id"]},"minItems":2}},"required":["merge","todos"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"instructions":{"type":"string","description":"REDACTED"},"code_edit":{"type":"string","description":"REDACTED"}},"required":["target_file","instructions","code_edit"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_file":{"type":"string","description":"REDACTED"},"offset":{"type":"integer","description":"REDACTED"},"limit":{"type":"integer","description":"REDACTED"}},"required":["target_file"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_directory":{"type":"string","description":"REDACTED"},"ignore_globs":{"type":"array","items":{"type":"string"},"description":"REDACTED"}},"required":["target_directory"]},"strict":false},{"type":"function","description":"REDACTED","name":"REDACTED","parameters":{"type":"object","properties":{"target_directory":{"type":"string","description":"REDACTED"},"glob_pattern":{"type":"string","description":"REDACTED"}},"required":["glob_pattern"]},"strict":false}],"top_p":1.0,"truncation":"auto","usage":{"input_tokens":8510,"input_tokens_details":{"cached_tokens":0},"output_tokens":7,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":8517},"user":null,"metadata":{}}} + diff --git a/tests/test_replays.py b/tests/test_replays.py index a26ee7f..92aa5fd 100644 --- a/tests/test_replays.py +++ b/tests/test_replays.py @@ -50,3 +50,9 @@ class TestReplyVerbosityLevelHigh(ReplyBase): app.config["AZURE_VERBOSITY_LEVEL"] = "high" recording = "verbosity_level" + + +class TestReplyWithEmptyTools(ReplyBase): + """Reply with the 'tools' key not present in the downstream request.""" + + recording = "empty_tools"