solace-agent-mesh 1.6.0__py3-none-any.whl → 1.6.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of solace-agent-mesh might be problematic. Click here for more details.

Files changed (127) hide show
  1. solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
  2. solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +1 -1
  3. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +135 -31
  4. solace_agent_mesh/agent/adk/models/lite_llm.py +5 -0
  5. solace_agent_mesh/agent/adk/runner.py +10 -12
  6. solace_agent_mesh/agent/adk/services.py +50 -14
  7. solace_agent_mesh/agent/adk/setup.py +66 -38
  8. solace_agent_mesh/agent/protocol/event_handlers.py +416 -152
  9. solace_agent_mesh/agent/proxies/a2a/app.py +3 -2
  10. solace_agent_mesh/agent/proxies/base/app.py +3 -2
  11. solace_agent_mesh/agent/proxies/base/component.py +35 -4
  12. solace_agent_mesh/agent/sac/app.py +97 -9
  13. solace_agent_mesh/agent/sac/component.py +284 -145
  14. solace_agent_mesh/agent/sac/task_execution_context.py +79 -2
  15. solace_agent_mesh/agent/tools/tool_config_types.py +3 -0
  16. solace_agent_mesh/agent/utils/artifact_helpers.py +1 -1
  17. solace_agent_mesh/assets/docs/404.html +3 -3
  18. solace_agent_mesh/assets/docs/assets/js/240a0364.c39f8388.js +1 -0
  19. solace_agent_mesh/assets/docs/assets/js/631738c7.7c4594c9.js +1 -0
  20. solace_agent_mesh/assets/docs/assets/js/66d4869e.830d443f.js +1 -0
  21. solace_agent_mesh/assets/docs/assets/js/71da7b71.ddbdfbe2.js +1 -0
  22. solace_agent_mesh/assets/docs/assets/js/{e3d9abda.2b916f9e.js → e3d9abda.6b9493d0.js} +1 -1
  23. solace_agent_mesh/assets/docs/assets/js/e92d0134.4f395c6b.js +1 -0
  24. solace_agent_mesh/assets/docs/assets/js/f284c35a.720d2ef2.js +1 -0
  25. solace_agent_mesh/assets/docs/assets/js/main.d1643f0b.js +2 -0
  26. solace_agent_mesh/assets/docs/assets/js/runtime~main.97f920d4.js +1 -0
  27. solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +3 -3
  28. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +3 -3
  29. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +3 -3
  30. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +3 -3
  31. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +3 -3
  32. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +3 -3
  33. solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +3 -3
  34. solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +3 -3
  35. solace_agent_mesh/assets/docs/docs/documentation/components/index.html +3 -3
  36. solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +3 -3
  37. solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +3 -3
  38. solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +3 -3
  39. solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +4 -25
  40. solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +4 -4
  41. solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +4 -4
  42. solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +76 -0
  43. solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +5 -4
  44. solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +3 -3
  45. solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +3 -3
  46. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +3 -3
  47. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +3 -3
  48. solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +3 -3
  49. solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +3 -3
  50. solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +3 -3
  51. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +3 -3
  52. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +3 -3
  53. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +3 -3
  54. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +3 -3
  55. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +3 -3
  56. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +3 -3
  57. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +3 -3
  58. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +3 -3
  59. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +3 -3
  60. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +3 -3
  61. solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +3 -3
  62. solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +3 -3
  63. solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +3 -3
  64. solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +3 -3
  65. solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +3 -3
  66. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
  67. solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +3 -3
  68. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +3 -6
  69. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +3 -3
  70. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +3 -3
  71. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +3 -3
  72. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +3 -3
  73. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
  74. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +3 -3
  75. solace_agent_mesh/assets/docs/lunr-index-1761663789856.json +1 -0
  76. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  77. solace_agent_mesh/assets/docs/search-doc-1761663789856.json +1 -0
  78. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  79. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  80. solace_agent_mesh/cli/__init__.py +1 -1
  81. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-BTf6dqwp.js → authCallback-D4_RMYRh.js} +1 -1
  82. solace_agent_mesh/client/webui/frontend/static/assets/{client-CaY59VuC.js → client-UZ3qU6Bq.js} +1 -1
  83. solace_agent_mesh/client/webui/frontend/static/assets/main--3yJYl7S.css +1 -0
  84. solace_agent_mesh/client/webui/frontend/static/assets/main-DojKHS49.js +342 -0
  85. solace_agent_mesh/client/webui/frontend/static/assets/{vendor-BEmvJSYz.js → vendor-DSqhjwq_.js} +1 -1
  86. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  87. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  88. solace_agent_mesh/common/a2a/events.py +2 -1
  89. solace_agent_mesh/common/a2a/protocol.py +78 -0
  90. solace_agent_mesh/common/sac/sam_component_base.py +406 -21
  91. solace_agent_mesh/common/utils/pydantic_utils.py +90 -3
  92. solace_agent_mesh/gateway/base/app.py +15 -0
  93. solace_agent_mesh/gateway/base/component.py +116 -46
  94. solace_agent_mesh/gateway/http_sse/app.py +7 -0
  95. solace_agent_mesh/gateway/http_sse/component.py +18 -10
  96. solace_agent_mesh/gateway/http_sse/dependencies.py +83 -59
  97. solace_agent_mesh/gateway/http_sse/main.py +5 -4
  98. solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +1 -1
  99. solace_agent_mesh/gateway/http_sse/routers/auth.py +103 -6
  100. solace_agent_mesh/gateway/http_sse/routers/config.py +1 -1
  101. solace_agent_mesh/gateway/http_sse/routers/sessions.py +1 -1
  102. solace_agent_mesh/gateway/http_sse/routers/sse.py +15 -5
  103. solace_agent_mesh/gateway/http_sse/routers/tasks.py +3 -3
  104. solace_agent_mesh/gateway/http_sse/routers/users.py +47 -1
  105. solace_agent_mesh/gateway/http_sse/routers/visualization.py +90 -8
  106. solace_agent_mesh/gateway/http_sse/services/session_service.py +1 -1
  107. solace_agent_mesh/gateway/http_sse/session_manager.py +15 -15
  108. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +16 -1
  109. solace_agent_mesh/gateway/http_sse/sse_manager.py +15 -6
  110. solace_agent_mesh/templates/logging_config_template.ini +2 -2
  111. {solace_agent_mesh-1.6.0.dist-info → solace_agent_mesh-1.6.2.dist-info}/METADATA +2 -2
  112. {solace_agent_mesh-1.6.0.dist-info → solace_agent_mesh-1.6.2.dist-info}/RECORD +116 -114
  113. solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +0 -1
  114. solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +0 -1
  115. solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +0 -1
  116. solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +0 -1
  117. solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +0 -1
  118. solace_agent_mesh/assets/docs/assets/js/main.20feee82.js +0 -2
  119. solace_agent_mesh/assets/docs/assets/js/runtime~main.0d198646.js +0 -1
  120. solace_agent_mesh/assets/docs/lunr-index-1761165361160.json +0 -1
  121. solace_agent_mesh/assets/docs/search-doc-1761165361160.json +0 -1
  122. solace_agent_mesh/client/webui/frontend/static/assets/main-BGTaW0uv.js +0 -342
  123. solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +0 -1
  124. /solace_agent_mesh/assets/docs/assets/js/{main.20feee82.js.LICENSE.txt → main.d1643f0b.js.LICENSE.txt} +0 -0
  125. {solace_agent_mesh-1.6.0.dist-info → solace_agent_mesh-1.6.2.dist-info}/WHEEL +0 -0
  126. {solace_agent_mesh-1.6.0.dist-info → solace_agent_mesh-1.6.2.dist-info}/entry_points.txt +0 -0
  127. {solace_agent_mesh-1.6.0.dist-info → solace_agent_mesh-1.6.2.dist-info}/licenses/LICENSE +0 -0
