proxies.md
1 --- 2 title: Proxies 3 sidebar_position: 250 4 --- 5 6 # Proxies 7 8 Proxies act as protocol bridges that connect Agent Mesh to external A2A agents. By translating between A2A over Solace event mesh and A2A over HTTPS protocols, proxies enable agents within the mesh to delegate tasks to external agents and include them in collaborative workflows. 9 10 A single proxy instance can manage multiple external agents, each with its own URL, authentication configuration, and timeout settings. 11 12 :::tip[In one sentence] 13 Proxies are protocol bridges that connect multiple external A2A-over-HTTPS agents to the Solace event mesh, enabling hybrid agent architectures. 14 ::: 15 16 :::info[Agent Mesh Enterprise] 17 If you are using Agent Mesh Enterprise, you can connect external agents through a guided wizard interface instead of writing YAML configuration files. For more information, see [Connect External Agents](../enterprise/connect-external-agents.md). 18 ::: 19 20 ## Key Functions 21 22 1. **Protocol Translation**: Proxies translate between A2A over HTTPS and A2A over Solace event mesh, enabling external agents to communicate with agents on the mesh without modification. 23 24 2. **Authentication Management**: Proxies handle authentication to downstream agents, supporting multiple authentication schemes including static bearer tokens, API keys, and OAuth 2.0 client credentials flow with automatic token refresh. 25 26 3. **Agent Discovery**: Proxies fetch agent cards from external agents and publish them to the mesh discovery topic, making external agents discoverable to other agents in the system. 27 28 4. **Artifact Handling**: Proxies manage artifact flow between the mesh and external agents, resolving artifact URIs to byte content before forwarding requests and saving returned artifacts to the mesh's artifact service. 29 30 5. **Task Lifecycle Management**: Proxies track active tasks, handle cancellation requests, and ensure proper cleanup when tasks complete or fail. 31 32 6. **Automatic Retry Logic**: For OAuth 2.0 authenticated agents, proxies automatically detect authentication failures (401 responses), refresh tokens, and retry requests without manual intervention. 33 34 ## When to Use a Proxy 35 36 Proxies are the right choice when you need: 37 38 - **Integration with Third-Party Agents**: Connect to external A2A agents provided by vendors or partners that run on their own infrastructure. 39 40 - **Hybrid Cloud Architectures**: Bridge agents running in different cloud environments or on-premises systems with your Solace mesh. 41 42 - **Legacy System Integration**: Connect existing A2A agents that cannot be modified to use Solace messaging directly. 43 44 - **Gradual Migration**: Incrementally migrate agents to the Solace mesh while maintaining compatibility with external systems. 45 46 - **Service Isolation**: Keep certain agents isolated on separate infrastructure while still enabling them to participate in collaborative workflows. 47 48 ### Proxy vs. Native Agent 49 50 | Aspect | Proxy | Native Agent | 51 |--------|-------|--------------| 52 | **Communication** | A2A over HTTPS to external agent | A2A over Solace event mesh directly | 53 | **Deployment** | External agent runs separately | Runs within Agent Mesh | 54 | **Authentication** | Proxy handles auth to external agent | Mesh-level authentication | 55 | **Latency** | Additional HTTP hop | Direct mesh communication | 56 | **Task Initiation** | Can only receive tasks from mesh agents | Can initiate tasks to any agent | 57 | **Use Case** | External/third-party agents | Agents you control | 58 59 ## Architecture Overview 60 61 The proxy sits between the Solace event mesh and external A2A agents, performing bidirectional protocol translation: 62 63 ```mermaid 64 graph LR 65 A[Agent Mesh<br/>A2A over Solace Event Mesh] <-->|Solace Topics| B[Proxy Component] 66 B <-->|HTTPS| C[External Agent 1<br/>A2A over HTTPS] 67 B <-->|HTTPS| D[External Agent 2<br/>A2A over HTTPS] 68 B <-->|HTTPS| E[External Agent N<br/>A2A over HTTPS] 69 70 style B fill:none,stroke:#00C895,stroke-width:2px 71 style A fill:none,stroke:#333,stroke-width:2px 72 style C fill:none,stroke:#333,stroke-width:2px 73 style D fill:none,stroke:#333,stroke-width:2px 74 style E fill:none,stroke:#333,stroke-width:2px 75 ``` 76 77 The proxy performs these operations: 78 79 1. **Request Flow**: Receives A2A requests from Agent Mesh, resolves artifact URIs to byte content, forwards HTTPS requests to external agents, and streams responses back to Agent Mesh. 80 81 2. **Response Flow**: Receives responses from external agents, saves artifacts to Agent Mesh's artifact service, replaces byte content with artifact URIs, and publishes responses to Agent Mesh topics. 82 83 3. **Discovery Flow**: Periodically fetches agent cards from external agents, updates the local registry, and publishes cards to the Agent Mesh discovery topic. 84 85 ## Configuration 86 87 Proxies are configured through YAML files that specify the namespace, downstream agents, authentication, and service settings. 88 89 ### Basic Configuration 90 91 A single proxy can manage multiple external agents. Each agent in the `proxied_agents` list can have its own URL, authentication, and timeout configuration: 92 93 ```yaml 94 app: 95 class_name: solace_agent_mesh.agent.proxies.a2a.app.A2AProxyApp 96 name: my-a2a-proxy 97 app_config: 98 namespace: "myorg/production" 99 proxied_agents: 100 - name: "external-data-agent" 101 url: "https://api.example.com/agent" 102 request_timeout_seconds: 120 103 # Optional: Apply auth to agent card fetching 104 # use_auth_for_agent_card: true 105 # Optional: Use configured URL instead of agent card URL for tasks 106 # use_agent_card_url: false 107 # Optional: Custom headers for agent card fetching 108 # agent_card_headers: 109 # - name: "X-API-Version" 110 # value: "v2" 111 # Optional: Custom headers for task invocations 112 # task_headers: 113 # - name: "X-Tenant-ID" 114 # value: "${TENANT_ID}" 115 - name: "external-analytics-agent" 116 url: "https://analytics.example.com/agent" 117 request_timeout_seconds: 180 118 - name: "external-reporting-agent" 119 url: "https://reports.example.com/agent" 120 artifact_service: 121 type: "filesystem" 122 base_path: "/tmp/proxy-artifacts" 123 discovery_interval_seconds: 60 124 default_request_timeout_seconds: 300 125 126 broker: 127 # Broker configuration inherited from environment or specified here 128 ``` 129 130 ### Configuration Parameters 131 132 - `namespace`: The topic prefix for A2A communication (for example, "myorg/production"). 133 - `proxied_agents`: A list of external agents to proxy. Each agent can have its own URL, authentication, and timeout settings (see Authentication Types below). 134 - `use_auth_for_agent_card`: If true, applies the configured authentication when fetching agent cards. If false (default), agent card requests are made without authentication. 135 - `use_agent_card_url`: If true (default), uses the URL from the agent card for task invocations. If false, uses the configured URL directly for all task invocations. Note: The configured URL is always used to fetch the agent card itself. 136 - `agent_card_headers`: Custom HTTP headers to include when fetching the agent card. These headers are added alongside authentication headers. 137 - `task_headers`: Custom HTTP headers to include when invoking A2A tasks. These headers are added alongside authentication headers. 138 - `convert_progress_updates`: If true (default), converts TextParts in status updates to AgentProgressUpdateData DataParts for consistent UI behavior. If false, preserves original text parts. 139 - `agent_card_data`: Static agent card data embedded directly in configuration. If provided, the proxy uses this data instead of fetching from the agent card endpoint. This allows proxying agents that do not have agent card endpoints. 140 - `artifact_service`: Configuration for storing artifacts. This is shared across all proxied agents. This is configured in the same manner as agents and gateways 141 - `discovery_interval_seconds`: How often to refresh agent cards from all external agents (default: 60). 142 - `default_request_timeout_seconds`: Default timeout for requests to external agents. Individual agents can override this (default: 300). 143 144 ## Authentication Types 145 146 The proxy supports three authentication schemes for connecting to downstream agents. Each agent in the `proxied_agents` list can use a different authentication type, allowing you to integrate agents with varying security requirements in a single proxy instance. 147 148 By default, authentication is only applied to A2A task invocations, not to agent card fetching. You can enable authentication for agent card fetching by setting `use_auth_for_agent_card: true` in the agent configuration. 149 150 ### Static Bearer Token 151 152 Use static bearer tokens for agents that require a fixed authentication token. 153 154 ```yaml 155 proxied_agents: 156 - name: "secure-agent" 157 url: "https://api.example.com/agent" 158 authentication: 159 type: "static_bearer" 160 token: "${AGENT_BEARER_TOKEN}" # Use environment variable 161 # use_auth_for_agent_card: true # Optional: Apply auth to agent card fetching 162 ``` 163 164 ### Static API Key 165 166 Use static API keys for agents that require API key authentication. 167 168 ```yaml 169 proxied_agents: 170 - name: "api-key-agent" 171 url: "https://api.example.com/agent" 172 authentication: 173 type: "static_apikey" 174 token: "${AGENT_API_KEY}" 175 # use_auth_for_agent_card: true # Optional: Apply auth to agent card fetching 176 ``` 177 178 ### OAuth 2.0 Client Credentials 179 180 Use OAuth 2.0 client credentials flow for agents that require dynamic token acquisition. The proxy automatically handles token refresh and retry logic. 181 182 ```yaml 183 proxied_agents: 184 - name: "oauth-agent" 185 url: "https://api.example.com/agent" 186 authentication: 187 type: "oauth2_client_credentials" 188 token_url: "https://auth.example.com/oauth/token" 189 client_id: "${OAUTH_CLIENT_ID}" 190 client_secret: "${OAUTH_CLIENT_SECRET}" 191 scope: "agent.read agent.write" # Optional 192 token_cache_duration_seconds: 3300 # Optional, default: 3300 (55 minutes) 193 # use_auth_for_agent_card: true # Optional: Apply auth to agent card fetching 194 ``` 195 196 The proxy caches OAuth tokens and automatically refreshes them when they expire. If a request receives a 401 Unauthorized response, the proxy invalidates the cached token and retries the request once with a fresh token. 197 198 :::note[Security Best Practice] 199 Always use environment variables for sensitive credentials. Never commit tokens or secrets directly in configuration files. 200 ::: 201 202 ## SSL Certificate Verification 203 204 By default, the proxy verifies SSL certificates when connecting to downstream agents over HTTPS. You can disable certificate verification for specific agents using the `ssl_verify` configuration option. 205 206 ### When to Disable SSL Verification 207 208 Disable SSL verification (`ssl_verify: false`) only in these scenarios: 209 210 - **Development/Testing**: Connecting to agents with self-signed certificates in non-production environments 211 - **Internal Infrastructure**: Agents running on internal networks with private CA certificates not trusted by the system 212 213 :::warning[Security Warning] 214 Disabling SSL verification removes protection against man-in-the-middle attacks. Never disable SSL verification in production environments unless you fully understand the security implications. 215 ::: 216 217 ### Configuration 218 219 ```yaml 220 proxied_agents: 221 - name: "production-agent" 222 url: "https://api.example.com/agent" 223 ssl_verify: true # Default - verify against system CAs 224 225 - name: "dev-agent-self-signed" 226 url: "https://dev.internal.example.com/agent" 227 ssl_verify: false # Disable verification for self-signed certs 228 ``` 229 230 The `ssl_verify` setting applies to both agent card fetching and task invocations for the configured agent. 231 232 ## Custom HTTP Headers 233 234 The proxy supports custom HTTP headers for both agent card fetching and A2A task invocations. This is useful for scenarios like API versioning, tenant identification, custom authentication schemes, or any other header-based requirements. 235 236 ### Header Configuration 237 238 Custom headers are defined as name-value pairs and can be configured separately for agent card fetching (`agent_card_headers`) and task invocations (`task_headers`): 239 240 ```yaml 241 proxied_agents: 242 - name: "custom-header-agent" 243 url: "https://api.example.com/agent" 244 authentication: 245 type: "static_bearer" 246 token: "${AGENT_TOKEN}" 247 agent_card_headers: 248 - name: "X-API-Version" 249 value: "v2" 250 - name: "X-Tenant-ID" 251 value: "${TENANT_ID}" 252 task_headers: 253 - name: "X-API-Version" 254 value: "v2" 255 - name: "X-Request-Priority" 256 value: "high" 257 ``` 258 259 ### Header Precedence Rules 260 261 When both authentication and custom headers are configured: 262 263 1. **Authentication headers take precedence**: The proxy applies authentication headers (like `Authorization` or `X-API-Key`) based on the authentication type configured. These are applied by the A2A SDK's authentication layer after custom headers are set. 264 265 2. **Custom headers are for metadata, not authentication**: Custom headers should be used for non-authentication purposes such as API versioning, tenant identification, or request metadata. They cannot override authentication headers. 266 267 3. **For custom authentication**: If you need custom authentication logic, omit the `authentication` configuration block and use `task_headers` to set your custom authentication header directly. 268 269 ### Use Cases 270 271 **API Versioning**: Specify the API version your integration requires: 272 273 ```yaml 274 agent_card_headers: 275 - name: "X-API-Version" 276 value: "v2" 277 task_headers: 278 - name: "X-API-Version" 279 value: "v2" 280 ``` 281 282 **Tenant Identification**: Pass tenant or organization identifiers: 283 284 ```yaml 285 task_headers: 286 - name: "X-Tenant-ID" 287 value: "${TENANT_ID}" 288 - name: "X-Organization" 289 value: "acme-corp" 290 ``` 291 292 **Custom Authentication**: If you need custom authentication, omit the `authentication` block and use headers directly: 293 294 ```yaml 295 # Note: Do NOT configure the 'authentication' block if using custom auth headers 296 task_headers: 297 - name: "Authorization" 298 value: "Bearer ${CUSTOM_AUTH_TOKEN}" 299 # Or use a custom auth scheme: 300 - name: "X-Custom-Auth" 301 value: "${CUSTOM_AUTH_TOKEN}" 302 ``` 303 304 **Request Metadata**: Add metadata for tracking or routing: 305 306 ```yaml 307 task_headers: 308 - name: "X-Request-Source" 309 value: "agent-mesh" 310 - name: "X-Request-Priority" 311 value: "high" 312 ``` 313 314 ## Artifact Handling 315 316 The proxy manages artifact flow in both directions to ensure seamless integration between Agent Mesh and external agents. 317 318 ### Request Flow: Agent Mesh to External Agent 319 320 When it forwards requests to external agents, the proxy resolves artifact URIs to byte content using the following sequence of operations: 321 322 1. The proxy receives an A2A request containing artifact references (for example, `artifact://app/user/session/data.csv?version=1`). 323 2. The proxy loads the artifact content from Agent Mesh's artifact service. 324 3. The proxy replaces the URI with the actual byte content in the request. 325 4. The proxy forwards the modified request to the external agent. 326 327 This process ensures that external agents receive complete artifact data without needing access to Agent Mesh's artifact service. 328 329 ### Response Flow: External Agent to Agent Mesh 330 331 When it receives responses from external agents, the proxy saves artifacts to Agent Mesh as follows: 332 333 1. The external agent returns artifacts with byte content in the response. 334 2. The proxy saves each artifact to Agent Mesh's artifact service. 335 3. The proxy replaces the byte content with an artifact URI. 336 4. The proxy publishes the modified response to Agent Mesh. 337 338 This process ensures that artifacts are stored centrally and can be accessed by other agents in Agent Mesh. 339 340 ### Artifact Metadata 341 342 The proxy automatically generates metadata for saved artifacts, including: 343 344 - `proxied_from_artifact_id`: The original artifact ID from the external agent 345 - `description`: Extracted from the artifact or generated from context 346 - `produced_artifacts`: A manifest of all artifacts created during task execution 347 348 ## Status Update Conversion 349 350 The proxy can automatically convert text-based status updates from external A2A agents to match the native SAM agent format, ensuring consistent UI behavior across all agents in your mesh. 351 352 ### Conversion Scope 353 354 The `convert_progress_updates` setting only affects intermediate status updates: 355 356 - **Applies to**: `TaskStatusUpdateEvent` messages (streaming progress updates) 357 - **Does not apply to**: Final `Task` responses, artifact content, or other message types 358 359 This means that final responses from external agents remain as text parts, preserving the agent's intended final output format. 360 361 ### When to Disable 362 363 Set `convert_progress_updates: false` if: 364 365 - The external agent sends structured status updates that should be preserved exactly as-is 366 - You have custom UI handling for text-based status updates 367 - You need to preserve original TextParts for debugging or custom processing 368 - The external agent already sends progress updates as DataParts 369 370 Example configuration with conversion disabled: 371 372 ```yaml 373 proxied_agents: 374 - name: "legacy-agent" 375 url: "https://legacy.example.com/agent" 376 convert_progress_updates: false # Preserve original text parts 377 ``` 378 379 When disabled, all status update content passes through unchanged, allowing you to implement custom handling in your gateway or UI layer. 380 381 ## Discovery and Health 382 383 The proxy maintains agent discovery and health monitoring through periodic agent card fetching. 384 385 ### Initial Discovery 386 387 When the proxy starts, it performs synchronous discovery of all configured agents by: 388 389 1. Fetching agent cards from each external agent's `/.well-known/agent-card.json` endpoint. 390 2. Updating the local agent registry with agent capabilities. 391 3. Publishing agent cards to the Agent Mesh discovery topic. 392 393 This process ensures that external agents are immediately discoverable when the proxy starts. 394 395 ### Periodic Refresh 396 397 The proxy periodically refreshes agent cards based on the configured `discovery_interval_seconds`. When the configured interval elapses, the proxy fetches updated agent cards from external agents, updates the local registry with any changes, and then publishes the updated cards to Agent Mesh. This process ensures that Agent Mesh has current information about external agent capabilities and availability. 398 399 ### Agent Card Transformation 400 401 The proxy transforms agent cards to make external agents appear as native Agent Mesh agents: 402 403 - The `name` field is set to the configured alias (the name you specify in `proxied_agents`). 404 - The `url` field is rewritten to use the Solace topic format (for example, `solace:myorg/production/agent/external-data-agent`). 405 406 These agent cards allow other agents to interact with external agents using the standard A2A protocol over Solace event mesh, without knowing they are proxied. 407 408 ### URL Behavior 409 410 The proxy handles URLs in two contexts: 411 412 1. **Agent Card Fetching**: Always uses the configured URL in the `proxied_agents` list to fetch the agent card from the external agent's `/.well-known/agent-card.json` endpoint. 413 414 2. **Task Invocations**: By default, uses the URL specified in the agent card returned by the external agent. This allows external agents to advertise their preferred endpoint (which may differ from the agent card endpoint). You can override this behavior by setting `use_agent_card_url: false` to always use the configured URL for both agent card fetching and task invocations. 415 416 ## Task Lifecycle Management 417 418 The proxy tracks active tasks and manages their lifecycle from initiation to completion. 419 420 ### Task Initiation 421 422 When a request arrives from Agent Mesh, the proxy: 423 424 1. Creates a task context to track the task's state. 425 2. Resolves inbound artifacts. 426 3. Forwards the request to the external agent. 427 4. Begins streaming responses back to Agent Mesh. 428 429 ### Task Cancellation 430 431 When a cancellation request arrives, the proxy: 432 433 1. Looks up the active task context. 434 2. Forwards the cancellation request to the external agent. 435 3. Publishes the cancellation response to Agent Mesh. 436 437 ### Task Completion 438 439 When a task completes, the proxy: 440 441 1. Processes any final artifacts. 442 2. Publishes the final task response to Agent Mesh. 443 3. Removes the task context from active tracking. 444 445 ## Error Handling and Retry Logic 446 447 The proxy implements robust error handling and automatic retry logic for authentication failures. 448 449 ### OAuth 2.0 Automatic Retry 450 451 When using OAuth 2.0 authentication, the proxy automatically handles token expiration using the following sequence: 452 453 1. A request receives a 401 Unauthorized response from the external agent. 454 2. The proxy invalidates the cached token. 455 3. The proxy removes all cached clients for the agent/session. 456 4. The proxy fetches a fresh token from the OAuth provider. 457 5. The proxy retries the request once with the new token. 458 459 This sequence ensures seamless operation even when tokens expire during long-running tasks. 460 461 ### Connection Errors 462 463 The proxy provides clear error messages for connection failures: 464 465 - Connection refused or agent unreachable 466 - Timeout errors with configurable timeout values 467 - JSON-RPC protocol errors from external agents 468 469 ### Error Responses 470 471 When errors occur, the proxy publishes standard A2A error responses to Agent Mesh, including: 472 473 - `InternalError`: For unexpected proxy errors 474 - `InvalidRequestError`: For malformed requests 475 - `TaskNotFoundError`: For cancellation requests on unknown tasks 476 477 ## Creating a Proxy 478 479 Proxies are configured using standard YAML configuration files, similar to agents and gateways. 480 481 ### Creating the Configuration File 482 483 Create a new YAML file in your `configs` directory (for example, `configs/my-proxy.yaml`): 484 485 ```yaml 486 log: 487 stdout_log_level: INFO 488 log_file_level: DEBUG 489 log_file: my-proxy.log 490 491 # Include shared configuration (broker connection, etc.) 492 !include shared_config.yaml 493 494 apps: 495 - name: my_a2a_proxy 496 app_module: solace_agent_mesh.agent.proxies.a2a.app 497 broker: 498 <<: *broker_connection 499 500 app_config: 501 namespace: "${NAMESPACE}" 502 503 artifact_service: 504 type: "filesystem" 505 base_path: "/tmp/proxy-artifacts" 506 artifact_scope: "namespace" 507 508 discovery_interval_seconds: 60 509 default_request_timeout_seconds: 300 510 511 proxied_agents: 512 - name: "external-agent-1" 513 url: "https://api.example.com/agent" 514 request_timeout_seconds: 120 515 authentication: 516 type: "static_bearer" 517 token: "${AGENT_TOKEN}" 518 ``` 519 520 You can use the example file at `examples/a2a_proxy.yaml` as a template. 521 522 ### Running the Proxy 523 524 Run the proxy along with your other Agent Mesh components: 525 526 ```bash 527 sam run 528 ``` 529 530 The proxy automatically subscribes to the appropriate Solace topics and begins proxying requests to external agents. 531 532 ### Multiple Proxy Configurations 533 534 While a single proxy can manage multiple external agents, you may want to create separate proxy configurations to: 535 536 - Organize agents by domain or team 537 - Isolate agents with different security requirements 538 - Distribute load across multiple proxy instances 539 540 ```bash 541 configs/ 542 ├── data-agents-proxy.yaml # Proxies 3 data-related agents 543 ├── analytics-agents-proxy.yaml # Proxies 2 analytics agents 544 └── third-party-agents-proxy.yaml # Proxies external vendor agents 545 ``` 546 547 Run all proxies together: 548 549 ```bash 550 sam run 551 ``` 552 553 Or run specific proxy configurations: 554 555 ```bash 556 sam run configs/data-agents-proxy.yaml 557 ``` 558 559 ## Advanced Configuration 560 561 ### Per-Agent Timeout Override 562 563 You can override the default timeout for specific agents: 564 565 ```yaml 566 proxied_agents: 567 - name: "slow-agent" 568 url: "https://slow.example.com/agent" 569 request_timeout_seconds: 600 # 10 minutes 570 ``` 571 572 ### Custom Headers with Authentication 573 574 Combine authentication with custom headers for complex integration requirements: 575 576 ```yaml 577 proxied_agents: 578 - name: "enterprise-agent" 579 url: "https://enterprise.example.com/agent" 580 authentication: 581 type: "oauth2_client_credentials" 582 token_url: "https://auth.example.com/oauth/token" 583 client_id: "${OAUTH_CLIENT_ID}" 584 client_secret: "${OAUTH_CLIENT_SECRET}" 585 use_auth_for_agent_card: true # Apply OAuth to agent card fetching 586 agent_card_headers: 587 - name: "X-API-Version" 588 value: "v2" 589 - name: "X-Client-Type" 590 value: "agent-mesh" 591 task_headers: 592 - name: "X-API-Version" 593 value: "v2" 594 - name: "X-Tenant-ID" 595 value: "${TENANT_ID}" 596 - name: "X-Request-Priority" 597 value: "high" 598 ``` 599 600 ### URL Override for Task Invocations 601 602 By default, the proxy uses the URL from the agent card for task invocations. This allows external agents to specify their preferred endpoint. However, you can override this behavior by setting `use_agent_card_url: false`: 603 604 ```yaml 605 proxied_agents: 606 - name: "fixed-url-agent" 607 url: "https://api.example.com/agent" 608 use_agent_card_url: false # Always use the configured URL 609 authentication: 610 type: "static_bearer" 611 token: "${AGENT_TOKEN}" 612 ``` 613 614 **Important notes:** 615 616 - The configured URL is always used to fetch the agent card, regardless of this setting 617 - When `use_agent_card_url: false`, all task invocations use the configured URL 618 - When `use_agent_card_url: true` (default), the agent card's URL is used for tasks 619 620 ### Agents Without Agent Card Endpoints 621 622 For external agents that do not expose an agent card endpoint, you can embed the agent card data directly in the configuration using `agent_card_data`: 623 624 ```yaml 625 proxied_agents: 626 - name: "no-card-agent" 627 url: "https://api.example.com/agent" 628 agent_card_data: 629 name: "MyExternalAgent" 630 description: "An external agent without an agent card endpoint" 631 version: "1.0.0" 632 skills: 633 - id: "process_data" 634 name: "process_data" 635 description: "Processes incoming data" 636 defaultInputModes: 637 - "text" 638 defaultOutputModes: 639 - "text" 640 authentication: 641 type: "static_bearer" 642 token: "${AGENT_TOKEN}" 643 ``` 644 645 When `agent_card_data` is provided, the proxy skips fetching from the agent card endpoint and uses the embedded data instead. 646 647 ### Custom Artifact Service Scope 648 649 Configure artifact storage scope for the proxy: 650 651 ```yaml 652 artifact_service: 653 type: "filesystem" 654 base_path: "/data/proxy-artifacts" 655 artifact_scope: "namespace" # Options: namespace, app, custom 656 ``` 657 658 ### Multiple Proxies 659 660 You can run multiple proxy instances to distribute load or isolate different sets of external agents. Each proxy instance can manage multiple agents: 661 662 ```yaml 663 # data-agents-proxy.yaml 664 app: 665 name: data-agents-proxy 666 app_config: 667 proxied_agents: 668 - name: "data-agent-1" 669 url: "https://data1.example.com/agent" 670 - name: "data-agent-2" 671 url: "https://data2.example.com/agent" 672 - name: "data-agent-3" 673 url: "https://data3.example.com/agent" 674 675 # analytics-agents-proxy.yaml 676 app: 677 name: analytics-agents-proxy 678 app_config: 679 proxied_agents: 680 - name: "analytics-agent-1" 681 url: "https://analytics1.example.com/agent" 682 - name: "analytics-agent-2" 683 url: "https://analytics2.example.com/agent" 684 ``` 685 686 ## Troubleshooting 687 688 ### Agent Not Discoverable 689 690 If an external agent does not appear in Agent Mesh: 691 692 1. Check that the agent's URL is accessible from the proxy. 693 2. Verify that the agent exposes `/.well-known/agent-card.json`. 694 3. Check the proxy logs for discovery errors. 695 4. Ensure that `discovery_interval_seconds` is set appropriately and is more frequent than the `health_check_ttl_seconds` that is set on the calling agents and gateways. 696 697 ### Authentication Failures 698 699 If requests fail with 401 errors: 700 701 1. Verify that the credentials are correctly set in environment variables. 702 2. For OAuth 2.0, check that `token_url`, `client_id`, and `client_secret` are correct. 703 3. Ensure that the OAuth token URL uses HTTPS (required for security). 704 4. Check the proxy logs for token acquisition errors. 705 706 ### Timeout Errors 707 708 If requests timeout: 709 710 1. Increase `request_timeout_seconds` for slow agents. 711 2. Check the network connectivity between the proxy and the external agent. 712 3. Verify that the external agent is responding within the timeout period. 713 714 ### Artifact Issues 715 716 If artifacts are not flowing correctly: 717 718 1. Verify that the artifact service is properly configured. 719 2. Check that the proxy has write permissions to the artifact storage location. 720 3. Ensure that the artifact URIs are correctly formatted. 721 4. Check the proxy logs for artifact save/load errors. 722 723 ### Strands SDK Streaming Issues 724 725 If streaming responses from Strands SDK agents appear as status updates instead of chat content, the agent may be using legacy streaming mode. Strands agents require the `enable_a2a_compliant_streaming` option to be enabled on their `A2AServer` instance to properly send streaming content. See the [Strands A2AServer documentation](https://strandsagents.com/latest/documentation/docs/api-reference/python/multiagent/a2a/server/?h=enable_a2a_compliant_streaming#strands.multiagent.a2a.server.A2AServer.__init__) for details. 726 727 ### Issues Running A2A Samples with `Containerfile` 728 729 If you encounter a `ValueError: Invalid context_id: ... is not a valid UUID.` when running A2A samples using a `Containerfile`, it may be due to outdated dependencies in the `uv.lock` file. This can happen if the sample is pinned to an older version of the `a2a-sdk` package. For more details, see [this GitHub issue](https://github.com/a2aproject/a2a-samples/issues/399). 730 731 To resolve this, navigate to the sample's directory and upgrade the dependencies: 732 733 ```bash 734 uv lock --upgrade 735 ``` 736 737 This will update the `uv.lock` file to use the latest version of `a2a-sdk`, which includes the necessary bug fixes.