Feature: ToolAgent Functionality Scenario: Tool agent executes echo tool Given a ToolAgent is configured with name "echo_tool_agent" and config """ { "tools": ["echo"] } """ When I create the ToolAgent And I process a message with the ToolAgent: "echo hello world" Then the result should be "hello world" Scenario: Tool agent executes math tool with simple format Given a ToolAgent is configured with name "math_tool_agent" and config """ { "tools": ["math"] } """ When I create the ToolAgent And I process a message with the ToolAgent: "math 2+2*3" Then the result should be "8" Scenario: Tool agent executes math tool with JSON format Given a ToolAgent is configured with name "math_tool_agent" and config """ { "tools": ["math"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "math", "args": {"expression": "10 / 2"}} """ Then the result should be "5.0" Scenario: Tool agent handles invalid math expression Given a ToolAgent is configured with name "math_tool_agent" and config """ { "tools": ["math"] } """ When I create the ToolAgent And I process a message with the ToolAgent: "math 1/0" Then tool execution should fail with message containing "division by zero" Scenario: Tool agent file write and read Given I am running in unsafe mode And a ToolAgent is configured with name "file_tool_agent" and config """ { "tools": ["file_write", "file_read"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test.txt", "content": "hello from file"}} """ Then the tool result should contain "Successfully wrote" When I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "test.txt"}} """ Then the result should contain "hello from file" Scenario: Tool agent file write requires unsafe mode Given a ToolAgent is configured with name "file_tool_agent" and config """ { "tools": ["file_write"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test.txt", "content": "hello from file"}} """ Then tool execution should fail with message containing "File writing requires unsafe mode" Scenario: Tool Agent shell command execution Given I am running in unsafe mode And a ToolAgent is configured with name "shell_tool_agent" and config """ { "tools": ["/bin/echo"], "allow_shell": true } """ When I create the ToolAgent And I process a message with the ToolAgent: "/bin/echo hello shell" Then the result should be "hello shell" Scenario: Tool Agent shell command execution fails for dangerous command Given I am running in unsafe mode And a ToolAgent is configured with name "shell_tool_agent" and config """ { "tools": ["rm"], "allow_shell": true, "safe_mode": true } """ When I create the ToolAgent And I process a message with the ToolAgent: "rm -rf /" Then tool execution should fail with message containing "Dangerous command 'rm' blocked in safe mode" Scenario: Tool Agent validation fails for unknown tool Given a ToolAgent is configured with name "bad_tool_agent" and config """ { "tools": ["unknown_tool"], "allow_shell": false } """ When I try to create the ToolAgent Then agent creation should fail with message containing "Unknown tool 'unknown_tool' and shell execution disabled" Scenario: Tool Agent get capabilities and metadata Given a ToolAgent is configured with name "meta_agent" and config """ { "tools": ["echo", "math", "file_read", "file_write", "http_request"], "allow_shell": true, "safe_mode": false, "timeout": 2 } """ When I create the ToolAgent Then the agent capabilities should contain "tool-execution" And the agent capabilities should contain "file-operations" And the agent capabilities should contain "math-evaluation" And the agent capabilities should contain "http-requests" And the agent metadata "allow_shell" should be true And the agent metadata "safe_mode" should be false And the agent metadata "timeout" should be 2 Scenario: Tool Agent validation fails for invalid dict config Given a ToolAgent is configured with name "bad_dict_tool_agent" and config """ { "tools": [{"invalid": "config"}] } """ When I try to create the ToolAgent Then agent creation should fail with message containing "Tool configuration must include 'name'" Scenario: Tool Agent fails for not allowed tool Given a ToolAgent is configured with name "limited_tool_agent" and config """ { "tools": ["math"] } """ When I create the ToolAgent And I process a message with the ToolAgent: "echo hello" Then tool execution should fail with message containing "Tool 'echo' not in allowed tools list" Scenario: Tool agent file read with unsafe path blocked Given I am running in unsafe mode And a ToolAgent is configured with name "file_tool_agent" and config """ { "tools": ["file_read"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "../unsafe.txt"}} """ Then tool execution should fail with message containing "Unsafe file path blocked in safe mode" Scenario: Tool agent validates invalid tool configuration type Given a ToolAgent is configured with name "invalid_tool_agent" and config """ { "tools": [123] } """ When I try to create the ToolAgent Then agent creation should fail with message containing "Invalid tool configuration: 123" Scenario: Tool agent handles empty tool request Given a ToolAgent is configured with name "empty_tool_agent" and config """ { "tools": ["echo"] } """ When I create the ToolAgent And I process a message with the ToolAgent: "" Then tool execution should fail with message containing "Empty tool request" Scenario: Tool agent handles invalid JSON in tool request Given a ToolAgent is configured with name "json_tool_agent" and config """ { "tools": ["echo"] } """ When I create the ToolAgent And I process a message with the ToolAgent: "{invalid json}" Then tool execution should fail with message containing "Invalid JSON in tool request" Scenario: Tool agent shell execution disabled during creation Given a ToolAgent is configured with name "no_shell_agent" and config """ { "tools": ["custom_command"], "allow_shell": false } """ When I try to create the ToolAgent Then agent creation should fail with message containing "Unknown tool 'custom_command' and shell execution disabled" Scenario: Tool agent shell execution disabled at runtime Given a ToolAgent is configured with name "runtime_shell_agent" and config """ { "tools": ["echo", "custom_runtime_command"], "allow_shell": false } """ When I try to create the ToolAgent Then agent creation should fail with message containing "Unknown tool 'custom_runtime_command' and shell execution disabled" Scenario: Tool agent shell command timeout Given I am running in unsafe mode And a ToolAgent is configured with name "timeout_agent" and config """ { "tools": ["sleep"], "allow_shell": true, "timeout": 0.1, "safe_mode": false } """ When I create the ToolAgent And I process a message with the ToolAgent: "sleep 1" Then tool execution should fail with message containing "timed out after 0.1 seconds" And tool execution should fail with message containing "'timeout' config value" Scenario: Tool agent shell command with non-zero exit code Given I am running in unsafe mode And a ToolAgent is configured with name "error_command_agent" and config """ { "tools": ["false"], "allow_shell": true, "safe_mode": false } """ When I create the ToolAgent And I process a message with the ToolAgent: "false" Then tool execution should fail with message containing "Command failed with code 1" Scenario: Tool agent echo tool with args format Given a ToolAgent is configured with name "echo_args_agent" and config """ { "tools": ["echo"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "echo", "args": {"args": ["hello", "from", "args"]}} """ Then the result should be "hello from args" Scenario: Tool agent math tool requires expression Given a ToolAgent is configured with name "math_empty_agent" and config """ { "tools": ["math"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "math", "args": {}} """ Then tool execution should fail with message containing "Math tool requires an expression" Scenario: Tool agent json_parse tool basic usage Given a ToolAgent is configured with name "json_parse_agent" and config """ { "tools": ["json_parse"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "json_parse", "args": {"json": "{\"key\": \"value\"}"}} """ Then the tool result should contain "key" And the tool result should contain "value" Scenario: Tool agent json_parse tool with args format Given a ToolAgent is configured with name "json_parse_args_agent" and config """ { "tools": ["json_parse"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "json_parse", "args": {"args": ["{\"test\": 123}"]}} """ Then the tool result should contain "test" And the tool result should contain "123" Scenario: Tool agent json_parse tool with invalid JSON Given a ToolAgent is configured with name "json_parse_invalid_agent" and config """ { "tools": ["json_parse"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "json_parse", "args": {"json": "invalid json"}} """ Then tool execution should fail with message containing "JSON parsing failed" Scenario: Tool agent http_request tool basic usage Given a ToolAgent is configured with name "http_agent" and config """ { "tools": ["http_request"], "timeout": 5 } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "http_request", "args": {"url": "https://httpbin.org/get", "method": "GET"}} """ Then the tool result should contain "Status: 200" Scenario: Tool agent http_request tool requires URL Given a ToolAgent is configured with name "http_no_url_agent" and config """ { "tools": ["http_request"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "http_request", "args": {}} """ Then tool execution should fail with message containing "HTTP tool requires a URL" Scenario: Tool agent http_request tool with POST data Given a ToolAgent is configured with name "http_post_agent" and config """ { "tools": ["http_request"], "timeout": 5 } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "http_request", "args": {"url": "https://httpbin.org/post", "method": "POST", "data": {"test": "data"}, "headers": {"Content-Type": "application/json"}}} """ Then the tool result should contain "Status: 200" Scenario: Tool agent file_read tool requires file path Given I am running in unsafe mode And a ToolAgent is configured with name "file_read_no_path_agent" and config """ { "tools": ["file_read"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {}} """ Then tool execution should fail with message containing "File read tool requires a file path" Scenario: Tool agent file_read tool with args format Given I am running in unsafe mode And a ToolAgent is configured with name "file_read_args_agent" and config """ { "tools": ["file_read"] } """ When I create the ToolAgent And I create a test file with content "test file content" And I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"args": ["test_file.txt"]}} """ Then the result should contain "test file content" Scenario: Tool agent file_read tool with absolute path in safe mode Given a ToolAgent is configured with name "file_read_abs_path_agent" and config """ { "tools": ["file_read"], "safe_mode": true } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "/etc/passwd"}} """ Then tool execution should fail with message containing "Unsafe file path blocked in safe mode" Scenario: Tool agent file_read tool with absolute path in unsafe context Given I am running in unsafe mode And a ToolAgent is configured with name "file_read_abs_unsafe_agent" and config """ { "tools": ["file_read"], "safe_mode": true } """ When I create the ToolAgent And I create an absolute test file with content "absolute file content" And I process a JSON message with unsafe context with the ToolAgent: """ {"tool": "file_read", "args": {"file": "/tmp/test_abs_file.txt"}} """ Then the result should contain "absolute file content" Scenario: Tool agent file_read tool with file not found Given I am running in unsafe mode And a ToolAgent is configured with name "file_read_not_found_agent" and config """ { "tools": ["file_read"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "nonexistent.txt"}} """ Then tool execution should fail with message containing "File not found" Scenario: Tool agent file_write tool requires file path and content Given I am running in unsafe mode And a ToolAgent is configured with name "file_write_no_args_agent" and config """ { "tools": ["file_write"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test.txt"}} """ Then tool execution should fail with message containing "File write tool requires file path and content" Scenario: Tool agent file_write tool with absolute path in safe mode Given a ToolAgent is configured with name "file_write_abs_path_agent" and config """ { "tools": ["file_write"], "safe_mode": true } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "/tmp/test.txt", "content": "test"}} """ Then tool execution should fail with message containing "File writing requires unsafe mode" Scenario: Tool agent file_write tool with directory traversal blocked Given I am running in unsafe mode And a ToolAgent is configured with name "file_write_traversal_agent" and config """ { "tools": ["file_write"], "safe_mode": true } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "../test.txt", "content": "test"}} """ Then tool execution should fail with message containing "Unsafe file path blocked in safe mode" Scenario: Tool agent file_write tool with write error Given I am running in unsafe mode And a ToolAgent is configured with name "file_write_error_agent" and config """ { "tools": ["file_write"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "/invalid/path/file.txt", "content": "test"}} """ Then tool execution should fail with message containing "File write failed" Scenario: Tool agent capabilities with dict tool configuration Given a ToolAgent is configured with name "dict_tools_agent" and config """ { "tools": [{"name": "http_request"}, {"name": "file_read"}] } """ When I create the ToolAgent Then the agent capabilities should contain "http-requests" And the agent capabilities should contain "file-operations" Scenario: Tool agent http_request tool timeout error Given a ToolAgent is configured with name "http_timeout_agent" and config """ { "tools": ["http_request"], "timeout": 0.001 } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "http_request", "args": {"url": "https://httpbin.org/delay/1", "method": "GET"}} """ Then tool execution should fail with message containing "timed out after 0.001 seconds" And tool execution should fail with message containing "'timeout' config value" Scenario: Tool agent http_request tool with invalid URL Given a ToolAgent is configured with name "http_invalid_agent" and config """ { "tools": ["http_request"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "http_request", "args": {"url": "invalid://url", "method": "GET"}} """ Then tool execution should fail with message containing "HTTP request failed" Scenario: Tool agent math tool with args format Given a ToolAgent is configured with name "math_args_agent" and config """ { "tools": ["math"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "math", "args": {"args": ["2*3+1"]}} """ Then the result should be "7" Scenario: Tool agent echo tool with text parameter Given a ToolAgent is configured with name "echo_text_agent" and config """ { "tools": ["echo"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "echo", "args": {"text": "hello text param"}} """ Then the result should be "hello text param" Scenario: Tool agent shell safe mode blocking Given I am running in unsafe mode And a ToolAgent is configured with name "safe_shell_agent" and config """ { "tools": ["rm"], "allow_shell": true, "safe_mode": true } """ When I create the ToolAgent And I process a message with the ToolAgent: "rm -rf test" Then tool execution should fail with message containing "Dangerous command 'rm' blocked in safe mode" Scenario: Tool agent with dict tool config validation Given a ToolAgent is configured with name "dict_config_agent" and config """ { "tools": [{"name": "echo", "description": "echo tool"}] } """ When I create the ToolAgent And I process a message with the ToolAgent: "echo hello dict" Then the result should be "hello dict" Scenario: Tool agent file write append mode Given I am running in unsafe mode And a ToolAgent is configured with name "file_write_append_agent" and config """ { "tools": ["file_write", "file_read"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test_append.txt", "content": "initial content", "mode": "w"}} """ Then the tool result should contain "Successfully wrote" When I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test_append.txt", "content": " appended content", "mode": "a"}} """ Then the tool result should contain "Successfully appended" When I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "test_append.txt"}} """ Then the result should contain "initial content appended content" Scenario: Tool agent file write insert mode at end Given I am running in unsafe mode And a ToolAgent is configured with name "file_write_insert_agent" and config """ { "tools": ["file_write", "file_read"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test_insert.txt", "content": "line1\nline2\nline3", "mode": "w"}} """ Then the tool result should contain "Successfully wrote" When I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test_insert.txt", "content": "inserted line", "mode": "insert", "position": "end"}} """ Then the tool result should contain "Successfully inserted" When I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "test_insert.txt"}} """ Then the result should contain "inserted line" Scenario: Tool agent file write insert mode at start Given I am running in unsafe mode And a ToolAgent is configured with name "file_write_insert_start_agent" and config """ { "tools": ["file_write", "file_read"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test_insert_start.txt", "content": "original line", "mode": "w"}} """ Then the tool result should contain "Successfully wrote" When I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test_insert_start.txt", "content": "first line", "mode": "insert", "position": "start"}} """ Then the tool result should contain "Successfully inserted" When I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "test_insert_start.txt"}} """ Then the result should contain "first line" Scenario: Tool agent file write insert mode at specific line Given I am running in unsafe mode And a ToolAgent is configured with name "file_write_insert_line_agent" and config """ { "tools": ["file_write", "file_read"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test_insert_line.txt", "content": "line1\nline2\nline3", "mode": "w"}} """ Then the tool result should contain "Successfully wrote" When I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test_insert_line.txt", "content": "middle line", "mode": "insert", "position": 2}} """ Then the tool result should contain "Successfully inserted" When I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "test_insert_line.txt"}} """ Then the result should contain "middle line" Scenario: Tool agent file write invalid mode Given I am running in unsafe mode And a ToolAgent is configured with name "file_write_invalid_mode_agent" and config """ { "tools": ["file_write"] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_write", "args": {"file": "test.txt", "content": "test", "mode": "invalid"}} """ Then tool execution should fail with message containing "Invalid mode" # ── ToolAgent dict-style tool name dispatch fix (issue #63) ────────── Scenario: Tool agent with dict-style tools rejects unauthorized tool Given a ToolAgent is configured with name "dict_tool_agent" and config """ { "tools": [{"name": "echo"}] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "test.txt"}} """ Then tool execution should fail with message containing "not in allowed tools list" Scenario: Tool agent with dict-style tools accepts authorized tool Given a ToolAgent is configured with name "dict_echo_agent" and config """ { "tools": [{"name": "echo"}] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "echo", "args": {"text": "dict works"}} """ Then the result should be "dict works" Scenario: Tool agent with mixed string and dict tools rejects unauthorized Given a ToolAgent is configured with name "mixed_tool_agent" and config """ { "tools": ["echo", {"name": "math"}] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "file_read", "args": {"file": "test.txt"}} """ Then tool execution should fail with message containing "not in allowed tools list" Scenario: Tool agent with mixed string and dict tools accepts authorized string tool Given a ToolAgent is configured with name "mixed_echo_agent" and config """ { "tools": ["echo", {"name": "math"}] } """ When I create the ToolAgent And I process a message with the ToolAgent: "echo works with mixed" Then the result should be "works with mixed" Scenario: Tool agent with mixed string and dict tools accepts authorized dict tool Given a ToolAgent is configured with name "mixed_math_agent" and config """ { "tools": ["echo", {"name": "math"}] } """ When I create the ToolAgent And I process a JSON message with the ToolAgent: """ {"tool": "math", "args": {"expression": "40+2"}} """ Then the result should be "42"