solace-agent-mesh 1.1.0__py3-none-any.whl → 1.3.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/runner.py +18 -12
- solace_agent_mesh/agent/adk/services.py +3 -3
- solace_agent_mesh/agent/protocol/event_handlers.py +27 -21
- solace_agent_mesh/agent/sac/app.py +1 -1
- solace_agent_mesh/agent/sac/component.py +0 -1
- solace_agent_mesh/assets/docs/404.html +2 -2
- solace_agent_mesh/assets/docs/assets/js/{main.a75ecc0d.js → main.08d30374.js} +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +2 -2
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +2 -2
- solace_agent_mesh/assets/docs/lunr-index-1757433031159.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1757433031159.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +125 -48
- solace_agent_mesh/cli/commands/eval_cmd.py +14 -0
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +53 -31
- solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +19 -8
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +80 -25
- solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +32 -10
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +74 -15
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +0 -2
- solace_agent_mesh/cli/commands/run_cmd.py +5 -3
- solace_agent_mesh/cli/utils.py +68 -12
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-vY5eu2lI.js +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/client-BeBkzgWW.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-Bjys1KQs.js +339 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-C03yrETa.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CE0AeXyK.js +395 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -2
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -3
- solace_agent_mesh/common/utils/embeds/resolver.py +1 -0
- solace_agent_mesh/config_portal/backend/common.py +2 -2
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-bFMKlzKf.js +98 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d845808d.js → manifest-89db7c30.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/evaluation/message_organizer.py +35 -56
- solace_agent_mesh/evaluation/run.py +26 -5
- solace_agent_mesh/evaluation/subscriber.py +35 -10
- solace_agent_mesh/evaluation/summary_builder.py +27 -34
- solace_agent_mesh/gateway/http_sse/ARCHITECTURE_GUIDE.md +676 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +85 -0
- solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/b1c2d3e4f5g6_add_database_indexes.py +83 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/d5b3f8f2e9a0_create_initial_database.py +58 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +147 -0
- solace_agent_mesh/gateway/http_sse/api/__init__.py +11 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/__init__.py +9 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/session_controller.py +355 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/task_controller.py +279 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/user_controller.py +35 -0
- solace_agent_mesh/gateway/http_sse/api/dto/__init__.py +10 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/__init__.py +37 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/session_requests.py +49 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/task_requests.py +66 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/__init__.py +43 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/session_responses.py +68 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/task_responses.py +74 -0
- solace_agent_mesh/gateway/http_sse/app.py +31 -1
- solace_agent_mesh/gateway/http_sse/application/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/application/services/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/application/services/session_service.py +135 -0
- solace_agent_mesh/gateway/http_sse/component.py +224 -62
- solace_agent_mesh/gateway/http_sse/dependencies.py +142 -39
- solace_agent_mesh/gateway/http_sse/domain/entities/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/domain/entities/session.py +90 -0
- solace_agent_mesh/gateway/http_sse/domain/repositories/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/domain/repositories/session_repository.py +54 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/container.py +123 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_persistence_service.py +16 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_service.py +119 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/models.py +31 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence_service.py +12 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/repositories/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/repositories/session_repository.py +174 -0
- solace_agent_mesh/gateway/http_sse/main.py +289 -85
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +121 -54
- solace_agent_mesh/gateway/http_sse/routers/config.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +83 -2
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +7 -7
- solace_agent_mesh/gateway/http_sse/session_manager.py +64 -30
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +9 -0
- solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
- solace_agent_mesh/gateway/http_sse/shared/enums.py +45 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +45 -0
- solace_agent_mesh/templates/shared_config.yaml +4 -5
- solace_agent_mesh/templates/webui.yaml +8 -10
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.0.dist-info}/METADATA +5 -3
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.0.dist-info}/RECORD +130 -91
- solace_agent_mesh/assets/docs/lunr-index-1756992446316.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1756992446316.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-BmF2l6vg.js +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/client-D881Dttc.js +0 -49
- solace_agent_mesh/client/webui/frontend/static/assets/main-C0jZjYa8.js +0 -699
- solace_agent_mesh/client/webui/frontend/static/assets/main-CCeG324-.css +0 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-Bym6YkMd.js +0 -98
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +0 -85
- solace_agent_mesh/gateway/http_sse/routers/users.py +0 -59
- /solace_agent_mesh/assets/docs/assets/js/{main.a75ecc0d.js.LICENSE.txt → main.08d30374.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.0.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Request DTOs for API endpoints.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .session_requests import (
|
|
6
|
+
GetSessionsRequest,
|
|
7
|
+
GetSessionRequest,
|
|
8
|
+
GetSessionHistoryRequest,
|
|
9
|
+
UpdateSessionRequest,
|
|
10
|
+
DeleteSessionRequest,
|
|
11
|
+
CreateSessionRequest,
|
|
12
|
+
)
|
|
13
|
+
from .task_requests import (
|
|
14
|
+
SendTaskRequest,
|
|
15
|
+
SubscribeTaskRequest,
|
|
16
|
+
CancelTaskRequest,
|
|
17
|
+
GetTaskStatusRequest,
|
|
18
|
+
TaskFilesInfo,
|
|
19
|
+
ProcessedTaskRequest,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
# Session requests
|
|
24
|
+
"GetSessionsRequest",
|
|
25
|
+
"GetSessionRequest",
|
|
26
|
+
"GetSessionHistoryRequest",
|
|
27
|
+
"UpdateSessionRequest",
|
|
28
|
+
"DeleteSessionRequest",
|
|
29
|
+
"CreateSessionRequest",
|
|
30
|
+
# Task requests
|
|
31
|
+
"SendTaskRequest",
|
|
32
|
+
"SubscribeTaskRequest",
|
|
33
|
+
"CancelTaskRequest",
|
|
34
|
+
"GetTaskStatusRequest",
|
|
35
|
+
"TaskFilesInfo",
|
|
36
|
+
"ProcessedTaskRequest",
|
|
37
|
+
]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Session-related request DTOs.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, List
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from ....shared.types import SessionId, UserId, SortInfo, FilterInfo, PaginationInfo
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GetSessionsRequest(BaseModel):
|
|
12
|
+
"""Request DTO for retrieving sessions."""
|
|
13
|
+
user_id: UserId
|
|
14
|
+
pagination: Optional[PaginationInfo] = None
|
|
15
|
+
sort: Optional[SortInfo] = None
|
|
16
|
+
filters: Optional[List[FilterInfo]] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GetSessionRequest(BaseModel):
|
|
20
|
+
"""Request DTO for retrieving a specific session."""
|
|
21
|
+
session_id: SessionId
|
|
22
|
+
user_id: UserId
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class GetSessionHistoryRequest(BaseModel):
|
|
26
|
+
"""Request DTO for retrieving session message history."""
|
|
27
|
+
session_id: SessionId
|
|
28
|
+
user_id: UserId
|
|
29
|
+
pagination: Optional[PaginationInfo] = None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class UpdateSessionRequest(BaseModel):
|
|
33
|
+
"""Request DTO for updating session details."""
|
|
34
|
+
session_id: SessionId
|
|
35
|
+
user_id: UserId
|
|
36
|
+
name: str = Field(..., min_length=1, max_length=255, description="New session name")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class DeleteSessionRequest(BaseModel):
|
|
40
|
+
"""Request DTO for deleting a session."""
|
|
41
|
+
session_id: SessionId
|
|
42
|
+
user_id: UserId
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class CreateSessionRequest(BaseModel):
|
|
46
|
+
"""Request DTO for creating a new session."""
|
|
47
|
+
user_id: UserId
|
|
48
|
+
name: Optional[str] = Field(None, max_length=255, description="Session name")
|
|
49
|
+
agent_id: Optional[str] = Field(None, description="Associated agent ID")
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task-related request DTOs.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import List, Optional, Dict, Any
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
from fastapi import UploadFile
|
|
8
|
+
|
|
9
|
+
from ....shared.types import TaskId, UserId, SessionId, AgentId
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SendTaskRequest(BaseModel):
|
|
13
|
+
"""Request DTO for sending a non-streaming task."""
|
|
14
|
+
agent_name: str = Field(..., description="The name of the target A2A agent")
|
|
15
|
+
message: str = Field(..., description="The user's message or prompt")
|
|
16
|
+
user_id: UserId
|
|
17
|
+
client_id: Optional[str] = None
|
|
18
|
+
session_id: Optional[SessionId] = None
|
|
19
|
+
|
|
20
|
+
class Config:
|
|
21
|
+
# UploadFile cannot be included in Pydantic models directly
|
|
22
|
+
# Files will be handled separately in the controller
|
|
23
|
+
arbitrary_types_allowed = True
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SubscribeTaskRequest(BaseModel):
|
|
27
|
+
"""Request DTO for sending a streaming task."""
|
|
28
|
+
agent_name: str = Field(..., description="The name of the target A2A agent")
|
|
29
|
+
message: str = Field(..., description="The user's message or prompt")
|
|
30
|
+
user_id: UserId
|
|
31
|
+
session_id: Optional[SessionId] = None
|
|
32
|
+
client_id: Optional[str] = None
|
|
33
|
+
|
|
34
|
+
class Config:
|
|
35
|
+
arbitrary_types_allowed = True
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CancelTaskRequest(BaseModel):
|
|
39
|
+
"""Request DTO for cancelling a task."""
|
|
40
|
+
task_id: TaskId = Field(..., description="The ID of the task to cancel")
|
|
41
|
+
client_id: Optional[str] = None
|
|
42
|
+
user_id: UserId
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class GetTaskStatusRequest(BaseModel):
|
|
46
|
+
"""Request DTO for getting task status."""
|
|
47
|
+
task_id: TaskId
|
|
48
|
+
user_id: UserId
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class TaskFilesInfo(BaseModel):
|
|
52
|
+
"""Information about uploaded files for a task."""
|
|
53
|
+
filename: str
|
|
54
|
+
content_type: str
|
|
55
|
+
size: int
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ProcessedTaskRequest(BaseModel):
|
|
59
|
+
"""Internal DTO for processed task request with file information."""
|
|
60
|
+
agent_name: str
|
|
61
|
+
message: str
|
|
62
|
+
user_id: UserId
|
|
63
|
+
session_id: Optional[SessionId] = None
|
|
64
|
+
client_id: Optional[str] = None
|
|
65
|
+
files: List[TaskFilesInfo] = []
|
|
66
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Response DTOs for API endpoints.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .session_responses import (
|
|
6
|
+
MessageResponse,
|
|
7
|
+
SessionResponse,
|
|
8
|
+
SessionListResponse,
|
|
9
|
+
SessionHistoryResponse,
|
|
10
|
+
SessionCreatedResponse,
|
|
11
|
+
SessionUpdatedResponse,
|
|
12
|
+
SessionDeletedResponse,
|
|
13
|
+
)
|
|
14
|
+
from .task_responses import (
|
|
15
|
+
TaskResponse,
|
|
16
|
+
SendTaskResponse,
|
|
17
|
+
SubscribeTaskResponse,
|
|
18
|
+
CancelTaskResponse,
|
|
19
|
+
TaskStatusResponse,
|
|
20
|
+
TaskListResponse,
|
|
21
|
+
TaskErrorResponse,
|
|
22
|
+
JSONRPCTaskResponse,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
# Session responses
|
|
27
|
+
"MessageResponse",
|
|
28
|
+
"SessionResponse",
|
|
29
|
+
"SessionListResponse",
|
|
30
|
+
"SessionHistoryResponse",
|
|
31
|
+
"SessionCreatedResponse",
|
|
32
|
+
"SessionUpdatedResponse",
|
|
33
|
+
"SessionDeletedResponse",
|
|
34
|
+
# Task responses
|
|
35
|
+
"TaskResponse",
|
|
36
|
+
"SendTaskResponse",
|
|
37
|
+
"SubscribeTaskResponse",
|
|
38
|
+
"CancelTaskResponse",
|
|
39
|
+
"TaskStatusResponse",
|
|
40
|
+
"TaskListResponse",
|
|
41
|
+
"TaskErrorResponse",
|
|
42
|
+
"JSONRPCTaskResponse",
|
|
43
|
+
]
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Session-related response DTOs.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import List, Optional
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
from ....shared.types import SessionId, UserId, MessageId, PaginationInfo, Timestamp
|
|
10
|
+
from ....shared.enums import SessionStatus, SenderType, MessageType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MessageResponse(BaseModel):
|
|
14
|
+
"""Response DTO for a chat message."""
|
|
15
|
+
id: MessageId
|
|
16
|
+
session_id: SessionId
|
|
17
|
+
message: str
|
|
18
|
+
sender_type: SenderType
|
|
19
|
+
sender_name: str
|
|
20
|
+
message_type: MessageType = MessageType.TEXT
|
|
21
|
+
timestamp: datetime
|
|
22
|
+
created_at: datetime
|
|
23
|
+
updated_at: Optional[datetime] = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SessionResponse(BaseModel):
|
|
27
|
+
"""Response DTO for a session."""
|
|
28
|
+
id: SessionId
|
|
29
|
+
user_id: UserId
|
|
30
|
+
name: Optional[str] = None
|
|
31
|
+
agent_id: Optional[str] = None
|
|
32
|
+
status: SessionStatus = SessionStatus.ACTIVE
|
|
33
|
+
created_at: datetime
|
|
34
|
+
updated_at: Optional[datetime] = None
|
|
35
|
+
last_activity: Optional[datetime] = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SessionListResponse(BaseModel):
|
|
39
|
+
"""Response DTO for a list of sessions."""
|
|
40
|
+
sessions: List[SessionResponse]
|
|
41
|
+
pagination: Optional[PaginationInfo] = None
|
|
42
|
+
total_count: int
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SessionHistoryResponse(BaseModel):
|
|
46
|
+
"""Response DTO for session message history."""
|
|
47
|
+
session_id: SessionId
|
|
48
|
+
messages: List[MessageResponse]
|
|
49
|
+
pagination: Optional[PaginationInfo] = None
|
|
50
|
+
total_count: int
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class SessionCreatedResponse(BaseModel):
|
|
54
|
+
"""Response DTO for session creation."""
|
|
55
|
+
session: SessionResponse
|
|
56
|
+
message: str = "Session created successfully"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class SessionUpdatedResponse(BaseModel):
|
|
60
|
+
"""Response DTO for session update."""
|
|
61
|
+
session: SessionResponse
|
|
62
|
+
message: str = "Session updated successfully"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class SessionDeletedResponse(BaseModel):
|
|
66
|
+
"""Response DTO for session deletion."""
|
|
67
|
+
session_id: SessionId
|
|
68
|
+
message: str = "Session deleted successfully"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task-related response DTOs.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, Dict, Any, List
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
from ....shared.types import TaskId, UserId, SessionId, AgentId
|
|
10
|
+
from ....shared.enums import TaskStatus
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TaskResponse(BaseModel):
|
|
14
|
+
"""Response DTO for task information."""
|
|
15
|
+
task_id: TaskId
|
|
16
|
+
agent_name: str
|
|
17
|
+
status: TaskStatus
|
|
18
|
+
user_id: UserId
|
|
19
|
+
session_id: Optional[SessionId] = None
|
|
20
|
+
created_at: datetime
|
|
21
|
+
updated_at: Optional[datetime] = None
|
|
22
|
+
completed_at: Optional[datetime] = None
|
|
23
|
+
error_message: Optional[str] = None
|
|
24
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SendTaskResponse(BaseModel):
|
|
28
|
+
"""Response DTO for send task endpoint."""
|
|
29
|
+
task_id: TaskId
|
|
30
|
+
message: str = "Task submitted successfully"
|
|
31
|
+
status: TaskStatus = TaskStatus.PENDING
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SubscribeTaskResponse(BaseModel):
|
|
35
|
+
"""Response DTO for subscribe task endpoint."""
|
|
36
|
+
task_id: TaskId
|
|
37
|
+
session_id: SessionId
|
|
38
|
+
message: str = "Streaming task submitted successfully"
|
|
39
|
+
status: TaskStatus = TaskStatus.PENDING
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class CancelTaskResponse(BaseModel):
|
|
43
|
+
"""Response DTO for cancel task endpoint."""
|
|
44
|
+
task_id: TaskId
|
|
45
|
+
message: str = "Cancellation request sent successfully"
|
|
46
|
+
cancelled_at: datetime
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TaskStatusResponse(BaseModel):
|
|
50
|
+
"""Response DTO for task status."""
|
|
51
|
+
task: TaskResponse
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class TaskListResponse(BaseModel):
|
|
55
|
+
"""Response DTO for listing tasks."""
|
|
56
|
+
tasks: List[TaskResponse]
|
|
57
|
+
total_count: int
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class TaskErrorResponse(BaseModel):
|
|
61
|
+
"""Response DTO for task errors."""
|
|
62
|
+
task_id: TaskId
|
|
63
|
+
error_type: str
|
|
64
|
+
error_message: str
|
|
65
|
+
error_details: Optional[Dict[str, Any]] = None
|
|
66
|
+
occurred_at: datetime
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class JSONRPCTaskResponse(BaseModel):
|
|
70
|
+
"""Response DTO matching the existing JSONRPC format."""
|
|
71
|
+
result: Dict[str, Any]
|
|
72
|
+
error: Optional[Dict[str, Any]] = None
|
|
73
|
+
id: Optional[str] = None
|
|
74
|
+
jsonrpc: str = "2.0"
|
|
@@ -4,6 +4,9 @@ Defines configuration schema and programmatically creates the WebUIBackendCompon
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
from typing import Any, Dict, List
|
|
7
|
+
import os
|
|
8
|
+
from alembic import command
|
|
9
|
+
from alembic.config import Config
|
|
7
10
|
from solace_ai_connector.common.log import log
|
|
8
11
|
|
|
9
12
|
from ...gateway.http_sse.component import WebUIBackendComponent
|
|
@@ -183,7 +186,34 @@ class WebUIBackendApp(BaseGatewayApp):
|
|
|
183
186
|
"%s Initializing WebUIBackendApp...",
|
|
184
187
|
app_info.get("name", "WebUIBackendApp"),
|
|
185
188
|
)
|
|
186
|
-
super().__init__(app_info
|
|
189
|
+
super().__init__(app_info, **kwargs)
|
|
190
|
+
|
|
191
|
+
try:
|
|
192
|
+
|
|
193
|
+
alembic_ini_path = os.path.join(os.path.dirname(__file__), "alembic.ini")
|
|
194
|
+
if os.path.exists(alembic_ini_path):
|
|
195
|
+
log.debug("Loading Alembic configuration from alembic.ini.")
|
|
196
|
+
alembic_cfg = Config(alembic_ini_path)
|
|
197
|
+
else:
|
|
198
|
+
log.warning(
|
|
199
|
+
"alembic.ini not found. Falling back to programmatic configuration."
|
|
200
|
+
)
|
|
201
|
+
alembic_cfg = Config()
|
|
202
|
+
alembic_cfg.set_main_option(
|
|
203
|
+
"script_location",
|
|
204
|
+
os.path.join(os.path.dirname(__file__), "alembic"),
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
session_service_config = self.get_config("session_service", {})
|
|
208
|
+
db_url = session_service_config.get("database_url")
|
|
209
|
+
if db_url:
|
|
210
|
+
alembic_cfg.set_main_option("sqlalchemy.url", db_url)
|
|
211
|
+
command.upgrade(alembic_cfg, "head")
|
|
212
|
+
else:
|
|
213
|
+
log.warning("Database URL not configured. Skipping migrations.")
|
|
214
|
+
except Exception as e:
|
|
215
|
+
log.warning(f"Alembic migration failed: {e}")
|
|
216
|
+
|
|
187
217
|
log.debug("%s WebUIBackendApp initialization complete.", self.name)
|
|
188
218
|
|
|
189
219
|
def _get_gateway_component_class(self) -> type[BaseGatewayComponent]:
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
|
|
4
|
+
from solace_ai_connector.common.log import log
|
|
5
|
+
|
|
6
|
+
from ...domain.entities.session import Message, Session, SessionHistory
|
|
7
|
+
from ...domain.repositories.session_repository import (
|
|
8
|
+
IMessageRepository,
|
|
9
|
+
ISessionRepository,
|
|
10
|
+
)
|
|
11
|
+
from ...shared.enums import MessageType, SenderType, SessionStatus
|
|
12
|
+
from ...shared.types import PaginationInfo, SessionId, UserId
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SessionService:
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
session_repository: ISessionRepository,
|
|
19
|
+
message_repository: IMessageRepository,
|
|
20
|
+
):
|
|
21
|
+
self.session_repository = session_repository
|
|
22
|
+
self.message_repository = message_repository
|
|
23
|
+
|
|
24
|
+
def get_user_sessions(
|
|
25
|
+
self, user_id: UserId, pagination: PaginationInfo | None = None
|
|
26
|
+
) -> list[Session]:
|
|
27
|
+
return self.session_repository.get_by_user_id(user_id, pagination)
|
|
28
|
+
|
|
29
|
+
def get_session(self, session_id: SessionId, user_id: UserId) -> Session | None:
|
|
30
|
+
return self.session_repository.get_user_session(session_id, user_id)
|
|
31
|
+
|
|
32
|
+
def get_session_history(
|
|
33
|
+
self,
|
|
34
|
+
session_id: SessionId,
|
|
35
|
+
user_id: UserId,
|
|
36
|
+
pagination: PaginationInfo | None = None,
|
|
37
|
+
) -> SessionHistory | None:
|
|
38
|
+
session = self.session_repository.get_user_session(session_id, user_id)
|
|
39
|
+
if not session:
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
messages = self.message_repository.get_by_session_id(session_id, pagination)
|
|
43
|
+
|
|
44
|
+
return SessionHistory(
|
|
45
|
+
session=session,
|
|
46
|
+
messages=messages,
|
|
47
|
+
total_message_count=len(messages),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def create_session(
|
|
51
|
+
self,
|
|
52
|
+
user_id: UserId,
|
|
53
|
+
name: str | None = None,
|
|
54
|
+
agent_id: str | None = None,
|
|
55
|
+
session_id: str | None = None,
|
|
56
|
+
) -> Session:
|
|
57
|
+
if not user_id or user_id.strip() == "":
|
|
58
|
+
raise ValueError(f"user_id cannot be None or empty. Received: {user_id}")
|
|
59
|
+
|
|
60
|
+
if not session_id:
|
|
61
|
+
session_id = str(uuid.uuid4())
|
|
62
|
+
|
|
63
|
+
now = datetime.now(timezone.utc)
|
|
64
|
+
session = Session(
|
|
65
|
+
id=session_id,
|
|
66
|
+
user_id=user_id,
|
|
67
|
+
name=name,
|
|
68
|
+
agent_id=agent_id,
|
|
69
|
+
status=SessionStatus.ACTIVE,
|
|
70
|
+
created_at=now,
|
|
71
|
+
updated_at=now,
|
|
72
|
+
last_activity=now,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return self.session_repository.create(session)
|
|
76
|
+
|
|
77
|
+
def update_session_name(
|
|
78
|
+
self, session_id: SessionId, user_id: UserId, name: str
|
|
79
|
+
) -> Session | None:
|
|
80
|
+
session = self.session_repository.get_user_session(session_id, user_id)
|
|
81
|
+
if not session:
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
session.update_name(name)
|
|
85
|
+
return self.session_repository.update(session)
|
|
86
|
+
|
|
87
|
+
def delete_session(self, session_id: SessionId, user_id: UserId) -> bool:
|
|
88
|
+
session = self.session_repository.get_user_session(session_id, user_id)
|
|
89
|
+
if not session:
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
if not session.can_be_deleted_by_user(user_id):
|
|
93
|
+
return False
|
|
94
|
+
|
|
95
|
+
self.message_repository.delete_by_session_id(session_id)
|
|
96
|
+
return self.session_repository.delete(session_id, user_id)
|
|
97
|
+
|
|
98
|
+
def add_message_to_session(
|
|
99
|
+
self,
|
|
100
|
+
session_id: SessionId,
|
|
101
|
+
user_id: UserId,
|
|
102
|
+
message: str,
|
|
103
|
+
sender_type: SenderType,
|
|
104
|
+
sender_name: str,
|
|
105
|
+
agent_id: str | None = None,
|
|
106
|
+
) -> Message | None:
|
|
107
|
+
if not user_id or user_id.strip() == "":
|
|
108
|
+
raise ValueError(f"user_id cannot be None or empty. Received: {user_id}")
|
|
109
|
+
|
|
110
|
+
session = self.session_repository.get_user_session(session_id, user_id)
|
|
111
|
+
if not session:
|
|
112
|
+
log.error(f"Session {session_id} not found for user {user_id}")
|
|
113
|
+
return None
|
|
114
|
+
|
|
115
|
+
if agent_id and not session.agent_id:
|
|
116
|
+
session.agent_id = agent_id
|
|
117
|
+
self.session_repository.update(session)
|
|
118
|
+
log.info(f"Updated session {session_id} with agent_id: {agent_id}")
|
|
119
|
+
|
|
120
|
+
message_entity = Message(
|
|
121
|
+
id=str(uuid.uuid4()),
|
|
122
|
+
session_id=session_id,
|
|
123
|
+
message=message,
|
|
124
|
+
sender_type=sender_type,
|
|
125
|
+
sender_name=sender_name,
|
|
126
|
+
message_type=MessageType.TEXT,
|
|
127
|
+
created_at=datetime.now(timezone.utc),
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
message_entity.validate_message_content()
|
|
131
|
+
|
|
132
|
+
session.mark_activity()
|
|
133
|
+
self.session_repository.update(session)
|
|
134
|
+
|
|
135
|
+
return self.message_repository.create(message_entity)
|