Skip to content

Commit 300ce92

Browse files
committed
phase 2 of updates for symbiont 0.3.1 changes
1 parent 1824e0d commit 300ce92

File tree

9 files changed

+893
-73
lines changed

9 files changed

+893
-73
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ dependencies = [
3636
"cryptography>=41.0.0",
3737
"pyyaml>=6.0.0",
3838
"pydantic-settings>=2.0.0",
39+
"redis>=5.0.0",
3940
]
4041

4142
[project.optional-dependencies]

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ pydantic>=2.0.0
33
python-dotenv>=1.0.0
44
pyjwt>=2.8.0
55
cryptography>=41.0.0
6+
redis>=5.0.0
67
pyyaml>=6.0.0
78
pydantic-settings>=2.0.0

setup.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
from setuptools import setup, find_packages
21
import os
32

3+
from setuptools import find_packages, setup
4+
5+
46
# Read README.md for long description
57
def read_readme():
6-
with open(os.path.join(os.path.dirname(__file__), 'README.md'), 'r', encoding='utf-8') as f:
8+
with open(os.path.join(os.path.dirname(__file__), 'README.md'), encoding='utf-8') as f:
79
return f.read()
810

911
# Read requirements.txt for install_requires
1012
def read_requirements():
11-
with open(os.path.join(os.path.dirname(__file__), 'requirements.txt'), 'r', encoding='utf-8') as f:
13+
with open(os.path.join(os.path.dirname(__file__), 'requirements.txt'), encoding='utf-8') as f:
1214
return [line.strip() for line in f if line.strip() and not line.startswith('#')]
1315

1416
setup(
@@ -40,4 +42,4 @@ def read_requirements():
4042
'Programming Language :: Python :: 3.11',
4143
'Programming Language :: Python :: 3.12',
4244
],
43-
)
45+
)

