Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions documentation/docs/api-reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ Options:

- `--user-id, -u TEXT`: User ID for authorization flows

- `--response-only, -ro`: Return only the JSON payload response without metadata

**Example Output:**

- Session and Request IDs displayed in panel header
Expand Down Expand Up @@ -229,6 +231,9 @@ agentcore invoke '{"prompt": "Secure request"}' --bearer-token eyJhbGciOiJIUzI1N

# Invoke local agent
agentcore invoke '{"prompt": "Test locally"}' --local

# Invoke with response-only flag (returns only the JSON payload)
agentcore invoke '{"prompt": "Get raw response"}' --response-only
```

### Check Status
Expand Down
19 changes: 15 additions & 4 deletions src/bedrock_agentcore_starter_toolkit/cli/runtime/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,10 +602,11 @@ def _show_invoke_info_panel(agent_name: str, invoke_result=None, config=None):
)


def _show_success_response(content):
def _show_success_response(content, response_only=False):
"""Show success response content below panel."""
if content:
console.print("\n[bold]Response:[/bold]")
if not response_only:
console.print("\n[bold]Response:[/bold]")
console.print(content)


Expand Down Expand Up @@ -670,6 +671,9 @@ def invoke(
help="Custom headers (format: 'Header1:value,Header2:value2'). "
"Headers will be auto-prefixed with 'X-Amzn-Bedrock-AgentCore-Runtime-Custom-' if not already present.",
),
response_only: Optional[bool] = typer.Option(
False, "--response-only", "-ro", help="Return only the JSON payload response without metadata"
),
):
"""Invoke Bedrock AgentCore endpoint."""
config_path = Path.cwd() / ".bedrock_agentcore.yaml"
Expand Down Expand Up @@ -725,7 +729,12 @@ def invoke(
custom_headers=custom_headers,
)
agent_display = config.name if config else (agent or "unknown")
_show_invoke_info_panel(agent_display, result, config)

# Show info panel only if response_only is False
if not response_only:
_show_invoke_info_panel(agent_display, result, config)

# Process response content
if result.response != {}:
content = result.response
if isinstance(content, dict) and "response" in content:
Expand All @@ -752,7 +761,9 @@ def invoke(
content = parsed
except (json.JSONDecodeError, TypeError):
pass
_show_success_response(content)

# Display the content with or without formatting based on response_only flag
_show_success_response(content, response_only)

except FileNotFoundError:
_show_configuration_not_found_panel()
Expand Down
71 changes: 71 additions & 0 deletions tests/cli/runtime/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -3087,3 +3087,74 @@ def test_invoke_with_headers_local_mode(self, tmp_path):
assert call_args.kwargs["custom_headers"] == expected_headers
finally:
os.chdir(original_cwd)

def test_invoke_with_response_only_flag(self, tmp_path):
"""Test invoke command with response_only flag."""
config_file = tmp_path / ".bedrock_agentcore.yaml"
config_content = """
default_agent: test-agent
agents:
test-agent:
name: test-agent
entrypoint: test.py
"""
config_file.write_text(config_content.strip())

with (
patch("bedrock_agentcore_starter_toolkit.cli.runtime.commands.load_config") as mock_load_config,
patch("bedrock_agentcore_starter_toolkit.cli.runtime.commands.invoke_bedrock_agentcore") as mock_invoke,
patch("bedrock_agentcore_starter_toolkit.cli.runtime.commands.console.print") as mock_print,
patch("bedrock_agentcore_starter_toolkit.cli.runtime.commands._show_invoke_info_panel") as mock_show_panel,
patch("bedrock_agentcore_starter_toolkit.cli.runtime.commands._show_success_response") as mock_show_response,
):
# Mock project config and agent config
mock_project_config = Mock()
mock_agent_config = Mock()
mock_agent_config.authorizer_configuration = None
mock_project_config.get_agent_config.return_value = mock_agent_config
mock_load_config.return_value = mock_project_config

# Create a response with nested structure
mock_result = Mock()
mock_result.response = {"response": "This is the raw response"}
mock_result.session_id = "test-session"
mock_invoke.return_value = mock_result

original_cwd = Path.cwd()
os.chdir(tmp_path)

try:
# Test with response_only flag
result = self.runner.invoke(
app, ["invoke", '{"message": "hello"}', "--response-only"]
)

assert result.exit_code == 0

# Verify response_only was passed to invoke_bedrock_agentcore
call_args = mock_invoke.call_args

# Verify the info panel was not shown when response_only is True
mock_show_panel.assert_not_called()
mock_show_response.assert_not_called()

# Verify console.print was called directly with the content
mock_print.assert_any_call("This is the raw response")

# Test without response_only flag
mock_show_panel.reset_mock()
mock_show_response.reset_mock()
mock_print.reset_mock()

result = self.runner.invoke(
app, ["invoke", '{"message": "hello"}']
)

assert result.exit_code == 0

# Verify the info panel was shown when response_only is False
mock_show_panel.assert_called_once()
mock_show_response.assert_called_once()

finally:
os.chdir(original_cwd)