solace-agent-mesh 1.4.11__py3-none-any.whl → 1.5.0__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 (189) hide show
  1. solace_agent_mesh/agent/adk/adk_llm.txt +3 -4
  2. solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
  3. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
  4. solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +1 -0
  5. solace_agent_mesh/agent/adk/callbacks.py +51 -2
  6. solace_agent_mesh/agent/adk/models/lite_llm.py +1 -0
  7. solace_agent_mesh/agent/adk/models/models_llm.txt +1 -2
  8. solace_agent_mesh/agent/adk/services.py +30 -15
  9. solace_agent_mesh/agent/adk/setup.py +4 -0
  10. solace_agent_mesh/agent/agent_llm.txt +1 -1
  11. solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
  12. solace_agent_mesh/agent/protocol/event_handlers.py +2 -13
  13. solace_agent_mesh/agent/protocol/protocol_llm.txt +15 -2
  14. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
  15. solace_agent_mesh/agent/sac/component.py +51 -21
  16. solace_agent_mesh/agent/sac/sac_llm.txt +15 -1
  17. solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
  18. solace_agent_mesh/agent/sac/task_execution_context.py +73 -0
  19. solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
  20. solace_agent_mesh/agent/tools/tools_llm.txt +148 -154
  21. solace_agent_mesh/agent/tools/tools_llm_detail.txt +274 -0
  22. solace_agent_mesh/agent/utils/utils_llm.txt +1 -1
  23. solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
  24. solace_agent_mesh/assets/docs/404.html +3 -3
  25. solace_agent_mesh/assets/docs/assets/js/0e682baa.d54b8668.js +1 -0
  26. solace_agent_mesh/assets/docs/assets/js/483cef9a.bf9398af.js +1 -0
  27. solace_agent_mesh/assets/docs/assets/js/{main.dc155742.js → main.0c149855.js} +2 -2
  28. solace_agent_mesh/assets/docs/assets/js/{runtime~main.0d2ff2b6.js → runtime~main.c66557e4.js} +1 -1
  29. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +3 -3
  30. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +3 -3
  31. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +8 -4
  32. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
  33. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html +3 -3
  34. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +3 -3
  35. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +3 -3
  36. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +3 -3
  37. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +3 -3
  38. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +3 -3
  39. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +3 -3
  40. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +3 -3
  41. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +3 -3
  42. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +3 -3
  43. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +3 -3
  44. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +3 -3
  45. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +3 -3
  46. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +3 -3
  47. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
  48. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +3 -3
  49. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +3 -3
  50. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +3 -3
  51. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +3 -3
  52. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +7 -4
  53. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +3 -3
  54. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +3 -3
  55. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +3 -3
  56. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +3 -3
  57. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +3 -3
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +3 -3
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +3 -3
  60. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +3 -3
  61. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +3 -3
  62. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +3 -3
  63. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +3 -3
  64. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +3 -3
  65. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +3 -3
  66. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +3 -3
  67. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +3 -3
  68. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +3 -3
  69. solace_agent_mesh/assets/docs/lunr-index-1760032255022.json +1 -0
  70. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  71. solace_agent_mesh/assets/docs/search-doc-1760032255022.json +1 -0
  72. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  73. solace_agent_mesh/cli/__init__.py +1 -1
  74. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-j1LW-wlq.js → authCallback-DwrxZE0E.js} +1 -1
  75. solace_agent_mesh/client/webui/frontend/static/assets/{client-B9p_nFNA.js → client-DarGQzyw.js} +1 -1
  76. solace_agent_mesh/client/webui/frontend/static/assets/main-CZbpmwfA.css +1 -0
  77. solace_agent_mesh/client/webui/frontend/static/assets/main-C__uuUkB.js +339 -0
  78. solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CS5YMf8a.js → vendor-BKIeiHj_.js} +80 -70
  79. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  80. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  81. solace_agent_mesh/common/a2a/a2a_llm.txt +1 -1
  82. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
  83. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +1 -1
  84. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
  85. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +23 -0
  86. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +93 -15
  87. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +23 -0
  88. solace_agent_mesh/common/common_llm.txt +24 -39
  89. solace_agent_mesh/common/common_llm_detail.txt +2562 -0
  90. solace_agent_mesh/common/data_parts.py +9 -1
  91. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
  92. solace_agent_mesh/common/sac/sac_llm.txt +1 -1
  93. solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
  94. solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
  95. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
  96. solace_agent_mesh/common/services/identity_service.py +7 -4
  97. solace_agent_mesh/common/services/providers/local_file_identity_service.py +4 -2
  98. solace_agent_mesh/common/services/services_llm.txt +57 -6
  99. solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
  100. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
  101. solace_agent_mesh/common/utils/utils_llm.txt +75 -87
  102. solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
  103. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
  104. solace_agent_mesh/gateway/base/app.py +1 -1
  105. solace_agent_mesh/gateway/base/base_llm.txt +1 -1
  106. solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
  107. solace_agent_mesh/gateway/base/component.py +1 -1
  108. solace_agent_mesh/gateway/gateway_llm.txt +242 -235
  109. solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
  110. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +295 -0
  111. solace_agent_mesh/gateway/http_sse/alembic/env.py +10 -1
  112. solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
  113. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +155 -0
  114. solace_agent_mesh/gateway/http_sse/alembic.ini +1 -1
  115. solace_agent_mesh/gateway/http_sse/app.py +148 -2
  116. solace_agent_mesh/gateway/http_sse/component.py +368 -60
  117. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +46 -6
  118. solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +108 -0
  119. solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +1 -1
  120. solace_agent_mesh/gateway/http_sse/dependencies.py +116 -26
  121. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +172 -172
  122. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
  123. solace_agent_mesh/gateway/http_sse/main.py +146 -41
  124. solace_agent_mesh/gateway/http_sse/repository/__init__.py +3 -12
  125. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +103 -0
  126. solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +5 -3
  127. solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
  128. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +263 -0
  129. solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
  130. solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -16
  131. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +25 -0
  132. solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
  133. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +81 -0
  134. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +73 -18
  135. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -5
  136. solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
  137. solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
  138. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +266 -0
  139. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +3 -3
  140. solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
  141. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +32 -0
  142. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +340 -0
  143. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +4 -53
  144. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +173 -0
  145. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1 -1
  146. solace_agent_mesh/gateway/http_sse/routers/config.py +26 -4
  147. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +346 -0
  148. solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +3 -3
  149. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +83 -0
  150. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +2 -10
  151. solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
  152. solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +5 -3
  153. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +107 -0
  154. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +1 -15
  155. solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
  156. solace_agent_mesh/gateway/http_sse/routers/feedback.py +37 -0
  157. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +255 -204
  158. solace_agent_mesh/gateway/http_sse/routers/sessions.py +220 -40
  159. solace_agent_mesh/gateway/http_sse/routers/tasks.py +168 -42
  160. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +272 -0
  161. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +241 -0
  162. solace_agent_mesh/gateway/http_sse/services/people_service.py +0 -80
  163. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +177 -13
  164. solace_agent_mesh/gateway/http_sse/services/session_service.py +151 -84
  165. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +317 -0
  166. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +25 -14
  167. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +285 -0
  168. solace_agent_mesh/gateway/http_sse/shared/types.py +7 -0
  169. solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
  170. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +32 -0
  171. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
  172. solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
  173. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
  174. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/METADATA +1 -1
  175. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/RECORD +179 -131
  176. solace_agent_mesh/agent/adk/invocation_monitor.py +0 -295
  177. solace_agent_mesh/assets/docs/assets/js/0e682baa.d054e1d8.js +0 -1
  178. solace_agent_mesh/assets/docs/assets/js/483cef9a.4736f2d8.js +0 -1
  179. solace_agent_mesh/assets/docs/lunr-index-1759514789087.json +0 -1
  180. solace_agent_mesh/assets/docs/search-doc-1759514789087.json +0 -1
  181. solace_agent_mesh/client/webui/frontend/static/assets/main-ChRwcV89.css +0 -1
  182. solace_agent_mesh/client/webui/frontend/static/assets/main-DnnE01OM.js +0 -339
  183. solace_agent_mesh/gateway/http_sse/repository/entities/message.py +0 -41
  184. solace_agent_mesh/gateway/http_sse/repository/message_repository.py +0 -84
  185. solace_agent_mesh/gateway/http_sse/repository/models/message_model.py +0 -45
  186. /solace_agent_mesh/assets/docs/assets/js/{main.dc155742.js.LICENSE.txt → main.0c149855.js.LICENSE.txt} +0 -0
  187. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/WHEEL +0 -0
  188. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/entry_points.txt +0 -0
  189. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,108 @@
