From 707e8aec2bb23dd987251d1154d577d0d03c5e07 Mon Sep 17 00:00:00 2001 From: Alishahryar1 Date: Sat, 31 Jan 2026 15:57:37 -0800 Subject: [PATCH] fixed subagents --- providers/nvidia_nim.py | 17 ++++++++ tests/test_subagent_interception.py | 61 +++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/test_subagent_interception.py diff --git a/providers/nvidia_nim.py b/providers/nvidia_nim.py index aec1090b..4e65148a 100644 --- a/providers/nvidia_nim.py +++ b/providers/nvidia_nim.py @@ -278,7 +278,24 @@ class NvidiaNimProvider( if not sse.blocks.tool_started.get(tc_index): tool_id = tc.get("id") or f"tool_{uuid.uuid4()}" name = sse.blocks.tool_names.get(tc_index, "tool_call") or "tool_call" + yield sse.start_tool_block(tc_index, tool_id, name) sse.blocks.tool_started[tc_index] = True + # INTERCEPTION: If this is a Task tool, force background=False + current_name = sse.blocks.tool_names.get(tc_index, "") + if current_name == "Task": + try: + args_json = json.loads(args) + if args_json.get("run_in_background") is not False: + logger.info( + f"NIM_INTERCEPT: Forcing run_in_background=False for Task {tc.get('id', 'unknown')}" + ) + args_json["run_in_background"] = False + args = json.dumps(args_json) + except Exception as e: + logger.warning( + f"NIM_INTERCEPT: Failed to parse/modify Task args: {e}" + ) + yield sse.emit_tool_delta(tc_index, args) diff --git a/tests/test_subagent_interception.py b/tests/test_subagent_interception.py new file mode 100644 index 00000000..58b2af1e --- /dev/null +++ b/tests/test_subagent_interception.py @@ -0,0 +1,61 @@ +import json +import uuid +import pytest +from unittest.mock import MagicMock, AsyncMock +from providers.nvidia_nim import NvidiaNimProvider +from providers.base import ProviderConfig + + +@pytest.mark.asyncio +async def test_task_tool_interception(): + # Setup provider + config = ProviderConfig(api_key="test") + provider = NvidiaNimProvider(config) + + # Mock request and sse builder + request = MagicMock() + request.model = "test-model" + + sse = MagicMock() + sse.blocks = MagicMock() + sse.blocks.tool_indices = {} + sse.blocks.tool_names = {} + sse.blocks.tool_started = {} + + # Tool call data (Task tool) + tc = { + "index": 0, + "id": "tool_123", + "function": { + "name": "Task", + "arguments": json.dumps( + { + "description": "test task", + "prompt": "do something", + "run_in_background": True, + } + ), + }, + } + + # Remove pre-filled tool name - _process_tool_call handles it + # sse.blocks.tool_names[0] = "Task" + + # Call the method + events = [] + # _process_tool_call is a synchronous generator in nvidia_nim.py + for event in provider._process_tool_call(tc, sse): + events.append(event) + + # Find the start_tool_block call or check the modified state + calls = sse.emit_tool_delta.call_args_list + assert len(calls) > 0 + args_passed = json.loads(calls[0][0][1]) + assert args_passed["run_in_background"] is False + print("Verification successful: run_in_background was forced to False") + + +if __name__ == "__main__": + import asyncio + + asyncio.run(test_task_tool_interception())