Repository navigation
feat(topic): add sqlite topic store parity - #634
Conversation
Add SQLite TopicStore support for the local durable bundle and wire Coding Agent product paths to select SQLite or PG topic stores consistently. Cover local durable schema upgrade, path normalization, fenced topic mutations, checkpoint restore reconciliation, semantic rebuild availability, console wiring, Helm defaults, and shared SQLite/PG TopicStore contract behavior. Verification: - uv run pytest tests/cli/test_local_runtime.py -q - uv run pytest tests/coding_agent/test_topic_store_contract.py tests/coding_agent/test_topic_store.py tests/coding_agent/test_sqlite_topic_store.py -q - uv run pytest tests/coding_agent/test_sqlite_local_durable_fencing.py -k 'topic or upgrade or restore' -q - uv run pytest tests/ui/test_session_manager_runtime.py -k 'topic_store or semantic_topic_store or checkpoint_restore' -q - uv run pytest tests/coding_agent/test_runtime_preparation.py -k 'semantic_topic_store or local_daemon' -q - uv run pytest tests/ui/test_http_server.py -k 'console_topic or normalizes_paths_local_for_sqlite_owner_store' -q - uv run pytest tests/coding_agent/test_semantic_maintenance.py -k 'factory or topic_store_available or rebuild' -q - uv run pytest tests/deploy/test_helm_chart.py -k 'topic_store or memory_semantic or storage' -q - uv run ruff check <changed python files> - uv run ruff format --check <changed python files> - git diff --check
|
Warning Review limit reached
More reviews will be available in 27 minutes and 29 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThe PR adds a SQLite-backed topic store, fenced local topic durability, and backend-based topic-store selection through session, CLI, and HTTP paths. It also threads optional semantic topic stores into runtime preparation and checkpoint restore flows, with matching docs and tests. ChangesTopic Store and Semantic Wiring
Sequence Diagram(s)sequenceDiagram
participant SessionManager
participant LocalDaemonRuntimePreparationService
participant RuntimeCheckpointRestoreService
participant CheckpointRuntimeBuilder
participant create_agent_for_session
participant SemanticMemoryMaintainer
SessionManager->>SessionManager: selected_topic_store()
SessionManager->>LocalDaemonRuntimePreparationService: semantic_topic_store_factory=self.selected_topic_store
LocalDaemonRuntimePreparationService->>create_agent_for_session: semantic_topic_store=...
SessionManager->>RuntimeCheckpointRestoreService: semantic_topic_store_factory=self.selected_topic_store
RuntimeCheckpointRestoreService->>CheckpointRuntimeBuilder: semantic_topic_store_factory=...
CheckpointRuntimeBuilder->>create_agent_for_session: semantic_topic_store=...
SessionManager->>SemanticMemoryMaintainer: semantic_memory_maintainer(session_id)
SemanticMemoryMaintainer->>SessionManager: selected_topic_store()
Estimated code review effort🎯 5 (Critical) | ⏱️ ~90+ minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Restore HTTP session store behavior so PG session storage keeps its dedicated pool semantics while TopicStore selection continues to use SessionManager's durable PG pool. Verification: - uv run pytest tests/ui/test_session_manager_public_api.py::test_session_manager_creates_dedicated_pg_pool_for_http_session_store tests/ui/test_session_manager_public_api.py::test_session_manager_http_session_store_does_not_reuse_injected_pg_pool tests/ui/test_session_manager_runtime.py::test_selected_topic_store_returns_pg_topic_store_for_pg_durable_mode -q - uv run ruff check src/coding_agent/server/session_manager.py tests/ui/test_session_manager_runtime.py - uv run ruff format --check src/coding_agent/server/session_manager.py tests/ui/test_session_manager_runtime.py - git diff --check
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@coding-agent/src/coding_agent/stores/durable_local.py`:
- Around line 1264-1268: The restore reconciliation logic currently uses only
entry_count to decide which topics to drop, which can incorrectly remove topics
that existed at checkpoint time but were finalized later. Update
_reconcile_topics_after_checkpoint_restore and its callers to use
snapshot.meta.created_at alongside tape_id and entry_count, so the restore path
can distinguish topics created/closed after the checkpoint from preexisting ones
and reopen or delete them correctly. Make sure the deletion condition and reopen
handling in the affected restore flow are based on checkpoint time, not just
sequence bounds.
In `@coding-agent/src/coding_agent/topics/store.py`:
- Around line 718-723: The SQLite work in the store is still running on the
request event loop, so calls like _connect and the read paths used by
_console_topic_summaries_from_store() and _console_topic_detail_from_store() can
block HTTP traffic during the busy_timeout. Move the sqlite3-backed read
operations in Store behind asyncio.to_thread or the existing executor pattern,
or replace them with an async SQLite client, and apply the same off-thread
approach to the related read methods called in the other affected store ranges.
- Around line 668-677: The topic anchor upsert/schema currently only enforces
topic_id, so a TopicAnchorRecord can be saved with a tape_id that does not
belong to the owning topic. Update the topic_anchors write path in topic store
logic to validate the parent topic’s tape_id before persisting, matching the
guard already used in durable_local.py’s anchor handling. Mirror the same
protection in PGTopicStore and add/adjust contract coverage so mismatched
tape_id anchors are rejected consistently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0fdbb50f-bb3e-4332-8342-572508600b89
📒 Files selected for processing (22)
coding-agent/docs/AGENTKIT-ARCHITECTURE.mdcoding-agent/docs/CODING-AGENT-ARCHITECTURE.mdcoding-agent/docs/topic_layer/USAGE.mdcoding-agent/src/coding_agent/cli/local_runtime.pycoding-agent/src/coding_agent/runs/checkpoint_runtime.pycoding-agent/src/coding_agent/runs/runtime_checkpoint_restore.pycoding-agent/src/coding_agent/runs/runtime_preparation.pycoding-agent/src/coding_agent/server/http_server.pycoding-agent/src/coding_agent/server/session_manager.pycoding-agent/src/coding_agent/stores/durable_local.pycoding-agent/src/coding_agent/topics/store.pycoding-agent/tests/cli/test_local_runtime.pycoding-agent/tests/coding_agent/test_checkpoint_runtime_builder.pycoding-agent/tests/coding_agent/test_runtime_preparation.pycoding-agent/tests/coding_agent/test_semantic_maintenance.pycoding-agent/tests/coding_agent/test_sqlite_local_durable_fencing.pycoding-agent/tests/coding_agent/test_sqlite_topic_store.pycoding-agent/tests/coding_agent/test_topic_store.pycoding-agent/tests/coding_agent/test_topic_store_contract.pycoding-agent/tests/deploy/test_helm_chart.pycoding-agent/tests/ui/test_http_server.pycoding-agent/tests/ui/test_session_manager_runtime.py
Summary
Verification
uv run pytest tests/cli/test_local_runtime.py -quv run pytest tests/coding_agent/test_topic_store_contract.py tests/coding_agent/test_topic_store.py tests/coding_agent/test_sqlite_topic_store.py -quv run pytest tests/coding_agent/test_sqlite_local_durable_fencing.py -k "topic or upgrade or restore" -quv run pytest tests/ui/test_session_manager_runtime.py -k "topic_store or semantic_topic_store or checkpoint_restore" -quv run pytest tests/coding_agent/test_runtime_preparation.py -k "semantic_topic_store or local_daemon" -quv run pytest tests/ui/test_http_server.py -k "console_topic or normalizes_paths_local_for_sqlite_owner_store" -quv run pytest tests/coding_agent/test_semantic_maintenance.py -k "factory or topic_store_available or rebuild" -quv run pytest tests/deploy/test_helm_chart.py -k "topic_store or memory_semantic or storage" -quv run ruff check <changed python files>uv run ruff format --check <changed python files>git diff --checkReview Gate
No P1/P2 findings.ADR / Task Packet
.opencode/prompts/tasks/sqlite-topic-store-parity-task-packet.md.Summary by CodeRabbit
New Features
Bug Fixes
~-based paths resolve correctly.Documentation