1
+ """
2
+ SAC Component to forward messages from an internal BrokerInput
3
+ to the WebUIBackendComponent's internal queue for task logging.
4
+ """
5
+
6
+ import queue
7
+ from typing import Any, Dict
8
+
9
+ from solace_ai_connector.components.component_base import ComponentBase
10
+ from solace_ai_connector.common.message import Message as SolaceMessage
11
+ from solace_ai_connector.common.log import log
12
+
13
+ info = {
14
+ "class_name": "TaskLoggerForwarderComponent",
15
+ "description": (
16
+ "Forwards A2A messages from an internal BrokerInput to the main "
17
+ "WebUIBackendComponent's internal queue for task logging."
18
+ ),
19
+ "config_parameters": [
20
+ {
21
+ "name": "target_queue_ref",
22
+ "required": True,
23
+ "type": "queue.Queue",
24
+ "description": "A direct reference to the target queue.Queue instance in WebUIBackendComponent.",
25
+ }
26
+ ],
27
+ "input_schema": {
28
+ "type": "object",
29
+ "description": "Output from a BrokerInput component.",
30
+ "properties": {
31
+ "payload": {"type": "any", "description": "The message payload."},
32
+ "topic": {"type": "string", "description": "The message topic."},
33
+ "user_properties": {
34
+ "type": "object",
35
+ "description": "User properties of the message.",
36
+ },
37
+ },
38
+ "required": ["payload", "topic"],
39
+ },
40
+ "output_schema": None,
41
+ }
42
+
43
+
44
+ class TaskLoggerForwarderComponent(ComponentBase):
45
+ """
46
+ A simple SAC component that takes messages from its input (typically
47
+ from a BrokerInput) and puts them onto a target Python queue.Queue
48
+ instance provided in its configuration.
49
+ """
50
+
51
+ def __init__(self, **kwargs: Any):
52
+ super().__init__(info, **kwargs)
53
+ self.target_queue: queue.Queue = self.get_config("target_queue_ref")
54
+ if not isinstance(self.target_queue, queue.Queue):
55
+ log.error(
56
+ "%s Configuration 'target_queue_ref' is not a valid queue.Queue instance. Type: %s",
57
+ self.log_identifier,
58
+ type(self.target_queue),
59
+ )
60
+ raise ValueError(
61
+ f"{self.log_identifier} 'target_queue_ref' must be a queue.Queue instance."
62
+ )
63
+ log.info("%s TaskLoggerForwarderComponent initialized.", self.log_identifier)
64
+
65
+ def invoke(self, message: SolaceMessage, data: Dict[str, Any]) -> None:
66
+ """
67
+ Processes the incoming message and forwards it.
68
+
69
+ Args:
70
+ message: The SolaceMessage object from BrokerInput (this is the original message).
71
+ data: The data extracted by BrokerInput's output_schema (payload, topic, user_properties).
72
+ """
73
+ log_id_prefix = f"{self.log_identifier}[Invoke]"
74
+ try:
75
+
76
+ forward_data = {
77
+ "topic": data.get("topic"),
78
+ "payload": data.get("payload"),
79
+ "user_properties": data.get("user_properties") or {},
80
+ "_original_broker_message": message,
81
+ }
82
+ log.debug(
83
+ "%s Forwarding message for topic: %s",
84
+ log_id_prefix,
85
+ forward_data["topic"],
86
+ )
87
+ try:
88
+ self.target_queue.put_nowait(forward_data)
89
+ except queue.Full:
90
+ log.warning(
91
+ "%s Task logging queue is full. Message dropped. Current size: %d",
92
+ log_id_prefix,
93
+ self.target_queue.qsize(),
94
+ )
95
+
96
+ message.call_acknowledgements()
97
+ log.debug("%s Message acknowledged to BrokerInput.", log_id_prefix)
98
+
99
+ except Exception as e:
100
+ log.exception(
101
+ "%s Error in TaskLoggerForwarderComponent invoke: %s",
102
+ log_id_prefix,
103
+ e,
104
+ )
105
+ if message:
106
+ message.call_negative_acknowledgements()
107
+ raise
108
+ return None
@@ -76,7 +76,7 @@ class VisualizationForwarderComponent(ComponentBase):
76
76
  forward_data = {
77
77
  "topic": data.get("topic"),
78
78
  "payload": data.get("payload"),
79
- "user_properties": data.get("user_properties"),
79
+ "user_properties": data.get("user_properties") or {},
80
80
  "_original_broker_message": message,
81
81
  }