@@ -43,8 +43,9 @@ class A2AProxyApp(BaseProxyApp):
43
43
  app_info["app_config"] = app_config
44
44
  log.debug("A2A proxy configuration validated successfully.")
45
45
  except ValidationError as e:
46
- log.error("A2A proxy configuration validation failed:\n%s", e)
47
- raise ValueError(f"Invalid A2A proxy configuration: {e}") from e
46
+ message = A2AProxyAppConfig.format_validation_error_message(e, app_info['name'])
47
+ log.error("Invalid A2A Proxy configuration:\n%s", message)
48
+ raise
48
49
 
49
50
  super().__init__(app_info, **kwargs)
50
51
 
@@ -43,8 +43,9 @@ class BaseProxyApp(App, ABC):
43
43
  # Overwrite the raw dict with the validated object for downstream use
44
44
  app_info["app_config"] = app_config
45
45
  except ValidationError as e:
46
- log.error("Proxy configuration validation failed:\n%s", e)
47
- raise ValueError(f"Invalid proxy configuration: {e}") from e
46
+ message = BaseProxyAppConfig.format_validation_error_message(e, app_info['name'])
47
+ log.error("Invalid Proxy configuration:\n%s", message)
48
+ raise
48
49
 
49
50
  namespace = app_config.get("namespace")
