Skip to content
Merged
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
74 changes: 66 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ if result.success:
```

Test helpers include:
- **`test_agent`**: Pre-configured MCP test agent (ready to use)
- **`test_agent_a2a`**: Pre-configured A2A test agent
- **`test_agent`**: Pre-configured MCP test agent with authentication
- **`test_agent_a2a`**: Pre-configured A2A test agent with authentication
- **`test_agent_no_auth`**: Pre-configured MCP test agent WITHOUT authentication
- **`test_agent_a2a_no_auth`**: Pre-configured A2A test agent WITHOUT authentication
- **`creative_agent`**: Reference creative agent for preview functionality
- **`test_agent_client`**: Multi-agent client with both protocols
- **`create_test_agent()`**: Factory for custom test configurations
Expand Down Expand Up @@ -113,32 +115,47 @@ async with ADCPMultiAgentClient(
Pre-configured test agents for instant prototyping and testing:

```python
from adcp.testing import test_agent, test_agent_a2a, creative_agent, test_agent_client, create_test_agent
from adcp.testing import (
test_agent, test_agent_a2a,
test_agent_no_auth, test_agent_a2a_no_auth,
creative_agent, test_agent_client, create_test_agent
)
from adcp.types.generated import GetProductsRequest, PreviewCreativeRequest

# 1. Single agent (MCP)
# 1. Single agent with authentication (MCP)
result = await test_agent.get_products(
GetProductsRequest(brief="Coffee brands")
)

# 2. Single agent (A2A)
# 2. Single agent with authentication (A2A)
result = await test_agent_a2a.get_products(
GetProductsRequest(brief="Coffee brands")
)

# 3. Creative agent (preview functionality)
# 3. Single agent WITHOUT authentication (MCP)
# Useful for testing unauthenticated behavior
result = await test_agent_no_auth.get_products(
GetProductsRequest(brief="Coffee brands")
)

# 4. Single agent WITHOUT authentication (A2A)
result = await test_agent_a2a_no_auth.get_products(
GetProductsRequest(brief="Coffee brands")
)

# 5. Creative agent (preview functionality, no auth required)
result = await creative_agent.preview_creative(
PreviewCreativeRequest(
manifest={"format_id": "banner_300x250", "assets": {...}}
)
)

# 4. Multi-agent (parallel execution)
# 6. Multi-agent (parallel execution with both protocols)
results = await test_agent_client.get_products(
GetProductsRequest(brief="Coffee brands")
)

# 5. Custom configuration
# 7. Custom configuration
from adcp.client import ADCPClient
config = create_test_agent(id="my-test", timeout=60.0)
client = ADCPClient(config)
Expand All @@ -148,6 +165,7 @@ client = ADCPClient(config)
- Quick prototyping and experimentation
- Example code and documentation
- Integration testing without mock servers
- Testing authentication behavior (comparing auth vs no-auth results)
- Learning AdCP concepts

**Important:** Test agents are public, rate-limited, and for testing only. Never use in production.
Expand Down Expand Up @@ -417,6 +435,46 @@ uvx adcp --json myagent get_products '{"brief":"TV ads"}'
uvx adcp --debug myagent get_products '{"brief":"TV ads"}'
```

### Using Test Agents from CLI

The CLI provides easy access to public test agents without configuration:

```bash
# Use test agent with authentication (MCP)
uvx adcp https://test-agent.adcontextprotocol.org/mcp/ \
--auth 1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ \
get_products '{"brief":"Coffee brands"}'

# Use test agent WITHOUT authentication (MCP)
uvx adcp https://test-agent.adcontextprotocol.org/mcp/ \
get_products '{"brief":"Coffee brands"}'

# Use test agent with authentication (A2A)
uvx adcp --protocol a2a \
--auth 1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ \
https://test-agent.adcontextprotocol.org \
get_products '{"brief":"Coffee brands"}'

# Save test agent for easier access
uvx adcp --save-auth test-agent https://test-agent.adcontextprotocol.org/mcp/ mcp
# Enter token when prompted: 1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ

# Now use saved config
uvx adcp test-agent get_products '{"brief":"Coffee brands"}'