82
82
  log.debug(
@@ -20,9 +20,14 @@ from ...gateway.base.task_context import TaskContextManager
20
20
  from ...gateway.http_sse.services.agent_card_service import AgentCardService
21
21
  from ...gateway.http_sse.services.people_service import PeopleService
22
22
  from ...gateway.http_sse.services.task_service import TaskService
23
+ from ...gateway.http_sse.services.feedback_service import FeedbackService
24
+ from ...gateway.http_sse.services.task_logger_service import TaskLoggerService
25
+ from ...gateway.http_sse.services.data_retention_service import DataRetentionService
23
26
  from ...gateway.http_sse.session_manager import SessionManager
24
27
  from ...gateway.http_sse.sse_manager import SSEManager
25
- from .repository import Message, MessageRepository, SessionRepository
28
+ from .repository import SessionRepository
29
+ from .repository.interfaces import ITaskRepository
30
+ from .repository.task_repository import TaskRepository
26
31
  from .services.session_service import SessionService
27
32
 
28
33
  try:
@@ -57,8 +62,20 @@ def init_database(database_url: str):
57
62
  global SessionLocal
58
63
  if SessionLocal is None:
59
64
  engine = create_engine(database_url)
65
+
66
+ # Enable foreign keys for SQLite only (database-agnostic)
67
+ from sqlalchemy import event
68
+
69
+ @event.listens_for(engine, "connect")
70
+ def set_sqlite_pragma(dbapi_conn, connection_record):
71
+ # Only apply to SQLite connections
72
+ if database_url.startswith("sqlite"):
73
+ cursor = dbapi_conn.cursor()
74
+ cursor.execute("PRAGMA foreign_keys=ON")
75
+ cursor.close()
76
+
60
77
  SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
61
- log.info("[Dependencies] Database initialized.")
78
+ log.info("[Dependencies] Database initialized with foreign key support.")
62
79
  else:
63
80
  log.warning("[Dependencies] Database already initialized.")
64
81
 
@@ -199,6 +216,23 @@ def get_identity_service(
199
216
  return component.identity_service
200
217
 
201
218
 
219
+ def get_db() -> Generator[Session, None, None]:
220
+ if SessionLocal is None:
221
+ raise HTTPException(
222
+ status_code=status.HTTP_501_NOT_IMPLEMENTED,
223
+ detail="Session management requires database configuration.",
224
+ )
225
+ db = SessionLocal()
226
+ try:
227
+ yield db
228
+ db.commit()
229
+ except Exception:
230
+ db.rollback()
231
+ raise
232
+ finally:
233
+ db.close()
234
+
235
+
202
236
  def get_people_service(
203
237
  identity_service: BaseIdentityService | None = Depends(get_identity_service),
204
238
  ) -> PeopleService:
@@ -207,6 +241,73 @@ def get_people_service(
207
241
  return PeopleService(identity_service=identity_service)
208
242
 
209
243
 
244
+ def get_task_repository(db: Session = Depends(get_db)) -> ITaskRepository:
245
+ """FastAPI dependency to get an instance of TaskRepository."""
246
+ log.debug("[Dependencies] get_task_repository called")
247
+ return TaskRepository(db)
248
+
249
+
250
+ def get_feedback_service(
251
+ component: "WebUIBackendComponent" = Depends(get_sac_component),
252
+ task_repo: ITaskRepository = Depends(get_task_repository),
253
+ ) -> FeedbackService:
254
+ """FastAPI dependency to get an instance of FeedbackService."""
255
+ log.debug("[Dependencies] get_feedback_service called")
256
+ # The session factory is needed for the existing DB save logic.
257
+ session_factory = SessionLocal if component.database_url else None
258
+ return FeedbackService(
259
+ session_factory=session_factory, component=component, task_repo=task_repo
260
+ )
261
+
262
+
263
+ def get_data_retention_service(
264
+ component: "WebUIBackendComponent" = Depends(get_sac_component),
265
+ ) -> "DataRetentionService | None":
266
+ """
267
+ FastAPI dependency to get the DataRetentionService instance.
268
+
269
+ Returns:
270
+ DataRetentionService instance if database is configured and service is initialized,
271
+ None otherwise.
272
+
273
+ Note:
274
+ This dependency is primarily for future API endpoints that might expose
275
+ data retention statistics or manual cleanup triggers. The service itself
276
+ runs automatically via timer in the component.
277
+ """
278
+ log.debug("[Dependencies] get_data_retention_service called")
279
+
280
+ if not component.database_url:
281
+ log.debug(
282
+ "[Dependencies] Database not configured, returning None for data retention service"
283
+ )
284
+ return None
285
+
286
+ if (
287
+ not hasattr(component, "data_retention_service")
288
+ or component.data_retention_service is None
289
+ ):
290
+ log.warning("[Dependencies] DataRetentionService not initialized on component")
291
+ return None
292
+
293
+ return component.data_retention_service
294
+
295
+
296
+ def get_task_logger_service(
297
+ component: "WebUIBackendComponent" = Depends(get_sac_component),
298
+ ) -> TaskLoggerService:
299
+ """FastAPI dependency to get an instance of TaskLoggerService."""
300
+ log.debug("[Dependencies] get_task_logger_service called")
301
+ task_logger_service = component.get_task_logger_service()
302
+ if task_logger_service is None:
303
+ log.error("[Dependencies] TaskLoggerService is not available.")
304
+ raise HTTPException(
305
+ status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
306
+ detail="Task logging service is not configured or available.",
307
+ )
308
+ return task_logger_service
309
+
310
+
210
311
  PublishFunc = Callable[[str, dict, dict | None], None]
211
312
 
212
313
 
@@ -304,18 +405,22 @@ class ValidatedUserConfig:
304
405
  ) -> dict[str, Any]:
305
406
  user_id = user_config.get("user_profile", {}).get("id")
306
407
 
307
- log.debug(f"[Dependencies] ValidatedUserConfig called for user_id: {user_id} with required scopes: {self.required_scopes}")
408
+ log.debug(
409
+ f"[Dependencies] ValidatedUserConfig called for user_id: {user_id} with required scopes: {self.required_scopes}"
410
+ )
308
411
 
309
412
  # Validate scopes
310
413
  if not config_resolver.is_feature_enabled(
311
- user_config, {"tool_metadata": {"required_scopes": self.required_scopes}}, {}
414
+ user_config,
415
+ {"tool_metadata": {"required_scopes": self.required_scopes}},
416
+ {},
312
417
  ):
313
418
  log.warning(
314
419
  f"[Dependencies] Authorization denied for user '{user_id}'. Required scopes: {self.required_scopes}"
315
420
  )
316
421
  raise HTTPException(
317
422
  status_code=status.HTTP_403_FORBIDDEN,
318
- detail=f"Not authorized. Required scopes: {self.required_scopes}"
423
+ detail=f"Not authorized. Required scopes: {self.required_scopes}",
319
424
  )
320
425
 
321
426
  return user_config
@@ -396,23 +501,6 @@ def get_task_service(
396
501
  )
397
502
 
398
503
 
399
- def get_db() -> Generator[Session, None, None]:
400
- if SessionLocal is None:
401
- raise HTTPException(
402
- status_code=status.HTTP_501_NOT_IMPLEMENTED,
403
- detail="Session management requires database configuration.",
404
- )
405
- db = SessionLocal()
406
- try:
407
- yield db
408
- db.commit()
409
- except Exception:
410
- db.rollback()
411
- raise
412
- finally:
413
- db.close()
414
-
415
-
416
504
  def get_session_business_service(
417
505
  component: "WebUIBackendComponent" = Depends(get_sac_component),
418
506
  ) -> SessionService:
@@ -423,8 +511,6 @@ def get_session_business_service(
423
511
  return SessionService(component=component)
424
512
 
425
513
 
426
-
427
-
428
514
  def get_session_validator(
429
515
  component: "WebUIBackendComponent" = Depends(get_sac_component),
430
516
  ) -> Callable[[str, str], bool]:
@@ -438,7 +524,9 @@ def get_session_validator(
438
524
  db = SessionLocal()
439
525
  try:
440
526
  session_repository = SessionRepository(db)
441
- session_domain = session_repository.find_user_session(session_id, user_id)
527
+ session_domain = session_repository.find_user_session(
528
+ session_id, user_id
529
+ )
442
530
  return session_domain is not None
443
531
  finally:
444
532
  db.close()
@@ -479,6 +567,8 @@ def get_session_business_service_optional(
479
567
  ) -> SessionService | None:
480
568
  """Optional session service dependency that returns None if database is not configured."""
481
569
  if SessionLocal is None:
482
- log.debug("[Dependencies] Database not configured, returning None for session service")
570
+ log.debug(
571
+ "[Dependencies] Database not configured, returning None for session service"
572
+ )
483
573
  return None
484
574
  return SessionService(component=component)