50
51
  proxied_agents = app_config.get("proxied_agents", [])
@@ -140,12 +140,23 @@ class BaseProxyComponent(ComponentBase, ABC):
140
140
  future = asyncio.run_coroutine_threadsafe(
141
141
  self._process_event_async(event), self._async_loop
142
142
  )
143
- future.add_done_callback(self._handle_scheduled_task_completion)
143
+ # Pass the event to the completion handler so it can NACK on failure
144
+ future.add_done_callback(
145
+ lambda f: self._handle_scheduled_task_completion(f, event)
146
+ )
144
147
 
145
148
  async def _process_event_async(self, event: Event):
146
149
  """Asynchronous event processing logic."""
147
150
  if event.event_type == EventType.MESSAGE:
148
- await self._handle_a2a_request(event.data)
151
+ message_handled = False
152
+ try:
153
+ await self._handle_a2a_request(event.data)
154
+ message_handled = True
155
+ finally:
156
+ # Mark that we attempted to handle the message
157
+ # (success/failure ack/nack is done inside _handle_a2a_request)
158
+ if not hasattr(event, "_proxy_message_handled"):
159
+ event._proxy_message_handled = message_handled
149
160
  elif event.event_type == EventType.TIMER:
150
161
  if event.data.get("timer_id") == self._discovery_timer_id:
151
162
  await self._discover_and_publish_agents()
@@ -510,8 +521,10 @@ class BaseProxyComponent(ComponentBase, ABC):
510
521
  self._async_init_future.set_exception, e
511
522
  )
512
523
 
513
- def _handle_scheduled_task_completion(self, future: concurrent.futures.Future):
514
- """Callback to log exceptions from tasks scheduled on the async loop."""
524
+ def _handle_scheduled_task_completion(
525
+ self, future: concurrent.futures.Future, event: Event
526
+ ):
527
+ """Callback to log exceptions from tasks scheduled on the async loop and NACK messages on failure."""
515
528
  if future.done() and future.exception():
516
529
  log.error(
517
530
  "%s Coroutine scheduled on async loop failed: %s",
@@ -519,6 +532,24 @@ class BaseProxyComponent(ComponentBase, ABC):
519
532
  future.exception(),
520
533
  exc_info=future.exception(),
521
534
  )
535
+ # NACK the message if this was a MESSAGE event that failed before being handled
536
+ # The _proxy_message_handled flag is set in _process_event_async to track
537
+ # whether _handle_a2a_request was entered (where ack/nack is normally done)
538
+ if event.event_type == EventType.MESSAGE:
539
+ message_handled = getattr(event, "_proxy_message_handled", False)
540
+ if not message_handled:
541
+ try:
542
+ event.data.call_negative_acknowledgements()
543
+ log.warning(
544
+ "%s NACKed message due to async processing failure before entering request handler.",
545
+ self.log_identifier,
546
+ )
547
+ except Exception as nack_e:
548
+ log.error(
549
+ "%s Failed to NACK message after async processing failure: %s",
550
+ self.log_identifier,
551
+ nack_e,
552
+ )
522
553
 
523
554
  def _publish_discovered_cards(self):
524
555
  """Publishes all agent cards currently in the registry."""
@@ -23,7 +23,13 @@ from ...common.a2a import (
23
23
  get_agent_status_subscription_topic,
24
24
  get_sam_events_subscription_topic,
25
25
  )
26
- from ...common.constants import DEFAULT_COMMUNICATION_TIMEOUT, TEXT_ARTIFACT_CONTEXT_MAX_LENGTH_CAPACITY, TEXT_ARTIFACT_CONTEXT_DEFAULT_LENGTH, HEALTH_CHECK_TTL_SECONDS, HEALTH_CHECK_INTERVAL_SECONDS
26
+ from ...common.constants import (
27
+ DEFAULT_COMMUNICATION_TIMEOUT,
28
+ TEXT_ARTIFACT_CONTEXT_MAX_LENGTH_CAPACITY,
29
+ TEXT_ARTIFACT_CONTEXT_DEFAULT_LENGTH,
30
+ HEALTH_CHECK_TTL_SECONDS,
31
+ HEALTH_CHECK_INTERVAL_SECONDS,
32
+ )
27
33
  from ...agent.sac.component import SamAgentComponent