# Use creative agent (no auth required)
uvx adcp https://creative.adcontextprotocol.org/mcp \
preview_creative @creative_manifest.json
```

**Test Agent Details:**
- **URL (MCP)**: `https://test-agent.adcontextprotocol.org/mcp/`
- **URL (A2A)**: `https://test-agent.adcontextprotocol.org`
- **Auth Token**: `1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ` (optional, public token)
- **Rate Limited**: For testing only, not for production
- **No Auth Mode**: Omit `--auth` flag to test unauthenticated behavior
```

### Configuration Management

```bash
Expand Down
58 changes: 54 additions & 4 deletions examples/test_helpers_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
create_test_agent,
test_agent,
test_agent_a2a,
test_agent_a2a_no_auth,
test_agent_client,
test_agent_no_auth,
)
from adcp.types.generated import GetProductsRequest, ListCreativeFormatsRequest

Expand Down Expand Up @@ -148,12 +150,57 @@ async def custom_test_agent() -> None:
await client.close()


async def auth_vs_no_auth_comparison() -> None:
"""Example 5: Authenticated vs Unauthenticated Requests.

Compare behavior between authenticated and unauthenticated test agents.
Useful for testing how agents handle different authentication states.
"""
print("🔐 Example 5: Authentication Comparison")
print("=" * 39)
print()

request = GetProductsRequest(
brief="Coffee subscription service",
promoted_offering="Premium coffee",
)

try:
# Test with authentication
print("Testing WITH authentication (MCP)...")
auth_result = await test_agent.get_products(request)
auth_success = "✅" if auth_result.success else "❌"
auth_count = len(auth_result.data.products) if auth_result.data else 0
print(f" {auth_success} With Auth: {auth_count} products")

# Test without authentication
print("Testing WITHOUT authentication (MCP)...")
no_auth_result = await test_agent_no_auth.get_products(request)
no_auth_success = "✅" if no_auth_result.success else "❌"
no_auth_count = len(no_auth_result.data.products) if no_auth_result.data else 0
print(f" {no_auth_success} No Auth: {no_auth_count} products")

# Compare results
print()
if auth_count != no_auth_count:
print(" 💡 Note: Different results with/without auth!")
print(f" Auth returned {auth_count} products")
print(f" No auth returned {no_auth_count} products")
else:
print(" 💡 Note: Same results with/without auth")

print()
except Exception as e:
print(f"❌ Error: {e}")
print()


async def various_operations() -> None:
"""Example 5: Testing Different Operations.
"""Example 6: Testing Different Operations.

Show various ADCP operations with test agents.
"""
print("🎬 Example 5: Various ADCP Operations")
print("🎬 Example 6: Various ADCP Operations")
print("=" * 37)
print()

Expand Down Expand Up @@ -195,11 +242,14 @@ async def main() -> None:
await protocol_comparison()
await multi_agent_example()
await custom_test_agent()
await auth_vs_no_auth_comparison()
await various_operations()

print("💡 Key Takeaways:")
print(" • test_agent = Pre-configured MCP test agent (ready to use!)")
print(" • test_agent_a2a = Pre-configured A2A test agent")
print(" • test_agent = Pre-configured MCP test agent with auth")
print(" • test_agent_a2a = Pre-configured A2A test agent with auth")
print(" • test_agent_no_auth = Pre-configured MCP test agent WITHOUT auth")
print(" • test_agent_a2a_no_auth = Pre-configured A2A test agent WITHOUT auth")
print(" • test_agent_client = Multi-agent client with both protocols")
print(" • create_test_agent() = Create custom test configurations")
print(" • Perfect for examples, docs, and quick testing")
Expand Down
8 changes: 8 additions & 0 deletions src/adcp/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,31 @@
from adcp.testing.test_helpers import (
CREATIVE_AGENT_CONFIG,
TEST_AGENT_A2A_CONFIG,
TEST_AGENT_A2A_NO_AUTH_CONFIG,
TEST_AGENT_MCP_CONFIG,
TEST_AGENT_MCP_NO_AUTH_CONFIG,
TEST_AGENT_TOKEN,
create_test_agent,
creative_agent,
test_agent,
test_agent_a2a,
test_agent_a2a_no_auth,
test_agent_client,
test_agent_no_auth,
)

__all__ = [
"test_agent",
"test_agent_a2a",
"test_agent_no_auth",
"test_agent_a2a_no_auth",
"creative_agent",
"test_agent_client",
"create_test_agent",
"TEST_AGENT_TOKEN",
"TEST_AGENT_MCP_CONFIG",
"TEST_AGENT_A2A_CONFIG",
"TEST_AGENT_MCP_NO_AUTH_CONFIG",
"TEST_AGENT_A2A_NO_AUTH_CONFIG",
"CREATIVE_AGENT_CONFIG",
]
86 changes: 86 additions & 0 deletions src/adcp/testing/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@
auth_token=TEST_AGENT_TOKEN,
)

# Public test agent configuration (no auth) - MCP protocol
TEST_AGENT_MCP_NO_AUTH_CONFIG = AgentConfig(
id="test-agent-mcp-no-auth",
agent_uri="https://test-agent.adcontextprotocol.org/mcp/",
protocol=Protocol.MCP,
)

# Public test agent configuration (no auth) - A2A protocol
TEST_AGENT_A2A_NO_AUTH_CONFIG = AgentConfig(
id="test-agent-a2a-no-auth",
agent_uri="https://test-agent.adcontextprotocol.org",
protocol=Protocol.A2A,
)

# Reference creative agent configuration - MCP protocol
# No authentication required for the reference creative agent
CREATIVE_AGENT_CONFIG = AgentConfig(
Expand Down Expand Up @@ -67,6 +81,34 @@ def _create_test_agent_a2a_client() -> ADCPClient:
return ADCPClient(TEST_AGENT_A2A_CONFIG)


def _create_test_agent_no_auth_client() -> ADCPClient:
"""Create pre-configured test agent client (no auth) using MCP protocol.

