solace-agent-mesh 1.4.6__py3-none-any.whl → 1.4.8__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 (139) hide show
  1. solace_agent_mesh/agent/adk/runner.py +24 -8
  2. solace_agent_mesh/agent/sac/component.py +13 -1
  3. solace_agent_mesh/assets/docs/404.html +3 -3
  4. solace_agent_mesh/assets/docs/assets/js/{0e682baa.da822665.js → 0e682baa.d054e1d8.js} +1 -1
  5. solace_agent_mesh/assets/docs/assets/js/166ab619.e27886d9.js +1 -0
  6. solace_agent_mesh/assets/docs/assets/js/{1c6e87d2.43771adc.js → 1c6e87d2.e056b7e0.js} +1 -1
  7. solace_agent_mesh/assets/docs/assets/js/453a82a6.3c6bb61d.js +1 -0
  8. solace_agent_mesh/assets/docs/assets/js/483cef9a.4736f2d8.js +1 -0
  9. solace_agent_mesh/assets/docs/assets/js/{4c2787c2.fc6804f2.js → 4c2787c2.c1290a40.js} +1 -1
  10. solace_agent_mesh/assets/docs/assets/js/{5b4258a4.dff11eca.js → 5b4258a4.fdfd2325.js} +1 -1
  11. solace_agent_mesh/assets/docs/assets/js/{75384d09.abdf9cf9.js → 75384d09.c19e8b51.js} +1 -1
  12. solace_agent_mesh/assets/docs/assets/js/85387663.be2bc838.js +1 -0
  13. solace_agent_mesh/assets/docs/assets/js/945fb41e.16e00776.js +1 -0
  14. solace_agent_mesh/assets/docs/assets/js/a12a4955.25fbed32.js +1 -0
  15. solace_agent_mesh/assets/docs/assets/js/a3a92b25.af35e313.js +1 -0
  16. solace_agent_mesh/assets/docs/assets/js/ae0e903d.5fe5203f.js +1 -0
  17. solace_agent_mesh/assets/docs/assets/js/bac0be12.17de4316.js +1 -0
  18. solace_agent_mesh/assets/docs/assets/js/cee5d587.47904f5e.js +1 -0
  19. solace_agent_mesh/assets/docs/assets/js/d6a81ee7.829198f1.js +1 -0
  20. solace_agent_mesh/assets/docs/assets/js/f284c35a.ed8dd236.js +1 -0
  21. solace_agent_mesh/assets/docs/assets/js/f897a61a.126663fe.js +1 -0
  22. solace_agent_mesh/assets/docs/assets/js/{fbfa3e75.aca209c9.js → fbfa3e75.e144b16c.js} +1 -1
  23. solace_agent_mesh/assets/docs/assets/js/main.86924c42.js +2 -0
  24. solace_agent_mesh/assets/docs/assets/js/runtime~main.0d2ff2b6.js +1 -0
  25. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +4 -4
  26. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +201 -0
  27. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +4 -4
  28. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +4 -4
  29. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html +4 -4
  30. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +4 -4
  31. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +7 -7
  32. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
  33. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
  34. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
  35. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
  36. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +5 -5
  37. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +5 -5
  38. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +6 -6
  39. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +7 -7
  40. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +12 -13
  41. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +49 -0
  42. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
  43. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +6 -6
  44. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +6 -6
  45. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
  46. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +4 -4
  47. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +8 -8
  48. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +5 -5
  49. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
  50. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +7 -7
  51. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +5 -5
  52. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
  53. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
  54. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
  55. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
  56. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
  57. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +4 -4
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +4 -4
  60. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
  61. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +4 -4
  62. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +4 -4
  63. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +6 -6
  64. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +7 -7
  65. solace_agent_mesh/assets/docs/lunr-index-1759246102819.json +1 -0
  66. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  67. solace_agent_mesh/assets/docs/search-doc-1759246102819.json +1 -0
  68. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  69. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  70. solace_agent_mesh/cli/__init__.py +1 -1
  71. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +6 -3
  72. solace_agent_mesh/cli/commands/init_cmd/__init__.py +3 -3
  73. solace_agent_mesh/cli/commands/init_cmd/broker_step.py +1 -1
  74. solace_agent_mesh/cli/commands/init_cmd/env_step.py +1 -1
  75. solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +4 -4
  76. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +12 -1
  77. solace_agent_mesh/cli/commands/plugin_cmd/install_cmd.py +5 -5
  78. solace_agent_mesh/client/webui/frontend/static/assets/main-B0PHV3hm.js +339 -0
  79. solace_agent_mesh/client/webui/frontend/static/index.html +1 -1
  80. solace_agent_mesh/config_portal/backend/common.py +1 -1
  81. solace_agent_mesh/config_portal/frontend/static/client/assets/{_index-bFMKlzKf.js → _index-BNuqpWDc.js} +1 -1
  82. solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-89db7c30.js → manifest-44d62be6.js} +1 -1
  83. solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
  84. solace_agent_mesh/gateway/http_sse/alembic/versions/20250916_f6e7d8c9b0a1_convert_timestamps_to_epoch_and_align_columns.py +112 -42
  85. solace_agent_mesh/gateway/http_sse/app.py +0 -28
  86. solace_agent_mesh/gateway/http_sse/component.py +21 -15
  87. solace_agent_mesh/gateway/http_sse/dependencies.py +84 -88
  88. solace_agent_mesh/gateway/http_sse/main.py +37 -15
  89. solace_agent_mesh/gateway/http_sse/repository/entities/message.py +3 -1
  90. solace_agent_mesh/gateway/http_sse/repository/entities/session.py +3 -1
  91. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +5 -0
  92. solace_agent_mesh/gateway/http_sse/repository/message_repository.py +25 -23
  93. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +12 -4
  94. solace_agent_mesh/gateway/http_sse/repository/models/message_model.py +19 -1
  95. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +19 -1
  96. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +46 -42
  97. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +199 -59
  98. solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +1 -6
  99. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +3 -17
  100. solace_agent_mesh/gateway/http_sse/routers/people.py +4 -37
  101. solace_agent_mesh/gateway/http_sse/routers/sessions.py +33 -68
  102. solace_agent_mesh/gateway/http_sse/routers/tasks.py +54 -28
  103. solace_agent_mesh/gateway/http_sse/services/session_service.py +60 -28
  104. solace_agent_mesh/gateway/http_sse/shared/__init__.py +122 -1
  105. solace_agent_mesh/gateway/http_sse/shared/base_repository.py +278 -0
  106. solace_agent_mesh/gateway/http_sse/shared/database_exceptions.py +274 -0
  107. solace_agent_mesh/gateway/http_sse/shared/database_helpers.py +43 -0
  108. solace_agent_mesh/gateway/http_sse/shared/error_dto.py +107 -0
  109. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +192 -0
  110. solace_agent_mesh/gateway/http_sse/shared/exceptions.py +192 -0
  111. solace_agent_mesh/gateway/http_sse/shared/pagination.py +138 -0
  112. solace_agent_mesh/gateway/http_sse/shared/response_utils.py +134 -0
  113. solace_agent_mesh/gateway/http_sse/shared/utils.py +22 -0
  114. solace_agent_mesh/templates/plugin_agent_config_template.yaml +1 -1
  115. solace_agent_mesh/templates/plugin_custom_config_template.yaml +1 -1
  116. solace_agent_mesh/templates/plugin_gateway_config_template.yaml +1 -1
  117. solace_agent_mesh/templates/shared_config.yaml +1 -1
  118. {solace_agent_mesh-1.4.6.dist-info → solace_agent_mesh-1.4.8.dist-info}/METADATA +34 -35
  119. {solace_agent_mesh-1.4.6.dist-info → solace_agent_mesh-1.4.8.dist-info}/RECORD +123 -110
  120. solace_agent_mesh/assets/docs/assets/js/166ab619.e8f3a7c7.js +0 -1
  121. solace_agent_mesh/assets/docs/assets/js/483cef9a.8d318c2f.js +0 -1
  122. solace_agent_mesh/assets/docs/assets/js/85387663.6bf41934.js +0 -1
  123. solace_agent_mesh/assets/docs/assets/js/945fb41e.abf2be91.js +0 -1
  124. solace_agent_mesh/assets/docs/assets/js/a3a92b25.1d029b81.js +0 -1
  125. solace_agent_mesh/assets/docs/assets/js/ae0e903d.c786e887.js +0 -1
  126. solace_agent_mesh/assets/docs/assets/js/bac0be12.27ee2c26.js +0 -1
  127. solace_agent_mesh/assets/docs/assets/js/beecea0d.8bbd852c.js +0 -1
  128. solace_agent_mesh/assets/docs/assets/js/cee5d587.f1e1ca86.js +0 -1
  129. solace_agent_mesh/assets/docs/assets/js/f284c35a.2b2f5048.js +0 -1
  130. solace_agent_mesh/assets/docs/assets/js/f897a61a.bc634a3e.js +0 -1
  131. solace_agent_mesh/assets/docs/assets/js/main.72d74e33.js +0 -2
  132. solace_agent_mesh/assets/docs/assets/js/runtime~main.3dcfaf51.js +0 -1
  133. solace_agent_mesh/assets/docs/lunr-index-1758893005563.json +0 -1
  134. solace_agent_mesh/assets/docs/search-doc-1758893005563.json +0 -1
  135. solace_agent_mesh/client/webui/frontend/static/assets/main-BKIoiLSu.js +0 -339
  136. /solace_agent_mesh/assets/docs/assets/js/{main.72d74e33.js.LICENSE.txt → main.86924c42.js.LICENSE.txt} +0 -0
  137. {solace_agent_mesh-1.4.6.dist-info → solace_agent_mesh-1.4.8.dist-info}/WHEEL +0 -0
  138. {solace_agent_mesh-1.4.6.dist-info → solace_agent_mesh-1.4.8.dist-info}/entry_points.txt +0 -0
  139. {solace_agent_mesh-1.4.6.dist-info → solace_agent_mesh-1.4.8.dist-info}/licenses/LICENSE +0 -0