28
34
  from ...agent.utils.artifact_helpers import DEFAULT_SCHEMA_MAX_KEYS
29
35
  from ...common.utils.pydantic_utils import SamConfigBase
@@ -31,6 +37,14 @@ from ..tools.tool_config_types import AnyToolConfig
31
37
 
32
38
  log = logging.getLogger(__name__)
33
39
 
40
+ # Try to import TrustManagerConfig from enterprise repo
41
+ try:
42
+ from solace_agent_mesh_enterprise.common.trust.config import TrustManagerConfig
43
+
44
+ except ImportError:
45
+ # Enterprise features not available - create a placeholder type
46
+ TrustManagerConfig = Dict[str, Any] # type: ignore
47
+
34
48
  info = {
35
49
  "class_name": "SamAgentApp",
36
50
  "description": "Custom App class for SAM Agent Host with namespace prefixing and automatic subscription generation.",
@@ -80,10 +94,12 @@ class AgentDiscoveryConfig(SamConfigBase):
80
94
  default=True, description="Enable discovery and instruction injection."
81
95
  )
82
96
  health_check_ttl_seconds: int = Field(
83
- default=HEALTH_CHECK_TTL_SECONDS, description="Time-to-live in seconds after which an unresponsive agent is de-registered."
97
+ default=HEALTH_CHECK_TTL_SECONDS,
98
+ description="Time-to-live in seconds after which an unresponsive agent is de-registered.",
84
99
  )
85
100
  health_check_interval_seconds: int = Field(
86
- default=HEALTH_CHECK_INTERVAL_SECONDS, description="Interval in seconds between health checks."
101
+ default=HEALTH_CHECK_INTERVAL_SECONDS,
102
+ description="Interval in seconds between health checks.",
87
103
  )
88
104
 
89
105
 
@@ -214,11 +230,39 @@ class ArtifactServiceConfig(SamConfigBase):
214
230
  )
215
231
  return self
216
232
 
233
+ class AgentIdentityConfig(SamConfigBase):
234
+ """Configuration for agent identity and key management."""
235
+ key_mode: Literal["auto", "manual"] = Field(
236
+ default="auto",
237
+ description="Key mode for agent identity: 'auto' for automatic generation, 'manual' for user-provided."
238
+ )
239
+ key_identity: Optional[str] = Field(
240
+ default=None,
241
+ description="Actual key value when key_mode is 'manual'."
242
+ )
243
+ key_persistence: Optional[str] = Field(
244
+ default=None,
245
+ description="Path to the key file, e.g. '/path/to/keys/agent_{name}.key'."
246
+ )
247
+
248
+ @model_validator(mode="after")
249
+ def check_key_mode_and_identity(self) -> "AgentIdentityConfig":
250
+ if self.key_mode == "manual" and not self.key_identity:
251
+ raise ValueError(
252
+ "'key_identity' is required when 'key_mode' is 'manual'."
253
+ )
254
+ if self.key_mode == "auto" and self.key_identity:
255
+ log.warning(
256
+ "Configuration Warning: 'key_identity' is ignored when 'key_mode' is 'auto'."
257
+ )
258
+ return self
217
259
 
218
260
  class SessionServiceConfig(SamConfigBase):
219
261
  """Configuration for the ADK Session Service."""
220
262
 
221
- type: str = Field(..., description="Service type (e.g., 'memory', 'sql', 'vertex_rag').")
263
+ type: str = Field(
264
+ ..., description="Service type (e.g., 'memory', 'sql', 'vertex_rag')."
265
+ )
222
266
  default_behavior: Literal["PERSISTENT", "RUN_BASED"] = Field(
223
267
  default="PERSISTENT", description="Default behavior for session service."
224
268
  )
@@ -227,6 +271,12 @@ class SessionServiceConfig(SamConfigBase):
227
271
  )
228
272
 
229
273
 
274
+ class CredentialServiceConfig(SamConfigBase):
275
+ """Configuration for the ADK Credential Service."""
276
+
277
+ type: str = Field(..., description="Service type (e.g., 'memory').")
278
+
279
+
230
280
  class SamAgentAppConfig(SamConfigBase):
231
281
  """Pydantic model for the complete agent application configuration."""
232
282
 
@@ -235,10 +285,25 @@ class SamAgentAppConfig(SamConfigBase):
235
285
  description="Absolute topic prefix for A2A communication (e.g., 'myorg/dev').",