Returns:
ADCPClient instance configured for the public test agent without authentication

Note:
This agent is rate-limited and intended for testing scenarios where no auth is provided.
Useful for testing behavior differences between authenticated and unauthenticated requests.
DO NOT use in production applications.
"""
return ADCPClient(TEST_AGENT_MCP_NO_AUTH_CONFIG)


def _create_test_agent_a2a_no_auth_client() -> ADCPClient:
"""Create pre-configured test agent client (no auth) using A2A protocol.

Returns:
ADCPClient instance configured for the public test agent without authentication

Note:
This agent is rate-limited and intended for testing scenarios where no auth is provided.
Useful for testing behavior differences between authenticated and unauthenticated requests.
DO NOT use in production applications.
"""
return ADCPClient(TEST_AGENT_A2A_NO_AUTH_CONFIG)


def _create_creative_agent_client() -> ADCPClient:
"""Create pre-configured creative agent client.

Expand Down Expand Up @@ -139,6 +181,50 @@ def _create_test_multi_agent_client() -> ADCPMultiAgentClient:
# DO NOT use in production applications.
test_agent_a2a: ADCPClient = _create_test_agent_a2a_client()

# Pre-configured test agent client (no auth) using MCP protocol.
# Useful for testing scenarios where authentication is not provided,
# such as testing how agents handle unauthenticated requests or
# comparing behavior between authenticated and unauthenticated calls.
#
# Example:
# ```python
# from adcp.testing import test_agent_no_auth
#
# # Test behavior without authentication
# result = await test_agent_no_auth.get_products(
# GetProductsRequest(
# brief="Coffee subscription service",
# promoted_offering="Premium monthly coffee"
# )
# )
# ```
#
# Note:
# This agent is rate-limited and intended for testing/examples only.
# DO NOT use in production applications.
test_agent_no_auth: ADCPClient = _create_test_agent_no_auth_client()

# Pre-configured test agent client (no auth) using A2A protocol.
# Identical functionality to test_agent_no_auth but uses A2A instead of MCP.
#
# Example:
# ```python
# from adcp.testing import test_agent_a2a_no_auth
#
# # Test A2A behavior without authentication
# result = await test_agent_a2a_no_auth.get_products(
# GetProductsRequest(
# brief="Sustainable fashion brands",
# promoted_offering="Eco-friendly clothing"
# )
# )
# ```
#
# Note:
# This agent is rate-limited and intended for testing/examples only.
# DO NOT use in production applications.
test_agent_a2a_no_auth: ADCPClient = _create_test_agent_a2a_no_auth_client()

# Pre-configured reference creative agent.
# Provides creative preview functionality without authentication.
#
Expand Down
Loading