session-migrator
README.md
# session-migrator
[English](README.md) | [中文](README.zh-CN.md)
A cross-agent session memory migration layer: automatically migrate or compress a
conversation based on the target model's context window capacity.
## What problem does it solve
Agent 1 has a conversation in progress that needs to be handed off to Agent 2, but
the two agents use different models with different context windows. The rules are simple:
- If the target model **fits** the whole conversation → migrate as-is, no compression;
- If it **doesn't fit** → keep only the most valuable context (latest messages first).
## Directory structure
```
session-migrator/
├── session_migrator/
│ ├── context_windows.py # model capacity mapping table (the soul)
│ ├── exporter.py # session export/serialization + token estimation
│ ├── decision.py # decision engine: compare capacity → direct/compress
│ ├── compressors.py # compressor: budget truncation, keeps latest
│ ├── storage.py # shared storage: JSON files, per-workspace isolation
│ ├── codex_adapter.py # Codex session → Session adapter
│ ├── llm_summarizer.py # LLM topic summarization (deepseek/OpenAI-compatible)
│ ├── server.py # MCP server entry (exposes migration tools)
│ └── __init__.py
├── examples/
│ ├── demo.py # full demo, zero dependencies
│ ├── codex_to_workbuddy_demo.py # Codex → memory (truncation)
│ └── llm_summarize_demo.py # Codex → memory (LLM topic summarization)
├── tests/test_core.py # core logic tests
├── pyproject.toml
├── requirements.txt
└── LICENSE
```
## Quick start
### 1. Run the core logic first (zero dependencies)
```bash
python examples/demo.py
python tests/test_core.py
```
Both use only the standard library. No installation needed — you'll immediately see
"decision + compression + storage" working end to end.
### 2. Run as an MCP server
```bash
pip install mcp
python -m session_migrator.server
```
### 3. Connect to any MCP client
Using Claude Code as an example, add this to the project `.mcp.json` (or your global config):
```json
{
"mcpServers": {
"session-migrator": {
"command": "python",
"args": ["-m", "session_migrator.server"]
}
}
}
```
Cursor / Codex / WorkBuddy or any client that supports MCP stdio works the same way.
Once connected, the agent can call `model_context_window`, `list_known_models`, and
`migrate_session`.
### 4. Configure the LLM API (only needed for "topic summarization")
To compress a Codex session into structured memory, you need an OpenAI-compatible LLM.
deepseek / OpenAI / any service compatible with `/chat/completions` works — just set an env var:
```bash
export DEEPSEEK_API_KEY="sk-xxx" # or OPENAI_API_KEY
```
The three core MCP tools don't require it (they only do decision / truncation
compression, no LLM calls).
## MCP tools
| Tool | Purpose |
|---|---|
| `model_context_window(model)` | Query a model's context window capacity |
| `list_known_models()` | List built-in models and their capacities |
| `migrate_session(messages_json, source_model, target_model, ...)` | Run migration, returns decision + migrated messages + token before/after |
`migrate_session`'s `messages_json` looks like:
```json
[{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]
```
## Core concepts
### Decision engine `decide(session, target_model)`
The criterion is "can the target capacity fit the session's **actual token count**",
not simply comparing the two models' capacities — even if the target capacity is
smaller than the source model, a small session still migrates as-is.
### Compressor `TruncationCompressor`
The default implementation has zero external dependencies: it keeps whole messages
working backward from the latest, omits earlier ones that don't fit, and inserts a
placeholder note at the top (omitted count + preview of the earliest message).
## Topic summarization (Codex → memory)
Full pipeline for migrating a Codex session into structured memory (adapter + LLM):
```python
from session_migrator.codex_adapter import get_thread_meta, extract_rollout
from session_migrator.llm_summarizer import summarize_session
meta = get_thread_meta("your-codex-thread-id")
session = extract_rollout(meta["rollout_path"], meta["id"], meta["model"])
markdown = summarize_session(session, meta, target_chars=5000) # needs LLM key set first
```
Non-LLM truncation version: `codex_adapter.to_memory_markdown(session, meta)`.
## Model capacity table
`session_migrator/context_windows.py` ships a static mapping table (OpenAI / Anthropic /
Google / Chinese models). Note: these are **static fallback values** that may change as
providers update.
## Roadmap
- [x] LLM topic summarization (`llm_summarizer.py`, see "Topic summarization")
- [ ] Dynamic capacity fetching (call each provider's `/models` API)
- [ ] Headroom reversible compression (recall original text)
- [ ] Vector-store retrieval injection (on-demand retrieval)
- [ ] Precise token counting with tiktoken
## License
MIT
TDQS
A3.7/5.0
Scored across 3 tools
Disambiguation5/5
每个工具职责明确:一个查询具体模型容量,一个列出所有已知模型,一个执行会话迁移。三者之间没有功能重叠或模糊边界。
Naming Consistency4/5
list_known_models和migrate_session遵循动词_名词模式,但model_context_window是名词短语,缺少动词前缀,构成轻微偏差。整体命名仍可读且可预测。
Tool Count5/5
3个工具对于会话迁移这一窄领域非常合适,每个工具都服务于核心流程,没有冗余或缺失。
Completeness5/5
覆盖了迁移会话所需的全部关键操作:查看模型容量、列出已知模型、执行迁移并返回结果对比。没有明显的功能缺口。
Maintenance
ActivityMaintained
ResponsivenessNo issues