236
286
  )
237
287
  agent_name: str = Field(..., description="Unique name for this ADK agent instance.")
238
- display_name: str = Field(default=None, description="Human-friendly display name for this ADK agent instance.")
288
+ display_name: str = Field(
289
+ default=None,
290
+ description="Human-friendly display name for this ADK agent instance.",
291
+ )
292
+ deployment: Optional[Dict[str, Any]] = Field(
293
+ default=None,
294
+ description="Deployment tracking information for rolling updates and version control.",
295
+ )
239
296
  model: Union[str, Dict[str, Any]] = Field(
240
297
  ..., description="ADK model name (string) or BaseLlm config dict."
241
298
  )
299
+ agent_identity: Optional[AgentIdentityConfig] = Field(
300
+ default_factory=lambda: AgentIdentityConfig(key_mode="auto"),
301
+ description="Configuration for agent identity and key management."
302
+ )
303
+ trust_manager: Optional[Union[TrustManagerConfig, Dict[str, Any]]] = Field(
304
+ default=None,
305
+ description="Configuration for the Trust Manager (enterprise feature)",
306
+ )
242
307
  instruction: Any = Field(
243
308
  default="",
244
309
  description="User-provided instructions for the ADK agent (string or invoke block).",
@@ -277,6 +342,10 @@ class SamAgentAppConfig(SamConfigBase):
277
342
  default={"type": "memory"},
278
343
  description="Configuration for ADK Memory Service (defaults to memory).",
279
344
  )
345
+ credential_service: Optional[CredentialServiceConfig] = Field(
346
+ default=None,
347
+ description="Configuration for ADK Credential Service (optional).",
348
+ )
280
349
  multi_session_request_response: Dict[str, Any] = Field(
281
350
  default_factory=lambda: {"enabled": True},
282
351
  description="Enables multi-session request/response capabilities for the agent, required for peer delegation.",
@@ -407,8 +476,9 @@ class SamAgentApp(App):
407
476
  # Overwrite the raw dict with the validated object for downstream use
408
477
  app_info["app_config"] = app_config
409
478
  except ValidationError as e:
410
- log.error("Agent configuration validation failed:\n%s", e)
411
- raise ValueError(f"Invalid agent configuration: {e}") from e
479
+ message = SamAgentAppConfig.format_validation_error_message(e, app_info['name'], app_config_dict.get('agent_name'))
480
+ log.error("Invalid Agent configuration:\n%s", message)
481
+ raise
412
482
 
413
483
  # The rest of the method can now safely use .get() on the app_config object,
414
484
  # ensuring full backward compatibility.
@@ -429,6 +499,20 @@ class SamAgentApp(App):
429
499
  get_agent_status_subscription_topic(namespace, agent_name),
430
500
  get_sam_events_subscription_topic(namespace, "session"),
431
501
  ]
502
+
503
+ # Add trust card subscription if trust manager is enabled
504
+ trust_config = app_config.get("trust_manager")
505
+ if trust_config and trust_config.get("enabled", False):
506
+ from ...common.a2a.protocol import get_trust_card_subscription_topic
507
+
508
+ trust_card_topic = get_trust_card_subscription_topic(namespace)
509
+ required_topics.append(trust_card_topic)
510
+ log.info(
511
+ "Trust Manager enabled for agent '%s', added trust card subscription: %s",
512
+ agent_name,
513
+ trust_card_topic,
514
+ )
515
+
432
516
  generated_subs = [{"topic": topic} for topic in required_topics]
433
517
  log.info(
434
518
  "Automatically generated subscriptions for Agent '%s': %s",
@@ -458,8 +542,12 @@ class SamAgentApp(App):
458
542
  broker_config["queue_name"] = generated_queue_name
459
543
  log.debug("Injected generated broker.queue_name: %s", generated_queue_name)
460
544
 
461
- broker_config["temporary_queue"] = app_info.get("broker", {}).get("temporary_queue", True)
462
- log.debug("Set broker_config.temporary_queue = %s", broker_config["temporary_queue"])
545
+ broker_config["temporary_queue"] = app_info.get("broker", {}).get(
546
+ "temporary_queue", True
547
+ )
548
+ log.debug(
549
+ "Set broker_config.temporary_queue = %s", broker_config["temporary_queue"]
550
+ )
463
551
 
464
552
  super().__init__(app_info, **kwargs)
465
553
  log.debug("%s Agent initialization complete.", agent_name)