Conversation Service
Relevant source files
The following files were used as context for generating this wiki page:
- server/services/conversation/log.py
- server/services/conversation/summarization/summarizer.py
- server/services/conversation/summarization/working_memory_log.py
- server/services/conversation/summarization/prompt_builder.py
- server/agents/interaction_agent/runtime.py
- server/models/chat.py
- web/app/page.tsx
The Conversation Service is a core component of the OpenPoke platform responsible for managing the persistence, retrieval, and summarization of all interactions between users and agents. It acts as the system's memory, providing a consistent transcript for the Interaction Agent while optimizing context window usage through a sophisticated "Working Memory" summarization engine.
The service handles several message types, including user inputs (user_message), assistant replies (poke_reply), background agent updates (agent_message), and internal orchestration markers (wait). By maintaining both a raw append-only log and a condensed summary, the service ensures that long-running conversations remain coherent and performant for Large Language Model (LLM) processing.
Sources: server/services/conversation/log.py:118-142, server/services/conversation/summarization/working_memory_log.py:25-30
Architecture and Data Persistence
The service utilizes a two-tier storage architecture to manage conversation state: the Conversation Log and the Working Memory Log.
Conversation Log
The primary source of truth is an append-only flat file (poke_conversation.log) stored in the data/conversation/ directory. Each entry is wrapped in XML-style tags containing the message content, a timestamp in the user's timezone, and optional metadata.
- Storage Path:
server/data/conversation/poke_conversation.log - Format:
<tag timestamp="YYYY-MM-DD HH:MM:S">encoded_payload</tag> - Encoding: Payloads are HTML-escaped and newlines are collapsed to
\nto maintain a single-line-per-entry format.
Sources: server/services/conversation/log.py:18-45, server/services/conversation/log.py:59-65
Working Memory Log
To prevent LLM context overflow, the service maintains a "Working Memory" (poke_working_memory.log). This file stores the current high-level summary of the conversation alongside only the most recent unsummarized messages.
Sources: server/services/conversation/summarization/working_memory_log.py:25-30, server/services/conversation/summarization/working_memory_log.py:80-123
Data Flow Diagram
The following diagram illustrates how messages flow from the user or agents into the persistence layer and through the summarization process.
Conversation Summarization Engine
The summarization engine is a background service that condenses older parts of the conversation into a structured "briefing." This is triggered automatically when the number of unsummarized entries exceeds a configurable threshold.
Summarization Process
- Trigger: Every time a message is recorded, the system checks if
summarization_enabledis true. - Threshold Check: If unsummarized entries >
conversation_summary_threshold+tail_size, a summarization job is scheduled. - Prompt Construction: The
build_summarization_promptfunction combines the previous summary with the new batch of logs. - LLM Processing: An LLM (via OpenRouter) follows strict instructions to rebuild the "Working Memory Briefing" across five specific sections: Timeline & Commitments, Pending & Follow-ups, Routines & Recurring, Preferences & Profile, and Context & Notes.
- State Update: The new summary is written to the Working Memory Log, and the
last_indexof summarized messages is updated.
Sources: server/services/conversation/summarization/summarizer.py:80-125, server/services/conversation/summarization/prompt_builder.py:14-49
Summary Structure
The summarizer is forced to output a standardized format to ensure the Interaction Agent can always parse the history:
| Section | Description |
|---|---|
| Timeline & Commitments | Events, meetings, and travel with explicit timestamps. |
| Pending & Follow-ups | Open tasks, owners, next steps, and tracking IDs. |
| Routines & Recurring | Habits, reminders, and standing orders (e.g., Cadence). |
| Preferences & Profile | Stable user preferences (formats, brands, dietary needs). |
| Context & Notes | Strategic insights, risks, or configurations. |
Sources: server/services/conversation/summarization/prompt_builder.py:18-40
Messaging and Models
The service uses standard Pydantic models to ensure data integrity across the API and the internal loggers.
Chat Data Models
The ChatMessage model is used for both internal processing and API responses.
Sources: server/models/chat.py:10-25
| Field | Type | Description |
|---|---|---|
role | str | Either "user" or "assistant". |
content | str | The raw text of the message. |
timestamp | Optional[str] | ISO or formatted timestamp string. |
Message Type Logic
Different tags in the log signify different visibility and orchestration rules:
user_message: Visible in UI, sent by human.poke_reply: Visible in UI, sent by assistant.agent_message: Internal status from execution agents; summarized for user by Interaction Agent.wait: Silently added log entry to prevent redundant messaging; never shown to user.
Sources: server/services/conversation/log.py:118-142, server/agents/interaction_agent/runtime.py:214-230
API Integration
The frontend interacts with the Conversation Service through specific proxy routes that forward requests to the FastAPI backend.
Sequence: Sending and Retrieving Messages
This diagram shows the interaction between the React frontend and the backend conversation services.
Conclusion
The Conversation Service provides a robust foundation for the OpenPoke multi-agent system by balancing the need for deep historical context with the technical limitations of LLM context windows. Through its dual-log architecture and automated summarization engine, it maintains a persistent, information-dense "Working Memory" that allows the assistant to act as a truly informed "chief-of-staff" for the user.
Sources: server/services/conversation/summarization/summarizer.py:115-135, server/services/conversation/summarization/prompt_builder.py:14-16