From 630d93ef922a7ff2a212659e60642efcd664fc1f Mon Sep 17 00:00:00 2001 From: Prathap <436prathap@gmail.com> Date: Tue, 31 Mar 2026 19:16:35 +0530 Subject: [PATCH 1/3] fix(channels): push session history into agent context on channel messages --- src/openjarvis/system.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/openjarvis/system.py b/src/openjarvis/system.py index a9ade2f8..e39a1c40 100644 --- a/src/openjarvis/system.py +++ b/src/openjarvis/system.py @@ -63,6 +63,7 @@ class JarvisSystem: tools: Optional[List[str]] = None, system_prompt: Optional[str] = None, operator_id: Optional[str] = None, + prior_messages: Optional[List[Message]] = None, ) -> Dict[str, Any]: """Execute a query through the system and return a result dict.""" if temperature is None: @@ -106,6 +107,7 @@ class JarvisSystem: max_tokens, system_prompt=system_prompt, operator_id=operator_id, + prior_messages=prior_messages, ) # Direct engine mode @@ -133,6 +135,7 @@ class JarvisSystem: *, system_prompt=None, operator_id=None, + prior_messages=None, ) -> Dict[str, Any]: """Run through an agent.""" from openjarvis.agents._stubs import AgentContext @@ -153,6 +156,11 @@ class JarvisSystem: # Build context ctx = AgentContext() + # Seed prior conversation turns (channel session history) + if prior_messages: + for msg in prior_messages: + ctx.conversation.add(msg) + # Inject memory context messages into the agent conversation if messages and len(messages) > 1: # Context messages were prepended by inject_context @@ -297,7 +305,6 @@ class JarvisSystem: A connected :class:`~openjarvis.channels._stubs.BaseChannel` instance whose ``on_message`` method accepts a callable. """ - from openjarvis.agents._stubs import AgentContext from openjarvis.core.types import Message, Role from openjarvis.sessions.session import SessionStore @@ -320,14 +327,13 @@ class JarvisSystem: channel_user_id=cm.sender, ) - # Rebuild prior conversation turns into AgentContext - ctx = AgentContext() + prior_msgs: List[Message] = [] for sm in session.messages: try: role = Role(sm.role) except ValueError: role = Role.USER - ctx.conversation.add(Message(role=role, content=sm.content)) + prior_msgs.append(Message(role=role, content=sm.content)) reply = "" try: @@ -336,10 +342,15 @@ class JarvisSystem: cm.content, context=False, agent=_system.agent_name, + prior_messages=prior_msgs, ) reply = result.get("content", "") else: - result = _system.ask(cm.content, context=False) + result = _system.ask( + cm.content, + context=False, + prior_messages=prior_msgs, + ) reply = result.get("content", "") except Exception: logger.exception("Channel message handler error") From 35fa18fd1c7c4725d6185c3bc65bf6c1787eb9e8 Mon Sep 17 00:00:00 2001 From: Prathap <436prathap@gmail.com> Date: Tue, 31 Mar 2026 19:25:29 +0530 Subject: [PATCH 2/3] add test case --- tests/sessions/test_wire_channel_history.py | 115 ++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 tests/sessions/test_wire_channel_history.py diff --git a/tests/sessions/test_wire_channel_history.py b/tests/sessions/test_wire_channel_history.py new file mode 100644 index 00000000..1ee0e38d --- /dev/null +++ b/tests/sessions/test_wire_channel_history.py @@ -0,0 +1,115 @@ +"""Tests for wire_channel session history""" + +from __future__ import annotations + +from types import SimpleNamespace +from unittest.mock import MagicMock + +import pytest + +from openjarvis.core.config import JarvisConfig +from openjarvis.core.events import EventBus +from openjarvis.core.types import Role +from openjarvis.system import JarvisSystem + + +@pytest.fixture() +def minimal_system(): + engine = MagicMock() + engine.generate.return_value = {"content": "ok", "usage": {}} + return JarvisSystem( + config=JarvisConfig(), + bus=EventBus(), + engine=engine, + engine_key="mock", + model="mock-model", + agent_name="none", + ) + + +class TestWireChannelHistory: + def test_prior_messages_passed_to_ask(self, tmp_path, minimal_system): + """Session history is forwarded as prior_messages to ask().""" + from openjarvis.sessions.session import SessionStore + + db = tmp_path / "sessions.db" + store = SessionStore(db_path=db) + minimal_system.session_store = store + + session_key = "telegram:chat123" + session = store.get_or_create( + session_key, channel="telegram", channel_user_id="u1" + ) + store.save_message(session.session_id, "user", "hello", channel="telegram") + store.save_message( + session.session_id, "assistant", "hi there", channel="telegram" + ) + + captured: list = [] + + def capturing_ask(query, **kwargs): + captured.append(kwargs.get("prior_messages", [])) + return {"content": "reply"} + + minimal_system.ask = capturing_ask + + bridge = MagicMock() + handler_ref: list = [] + + def capture_handler(fn): + handler_ref.append(fn) + + bridge.on_message = capture_handler + minimal_system.wire_channel(bridge) + + cm = SimpleNamespace( + channel="telegram", + conversation_id="chat123", + sender="u1", + content="second message", + ) + handler_ref[0](cm) + + assert len(captured) == 1 + msgs = captured[0] + assert len(msgs) == 2 + assert msgs[0].role == Role.USER + assert msgs[0].content == "hello" + assert msgs[1].role == Role.ASSISTANT + assert msgs[1].content == "hi there" + + def test_empty_session_passes_empty_prior_messages(self, tmp_path, minimal_system): + """First message in a new session passes prior_messages=[].""" + from openjarvis.sessions.session import SessionStore + + db = tmp_path / "sessions.db" + store = SessionStore(db_path=db) + minimal_system.session_store = store + + captured: list = [] + + def capturing_ask(query, **kwargs): + captured.append(kwargs.get("prior_messages", None)) + return {"content": "reply"} + + minimal_system.ask = capturing_ask + + bridge = MagicMock() + handler_ref: list = [] + + def capture_handler(fn): + handler_ref.append(fn) + + bridge.on_message = capture_handler + minimal_system.wire_channel(bridge) + + cm = SimpleNamespace( + channel="telegram", + conversation_id="new-chat", + sender="u2", + content="first message", + ) + handler_ref[0](cm) + + assert len(captured) == 1 + assert captured[0] == [] From 670069ccdb213129e1324b6898b905cbc3780dee Mon Sep 17 00:00:00 2001 From: Prathap <436prathap@gmail.com> Date: Tue, 31 Mar 2026 19:27:26 +0530 Subject: [PATCH 3/3] fix linting issue --- src/openjarvis/connectors/slack_connector.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/openjarvis/connectors/slack_connector.py b/src/openjarvis/connectors/slack_connector.py index f7c4f0dc..65c8a715 100644 --- a/src/openjarvis/connectors/slack_connector.py +++ b/src/openjarvis/connectors/slack_connector.py @@ -25,7 +25,10 @@ from openjarvis.tools._stubs import ToolSpec _SLACK_API_BASE = "https://slack.com/api" _SLACK_AUTH_ENDPOINT = "https://slack.com/oauth/v2/authorize" -_SLACK_SCOPES = "channels:read,channels:history,groups:read,groups:history,im:read,im:history,mpim:read,mpim:history,users:read" +_SLACK_SCOPES = ( + "channels:read,channels:history,groups:read,groups:history," + "im:read,im:history,mpim:read,mpim:history,users:read" +) _DEFAULT_CREDENTIALS_PATH = str(DEFAULT_CONFIG_DIR / "connectors" / "slack.json") # ---------------------------------------------------------------------------