symbiont/client.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
AgentMetrics,
2727
AgentStatusResponse,
2828
AnalysisResults,
29+
ConsolidationResponse,
2930
# Configuration models (Phase 1)
3031
ContextQuery,
3132
ContextResponse,
33+
ConversationContext,
3234
# Agent DSL models
3335
DslCompileRequest,
3436
DslCompileResponse,
@@ -45,6 +47,12 @@
4547
# MCP Management models
4648
McpServerConfig,
4749
McpToolInfo,
50+
MemoryQuery,
51+
MemoryResponse,
52+
MemorySearchRequest,
53+
MemorySearchResponse,
54+
# Phase 2 Memory System models
55+
MemoryStoreRequest,
4856
ReviewSession,
4957
ReviewSessionCreate,
5058
ReviewSessionList,
@@ -1032,3 +1040,110 @@ def get_http_input_metrics(self, server_id: str) -> Dict[str, Any]:
10321040
"""
10331041
response = self._request("GET", f"http-input/servers/{server_id}/metrics")
10341042
return response.json()
1043+
1044+
# =============================================================================
1045+
# Phase 2 Memory System Methods
1046+
# =============================================================================
1047+
1048+
def add_memory(self, memory_request: Union[MemoryStoreRequest, Dict[str, Any]]) -> MemoryResponse:
1049+
"""Store a new memory in the system.
1050+
1051+
Args:
1052+
memory_request: Memory storage request
1053+
1054+
Returns:
1055+
MemoryResponse: Memory storage response
1056+
"""
1057+
if isinstance(memory_request, dict):
1058+
memory_request = MemoryStoreRequest(**memory_request)
1059+
1060+
response = self._request("POST", "memory", json=memory_request.model_dump())
1061+
return MemoryResponse(**response.json())
1062+
1063+
def get_memory(self, memory_query: Union[MemoryQuery, Dict[str, Any]]) -> MemoryResponse:
1064+
"""Retrieve a specific memory.
1065+
1066+
Args:
1067+
memory_query: Memory query parameters
1068+
1069+
Returns:
1070+
MemoryResponse: Memory retrieval response
1071+
"""
1072+
if isinstance(memory_query, dict):
1073+
memory_query = MemoryQuery(**memory_query)
1074+
1075+
response = self._request("GET", "memory", params=memory_query.model_dump(exclude_none=True))
1076+
return MemoryResponse(**response.json())
1077+
1078+
def search_memory(self, search_request: Union[MemorySearchRequest, Dict[str, Any]]) -> MemorySearchResponse:
1079+
"""Search for memories matching criteria.
1080+
1081+
Args:
1082+
search_request: Memory search request
1083+
1084+
Returns:
1085+
MemorySearchResponse: Search results
1086+
"""
1087+
if isinstance(search_request, dict):
1088+
search_request = MemorySearchRequest(**search_request)
1089+
1090+
response = self._request("POST", "memory/search", json=search_request.model_dump())
1091+
return MemorySearchResponse(**response.json())
1092+
1093+
def consolidate_memory(self, agent_id: str) -> ConsolidationResponse:
1094+
"""Consolidate memories for an agent.
1095+
1096+
Args:
1097+
agent_id: The agent identifier
1098+
1099+
Returns:
1100+
ConsolidationResponse: Consolidation process results
1101+
"""
1102+
response = self._request("POST", f"memory/consolidate/{agent_id}")
1103+
return ConsolidationResponse(**response.json())
1104+
1105+
def get_conversation_context(self, conversation_id: str, agent_id: str) -> ConversationContext:
1106+
"""Get conversation context with associated memories.
1107+
1108+
Args:
1109+
conversation_id: The conversation identifier
1110+
agent_id: The agent identifier
1111+
1112+
Returns:
1113+
ConversationContext: Conversation context with memories
1114+
"""
1115+
params = {
1116+
"conversation_id": conversation_id,
1117+
"agent_id": agent_id
1118+
}
1119+
response = self._request("GET", "memory/conversation", params=params)
1120+
return ConversationContext(**response.json())
1121+
1122+
def delete_memory(self, memory_id: str) -> Dict[str, Any]:
1123+
"""Delete a memory by ID.
1124+
1125+
Args:
1126+
memory_id: The memory identifier
1127+
1128+
Returns:
1129+
Dict[str, Any]: Deletion confirmation
1130+
"""
1131+
response = self._request("DELETE", f"memory/{memory_id}")
1132+
return response.json()
1133+
1134+
def list_agent_memories(self, agent_id: str, limit: int = 100) -> MemorySearchResponse:
1135+
"""List all memories for an agent.
1136+
1137+
Args:
1138+
agent_id: The agent identifier
1139+
limit: Maximum number of memories to return
1140+
1141+
Returns:
1142+
MemorySearchResponse: List of agent memories
1143+
"""
1144+
params = {
1145+
"agent_id": agent_id,
1146+
"limit": limit
1147+
}
1148+
response = self._request("GET", "memory/agent", params=params)
1149+
return MemorySearchResponse(**response.json())

symbiont/exceptions.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,40 @@ def __init__(self, message: str = "Insufficient permissions for this operation",
128128
"""
129129
super().__init__(message, 403)
130130
self.required_permission = required_permission
131+
132+
133+
# =============================================================================
134+
# Phase 2 Memory System Exception Classes
135+
# =============================================================================
136+
137+
class MemoryError(SymbiontError):
138+
"""Base exception for memory system errors."""
139+
pass
140+
141+
142+
class MemoryStorageError(MemoryError):
143+
"""Raised when memory storage operations fail."""
144+
145+
def __init__(self, message: str = "Memory storage error", storage_type: str = None):
146+
"""Initialize the MemoryStorageError.
147+
148+
Args:
149+
message: Error message describing the storage failure.
150+
storage_type: Optional storage backend type that failed.
151+
"""
152+
super().__init__(message)
153+
self.storage_type = storage_type
154+
155+
156+
class MemoryRetrievalError(MemoryError):
157+
"""Raised when memory retrieval operations fail."""
158+
159+
def __init__(self, message: str = "Memory retrieval error", memory_id: str = None):
160+
"""Initialize the MemoryRetrievalError.
161+
162+
Args:
163+
message: Error message describing the retrieval failure.
164+
memory_id: Optional memory ID that failed to retrieve.
165+
"""
166+
super().__init__(message)
167+
self.memory_id = memory_id

0 commit comments

Comments
 (0)