@@ -4,19 +4,26 @@ Message repository implementation using SQLAlchemy.
4
4
 
5
5
  from sqlalchemy.orm import Session as DBSession
6
6
 
7
+ from ..shared.base_repository import PaginatedRepository
7
8
  from ..shared.enums import MessageType, SenderType
8
9
  from ..shared.types import PaginationInfo, SessionId
9
10
  from .entities import Message
10
11
  from .interfaces import IMessageRepository
11
- from .models import MessageModel
12
+ from .models import MessageModel, CreateMessageModel, UpdateMessageModel
12
13
 
13
14
 
14
- class MessageRepository(IMessageRepository):
15
- """SQLAlchemy implementation of message repository."""
15
+ class MessageRepository(PaginatedRepository[MessageModel, Message], IMessageRepository):
16
+ """SQLAlchemy implementation of message repository using BaseRepository."""
16
17
 
17
18
  def __init__(self, db: DBSession):
19
+ super().__init__(MessageModel, Message)
18
20
  self.db = db
19
21
 
22
+ @property
23
+ def entity_name(self) -> str:
24
+ """Return the entity name for error messages."""
25
+ return "message"
26
+
20
27
  def find_by_session(
21
28
  self, session_id: SessionId, pagination: PaginationInfo | None = None
22
29
  ) -> list[Message]:
@@ -24,28 +31,28 @@ class MessageRepository(IMessageRepository):
24
31
  query = self.db.query(MessageModel).filter(
25
32
  MessageModel.session_id == session_id
26
33
  )
34
+ query = query.order_by(MessageModel.created_time.asc())
27
35
 
28
36
  if pagination:
29
37
  offset = (pagination.page - 1) * pagination.page_size
30
38
  query = query.offset(offset).limit(pagination.page_size)
31
39
 
32
- models = query.order_by(MessageModel.created_time.asc()).all()
33
- return [self._model_to_entity(model) for model in models]
40
+ models = query.all()
41
+ return [self._convert_model_to_entity(model) for model in models]
34
42
 
35
43
  def save(self, message: Message) -> Message:
36
44
  """Save or update a message."""
37
- model = (
38
- self.db.query(MessageModel).filter(MessageModel.id == message.id).first()
39
- )
45
+ existing_model = self.db.query(MessageModel).filter(MessageModel.id == message.id).first()
40
46
 
41
- if model:
42
- # Update existing
43
- model.message = message.message
44
- model.sender_type = message.sender_type.value
45
- model.sender_name = message.sender_name
47
+ if existing_model:
48
+ update_model = UpdateMessageModel(
49
+ message=message.message,
50
+ sender_type=message.sender_type.value,
51
+ sender_name=message.sender_name,
52
+ )
53
+ return self.update(self.db, message.id, update_model.model_dump())
46
54
  else:
47
- # Create new
48
- model = MessageModel(
55
+ create_model = CreateMessageModel(
49
56
  id=message.id,
50
57
  session_id=message.session_id,
51
58
  message=message.message,
@@ -53,11 +60,7 @@ class MessageRepository(IMessageRepository):
53
60
  sender_name=message.sender_name,
54
61
  created_time=message.created_time,
55
62
  )
56
- self.db.add(model)
57
-
58
- self.db.commit()
59
- self.db.refresh(model)
60
- return self._model_to_entity(model)
63
+ return self.create(self.db, create_model.model_dump())
61
64
 
62
65
  def delete_by_session(self, session_id: SessionId) -> bool:
63
66
  """Delete all messages in a session."""
@@ -66,11 +69,10 @@ class MessageRepository(IMessageRepository):
66
69
  .filter(MessageModel.session_id == session_id)
67
70
  .delete()
68
71
  )
