solace-agent-mesh 1.4.12__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.
- solace_agent_mesh/agent/adk/adk_llm.txt +3 -4
- solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
- solace_agent_mesh/agent/adk/callbacks.py +51 -2
- solace_agent_mesh/agent/adk/models/lite_llm.py +1 -0
- solace_agent_mesh/agent/adk/models/models_llm.txt +1 -2
- solace_agent_mesh/agent/agent_llm.txt +1 -1
- solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +2 -13
- solace_agent_mesh/agent/protocol/protocol_llm.txt +15 -2
- solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
- solace_agent_mesh/agent/sac/component.py +51 -21
- solace_agent_mesh/agent/sac/sac_llm.txt +15 -1
- solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
- solace_agent_mesh/agent/sac/task_execution_context.py +73 -0
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
- solace_agent_mesh/agent/tools/tools_llm.txt +148 -154
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +274 -0
- solace_agent_mesh/agent/utils/utils_llm.txt +1 -1
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/483cef9a.bf9398af.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{main.f67fc9f4.js → main.0c149855.js} +2 -2
- solace_agent_mesh/assets/docs/assets/js/{runtime~main.40527046.js → runtime~main.c66557e4.js} +1 -1
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +8 -4
- 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
- solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +3 -3
- solace_agent_mesh/assets/docs/lunr-index-1760032255022.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1760032255022.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-j1LW-wlq.js → authCallback-DwrxZE0E.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-B9p_nFNA.js → client-DarGQzyw.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-CZbpmwfA.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-C__uuUkB.js +339 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CS5YMf8a.js → vendor-BKIeiHj_.js} +80 -70
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
- solace_agent_mesh/common/a2a/a2a_llm.txt +1 -1
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +1 -1
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
- solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +23 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +93 -15
- solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +23 -0
- solace_agent_mesh/common/common_llm.txt +24 -39
- solace_agent_mesh/common/common_llm_detail.txt +2562 -0
- solace_agent_mesh/common/data_parts.py +9 -1
- solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
- solace_agent_mesh/common/sac/sac_llm.txt +1 -1
- solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
- solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
- solace_agent_mesh/common/services/services_llm.txt +57 -6
- solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
- solace_agent_mesh/common/utils/utils_llm.txt +75 -87
- solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
- solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
- solace_agent_mesh/gateway/base/app.py +1 -1
- solace_agent_mesh/gateway/base/base_llm.txt +1 -1
- solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
- solace_agent_mesh/gateway/gateway_llm.txt +242 -235
- solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +295 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +10 -1
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +155 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +1 -1
- solace_agent_mesh/gateway/http_sse/app.py +148 -2
- solace_agent_mesh/gateway/http_sse/component.py +368 -60
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +46 -6
- solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +108 -0
- solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +1 -1
- solace_agent_mesh/gateway/http_sse/dependencies.py +116 -26
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +172 -172
- solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
- solace_agent_mesh/gateway/http_sse/main.py +146 -41
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +3 -12
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +103 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +5 -3
- solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +263 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -16
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +25 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +81 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +73 -18
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -5
- solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
- solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +266 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +3 -3
- solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +32 -0
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +340 -0
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +4 -53
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +173 -0
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/config.py +26 -4
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +346 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +3 -3
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +83 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +2 -10
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +5 -3
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +107 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +1 -15
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +37 -0
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +255 -204
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +220 -40
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +168 -42
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +272 -0
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +241 -0
- solace_agent_mesh/gateway/http_sse/services/people_service.py +0 -80
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +177 -13
- solace_agent_mesh/gateway/http_sse/services/session_service.py +151 -84
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +317 -0
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +25 -14
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +285 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +7 -0
- solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
- solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +32 -0
- solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
- solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
- solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/METADATA +1 -1
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/RECORD +172 -124
- solace_agent_mesh/agent/adk/invocation_monitor.py +0 -295
- solace_agent_mesh/assets/docs/assets/js/483cef9a.4736f2d8.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1759936913198.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1759936913198.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-ChRwcV89.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-DnnE01OM.js +0 -339
- solace_agent_mesh/gateway/http_sse/repository/entities/message.py +0 -41
- solace_agent_mesh/gateway/http_sse/repository/message_repository.py +0 -84
- solace_agent_mesh/gateway/http_sse/repository/models/message_model.py +0 -45
- /solace_agent_mesh/assets/docs/assets/js/{main.f67fc9f4.js.LICENSE.txt → main.0c149855.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.4.12.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
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
570
|
+
log.debug(
|
|
571
|
+
"[Dependencies] Database not configured, returning None for session service"
|
|
572
|
+
)
|
|
483
573
|
return None
|
|
484
574
|
return SessionService(component=component)
|