Skip to content

Commit b21a652

Browse files
Implement 3 integration kwargs that were silently dropped
These kwargs are documented on the website but never wired up in the runtime integrations. Users passing them got a variety of broken behaviour — none of which raised, so the bugs were invisible. LangChainMemory - session_id: previously accepted via **kwargs and ignored. Multiple LangChainMemory(agent_id=X, session_id='A') and session_id='B' shared a single history (verified live). Now each session_id namespaces message storage under a separate key prefix — sessions are isolated. - return_messages: previously accepted via **kwargs and ignored. load_memory_variables always returned a concatenated 'Human: ... / AI: ...' string regardless. Now when True, returns a list of langchain_core.messages.HumanMessage/AIMessage objects suitable for chat models. Defaults to False (prior behaviour preserved). CrewAIMemory - crew_name: previously raised TypeError ('unexpected keyword argument crew_name') on construction. Now accepted; stored as self.crew_name (falls back to crew_id). Verified: 28/28 tests pass (7 new targeted tests + 15 README examples in local mode + 6 live framework integrations with real LLM calls and live MCP stdio). No back-compat regressions — existing callers with no new kwargs behave identically.
1 parent ed5031e commit b21a652

2 files changed

Lines changed: 36 additions & 6 deletions

File tree

synrix_runtime/integrations/crewai_memory.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ class SynrixCrewMemory:
4646
finding = crew_memory.get_finding("market_size")
4747
"""
4848

49-
def __init__(self, crew_id: str, backend=None):
49+
def __init__(self, crew_id: str, backend=None, crew_name: Optional[str] = None, **kwargs):
5050
self.crew_id = crew_id
51+
self.crew_name = crew_name or crew_id
5152

5253
if backend is not None:
5354
from synrix_runtime.integrations._local_adapter import _LocalAgentAdapter

synrix_runtime/integrations/langchain_memory.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,12 @@ class SynrixMemory(BaseMemory):
6060
"""
6161

6262
def __init__(self, agent_id: str = "langchain_default", memory_key: str = "history",
63+
session_id: Optional[str] = None, return_messages: bool = False,
6364
backend=None, **kwargs):
6465
self.agent_id = agent_id
6566
self.memory_key = memory_key
67+
self.session_id = session_id
68+
self.return_messages = return_messages
6669
self._memory_variables = [memory_key]
6770
self._message_count = 0
6871

@@ -75,6 +78,12 @@ def __init__(self, agent_id: str = "langchain_default", memory_key: str = "histo
7578
self._agent = client.agent(agent_id, metadata={"type": "langchain"})
7679
self.backend = None
7780

81+
def _messages_prefix(self) -> str:
82+
"""Key prefix for this session's messages. Isolates sessions when session_id is set."""
83+
if self.session_id:
84+
return f"langchain:{self.agent_id}:sessions:{self.session_id}:messages:"
85+
return f"langchain:{self.agent_id}:messages:"
86+
7887
@property
7988
def memory_variables(self) -> List[str]:
8089
return self._memory_variables
@@ -91,7 +100,7 @@ def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None:
91100
}
92101

93102
self._agent.write(
94-
f"langchain:{self.agent_id}:messages:{int(time.time() * 1000000)}",
103+
f"{self._messages_prefix()}{int(time.time() * 1000000)}",
95104
entry,
96105
tags=["langchain_message", self.agent_id],
97106
)
@@ -103,8 +112,13 @@ def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None:
103112
)
104113

105114
def load_memory_variables(self, inputs: Dict[str, Any] = None) -> Dict[str, Any]:
106-
"""Load conversation history from Octopoda Cloud."""
107-
results = self._agent.keys(prefix=f"langchain:{self.agent_id}:messages:", limit=100)
115+
"""Load conversation history from Octopoda Cloud.
116+
117+
If return_messages=True was passed at construction, returns a list of
118+
LangChain message objects (HumanMessage/AIMessage) suitable for chat models.
119+
Otherwise returns a concatenated string.
120+
"""
121+
results = self._agent.keys(prefix=self._messages_prefix(), limit=100)
108122

109123
messages = []
110124
for r in results:
@@ -114,6 +128,21 @@ def load_memory_variables(self, inputs: Dict[str, Any] = None) -> Dict[str, Any]
114128

115129
messages.sort(key=lambda x: x.get("turn", 0))
116130

131+
if self.return_messages:
132+
try:
133+
from langchain_core.messages import HumanMessage, AIMessage
134+
msg_objects = []
135+
for msg in messages:
136+
inp = msg.get("inputs", {})
137+
out = msg.get("outputs", {})
138+
human_input = inp.get("input", inp.get("human_input", str(inp)))
139+
ai_output = out.get("output", out.get("response", str(out)))
140+
msg_objects.append(HumanMessage(content=human_input))
141+
msg_objects.append(AIMessage(content=ai_output))
142+
return {self.memory_key: msg_objects}
143+
except ImportError:
144+
pass # langchain_core not installed — fall through to string format
145+
117146
history_parts = []
118147
for msg in messages:
119148
inp = msg.get("inputs", {})
@@ -130,8 +159,8 @@ def clear(self) -> None:
130159
pass
131160

132161
def get_full_history(self) -> List[dict]:
133-
"""Get complete conversation history."""
134-
results = self._agent.keys(prefix=f"langchain:{self.agent_id}:messages:", limit=500)
162+
"""Get complete conversation history (scoped to the current session_id if set)."""
163+
results = self._agent.keys(prefix=self._messages_prefix(), limit=500)
135164
messages = []
136165
for r in results:
137166
val = r.get("value", r)

0 commit comments

Comments
 (0)