69
- self.db.commit()
70
72
  return result > 0
71
73
 
72
- def _model_to_entity(self, model: MessageModel) -> Message:
73
- """Convert SQLAlchemy model to domain entity."""
74
+ def _convert_model_to_entity(self, model: MessageModel) -> Message:
75
+ """Convert SQLAlchemy model to domain entity with enum handling."""
74
76
  return Message(
75
77
  id=model.id,
76
78
  session_id=model.session_id,
@@ -1,9 +1,17 @@
1
1
  """
2
- SQLAlchemy models for database persistence.
2
+ SQLAlchemy models and Pydantic models for database persistence.
3
3
  """
4
4
 
5
5
  from .base import Base
6
- from .message_model import MessageModel
7
- from .session_model import SessionModel
6
+ from .message_model import MessageModel, CreateMessageModel, UpdateMessageModel
7
+ from .session_model import SessionModel, CreateSessionModel, UpdateSessionModel
8
8
 
9
- __all__ = ["Base", "MessageModel", "SessionModel"]
9
+ __all__ = [
10
+ "Base",
11
+ "MessageModel",
12
+ "SessionModel",
13
+ "CreateMessageModel",
14
+ "UpdateMessageModel",
15
+ "CreateSessionModel",
16
+ "UpdateSessionModel",
17
+ ]
@@ -1,7 +1,8 @@
1
1
  """
2
- Message SQLAlchemy model.
2
+ Message SQLAlchemy model and Pydantic models for strongly-typed operations.
3
3
  """
4
4
 
5
+ from pydantic import BaseModel
5
6
  from sqlalchemy import BigInteger, Column, ForeignKey, String, Text
6
7
  from sqlalchemy.orm import relationship
7
8
 
@@ -25,3 +26,20 @@ class MessageModel(Base):
25
26
 
26
27
  # Relationship to session
27
28
  session = relationship("SessionModel", back_populates="messages")
29
+
30
+
31
+ class CreateMessageModel(BaseModel):
32
+ """Pydantic model for creating a message."""
33
+ id: str
34
+ session_id: str
35
+ message: str
36
+ sender_type: str
37
+ sender_name: str
38
+ created_time: int
39
+
40
+
41
+ class UpdateMessageModel(BaseModel):
42
+ """Pydantic model for updating a message."""
43
+ message: str
44
+ sender_type: str
45
+ sender_name: str
@@ -1,7 +1,8 @@
1
1
  """
2
- Session SQLAlchemy model.
2
+ Session SQLAlchemy model and Pydantic models for strongly-typed operations.
3
3
  """
4
4
 
5
+ from pydantic import BaseModel
5
6
  from sqlalchemy import BigInteger, Column, String
6
7
  from sqlalchemy.orm import relationship
7
8
 
@@ -27,3 +28,20 @@ class SessionModel(Base):
27
28
  messages = relationship(
28
29
  "MessageModel", back_populates="session", cascade="all, delete-orphan"
29
30
  )
31
+
32
+
33
+ class CreateSessionModel(BaseModel):
34
+ """Pydantic model for creating a session."""
35
+ id: str
36
+ name: str | None
37
+ user_id: str
38
+ agent_id: str | None
39
+ created_time: int
40
+ updated_time: int
41
+
42
+
43
+ class UpdateSessionModel(BaseModel):
44
+ """Pydantic model for updating a session."""
45
+ name: str | None = None
46
+ agent_id: str | None = None
47
+ updated_time: int
@@ -4,30 +4,47 @@ Session repository implementation using SQLAlchemy.
4
4
 
5
5
  from sqlalchemy.orm import Session as DBSession
6
6
 
7
+ from ..shared.base_repository import PaginatedRepository
7
8
  from ..shared.types import PaginationInfo, SessionId, UserId
8
9
  from .entities import Message, Session
9
10
  from .interfaces import ISessionRepository
10
- from .models import MessageModel, SessionModel
11
+ from .models import (
12
+ MessageModel,
13
+ SessionModel,
14
+ CreateSessionModel,
15
+ UpdateSessionModel,
16
+ )
11
17
 
12
18
 
13
- class SessionRepository(ISessionRepository):
14
- """SQLAlchemy implementation of session repository."""
19
+ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepository):
20
+ """SQLAlchemy implementation of session repository using BaseRepository."""
15
21
 
16
22
  def __init__(self, db: DBSession):
23
+ super().__init__(SessionModel, Session)
17
24
  self.db = db
18
25
 
