feat: storage abstraction, PostgreSQL backend, and memo mirror contract (#69) - #143
Conversation
…ct (#69) Core storage contract changes: - `AgentrailSessionStore` gains optional memo document and tool-result artifact methods (read/write/append/list); required for non-filesystem backends to enable sandbox /workspace/memo/** access - `AgentrailSessionStore` no longer exposes `getSessionDir`; removed from all host call sites and developer docs - `MemoryIndex` paths use canonical /workspace/memo/... form only SandboxManager memo mirror: - New `SandboxMemoProvider` interface with bidirectional read/write methods - At sandbox creation: snapshots memo docs + tool-result artifacts into a temp dir; bind-mounts read-only so Bash cannot bypass Write/Edit tools - New `writeMemoBack(sessionId, containerPath, content)` — Write/Edit tools call this after every successful memo-path write to keep store in sync - New `refreshMemoMirror` / `refreshUserMemoMirrorForAllSessions` — host calls these after compaction artifact writes or USER.md consolidation so live containers see updated content immediately - `SandboxEntry` stores tenantId/userId/sessionId for write-back routing UserMemoryConsolidationService: - New optional `mirrorRefresher: UserMemoMirrorRefresher` constructor param; calls `refreshUserMemoMirrorForAllSessions` after every USER.md write memoryContext capability: - `MemorySessionContext` gains `sessionRef` field - `MemoryContextBuilders` gains `writeToolResultArtifact` builder; wired through to `DefaultCapabilityContextOptions.writeToolResultArtifact` so compaction artifacts are actually persisted (previous `sessionDir` path was never populated and silently dropped all artifacts) - `compactMessages` ctx type updated: `sessionDir` removed, replaced by `writeToolResultArtifact` callback OrchestrationPersistence: - Adds `loadAgentHistory` / `writeAgentHistory` for sub-agent message history across turn boundaries - Worker process supports dynamic postgres persistence init via `storageConfig` in `WorkerInitMessage` InspectorDataSource: - New `InspectorDataSource` interface + `createFilesystemInspectorDataSource` - `createInspectorRoute` accepts `InspectorDataSource` (string path deprecated) - `createAgentApp` `inspector` option now takes `true | InspectorDataSource` New package: @agentrail/storage-postgres: - `PostgresSessionStore` — full store including memo docs and artifacts - `PostgresSessionTraceStore` - `PostgresOrchestrationPersistence` — includes agent history - `PostgresInspectorDataSource` - `buildSchemaDDL(schema?)` for idempotent table creation - `createSqlClient(options)` connection pool helper - Full test suite via @testcontainers/postgresql playground-server example: - Updated `compactMessages` to use `writeToolResultArtifact` + mirror refresh - Stream route uses cached trace store (one per session, not one per event) - Inspector route switched to `createFilesystemInspectorDataSource` Docs: - New guide: docs/guides/build-a-storage-backend.md covering all 6 contracts and mirror refresh responsibilities - session-store.md, configure-sessions.md, inspector-route.md updated for new API; getSessionDir removed from public contract docs - playground-server.md examples updated to new patterns - docs/tools/bash.md + sandboxed-bash description: memo paths are read-only Signed-off-by: yai-dev <sunzhenyucn@gmail.com>
Signed-off-by: yai-dev <sunzhenyucn@gmail.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive storage abstraction layer across the Agentrail ecosystem, enabling support for non-filesystem backends and providing a reference PostgreSQL implementation. Key changes include breaking updates to the session and orchestration persistence contracts, the introduction of the @agentrail/storage-postgres package, and a new InspectorDataSource abstraction to decouple the Inspector API from the local filesystem. Additionally, the SandboxManager was enhanced to support bidirectional memo synchronization for database-backed stores. Feedback primarily addressed inconsistencies in default token budget values between the core implementation and the new PostgreSQL store, which should be aligned to ensure predictable behavior.
| @@ -512,67 +525,32 @@ export class SessionManager { | |||
| compressedCount: number; | |||
| async loadMessagesWithBudget( | ||
| tenantId: string, | ||
| sessionId: string, | ||
| tokenBudget = 40_000, |
Summary
AgentrailSessionStoregains optional memo-document and tool-result-artifact methods; all code paths that previously relied onsessionDirare refactored to use the new store API.@agentrail/storage-postgresas the first drop-in reference implementation (session, trace, orchestration, inspector — all without filesystem coupling), with a full test suite via@testcontainers/postgresql./workspace/memo/**as a read-only bind-mount inside sandboxes; Write/Edit tools callwriteMemoBackto sync writes back to the store, andrefreshMemoMirror/refreshUserMemoMirrorForAllSessionskeep live containers up-to-date after host-side compaction or USER.md consolidation.Changed packages
@agentrail/coreSessionRefinMemorySessionContext,MemoryIndexpath semantics@agentrail/capabilitiesSandboxMemoProvider, read-only memo mounts,writeToolResultArtifactbuilder, orchestration agent history@agentrail/appInspectorDataSource,UserSessionLister,UserMemoMirrorRefresher,compactToolResultswired to store@agentrail/storage-postgresTest plan
pnpm build:packagespassespnpm testpasses (includes@agentrail/storage-postgresdocker-based tests via@testcontainers/postgresql— theubuntu-latestCI runner has Docker available)pnpm typecheckpassespnpm format:checkpassesSigned-off-by: yai-dev <sunzhenyucn@gmail.com>)