26
+ @property
27
+ def entity_name(self) -> str:
28
+ """Return the entity name for error messages."""
29
+ return "session"
30
+
19
31
  def find_by_user(
20
32
  self, user_id: UserId, pagination: PaginationInfo | None = None
21
33
  ) -> list[Session]:
22
34
  """Find all sessions for a specific user."""
23
35
  query = self.db.query(SessionModel).filter(SessionModel.user_id == user_id)
36
+ query = query.order_by(SessionModel.updated_time.desc())
24
37
 
25
38
  if pagination:
26
39
  offset = (pagination.page - 1) * pagination.page_size
27
40
  query = query.offset(offset).limit(pagination.page_size)
28
41
 
29
- models = query.order_by(SessionModel.updated_time.desc()).all()
30
- return [self._model_to_entity(model) for model in models]
42
+ models = query.all()
43
+ return [Session.model_validate(model) for model in models]
44
+
45
+ def count_by_user(self, user_id: UserId) -> int:
46
+ """Count total sessions for a specific user."""
47
+ return self.db.query(SessionModel).filter(SessionModel.user_id == user_id).count()
31
48
 
32
49
  def find_user_session(
33
50
  self, session_id: SessionId, user_id: UserId
@@ -41,22 +58,21 @@ class SessionRepository(ISessionRepository):
41
58
  )
42
59
  .first()
43
60
  )
44
- return self._model_to_entity(model) if model else None
61
+ return Session.model_validate(model) if model else None
45
62
 
46
63
  def save(self, session: Session) -> Session:
47
64
  """Save or update a session."""
48
- model = (
49
- self.db.query(SessionModel).filter(SessionModel.id == session.id).first()
50
- )
65
+ existing_model = self.db.query(SessionModel).filter(SessionModel.id == session.id).first()
51
66
 
52
- if model:
53
- # Update existing
54
- model.name = session.name
55
- model.agent_id = session.agent_id
56
- model.updated_time = session.updated_time
67
+ if existing_model:
68
+ update_model = UpdateSessionModel(
69
+ name=session.name,
70
+ agent_id=session.agent_id,
71
+ updated_time=session.updated_time,
72
+ )
73
+ return self.update(self.db, session.id, update_model.model_dump(exclude_none=True))
57
74
  else:
58
- # Create new
59
- model = SessionModel(
75
+ create_model = CreateSessionModel(
60
76
  id=session.id,
61
77
  name=session.name,
62
78
  user_id=session.user_id,
@@ -64,24 +80,22 @@ class SessionRepository(ISessionRepository):
64
80
  created_time=session.created_time,
65
81
  updated_time=session.updated_time,
66
82
  )
67
- self.db.add(model)
68
-
69
- self.db.commit()
70
- self.db.refresh(model)
71
- return self._model_to_entity(model)
83
+ return self.create(self.db, create_model.model_dump())
72
84
 
73
85
  def delete(self, session_id: SessionId, user_id: UserId) -> bool:
74
86
  """Delete a session belonging to a user."""
75
- result = (
76
- self.db.query(SessionModel)
77
- .filter(
78
- SessionModel.id == session_id,
79
- SessionModel.user_id == user_id,
80
- )
81
- .delete()
82
- )
83
- self.db.commit()
84
- return result > 0
87
+ # Check if session belongs to user first
88
+ session_model = self.db.query(SessionModel).filter(
89
+ SessionModel.id == session_id,
90
+ SessionModel.user_id == user_id,
91
+ ).first()
92
+
93
+ if not session_model:
94
+ return False
95
+
96
+ # Use BaseRepository delete method
97
+ super().delete(self.db, session_id)
98
+ return True
85
99
 
86
100
  def find_user_session_with_messages(
87
101
  self,
@@ -112,21 +126,11 @@ class SessionRepository(ISessionRepository):
112
126
 
113
127
  message_models = message_query.order_by(MessageModel.created_time.asc()).all()
114
128
 
115
- session = self._model_to_entity(session_model)
129
+ session = Session.model_validate(session_model)
116
130
  messages = [self._message_model_to_entity(model) for model in message_models]
117
131
 
118
132
  return session, messages
119
133
 
120
- def _model_to_entity(self, model: SessionModel) -> Session:
121
- """Convert SQLAlchemy model to domain entity."""
122
- return Session(
123
- id=model.id,
124
- user_id=model.user_id,
125
- name=model.name,
126
- agent_id=model.agent_id,
127
- created_time=model.created_time,
128
- updated_time=model.updated_time,
129
- )
130
134
 
131
135
  def _message_model_to_entity(self, model: MessageModel) -> Message:
132
136
  """Convert SQLAlchemy message model to domain entity."""