Home

mweinbach / agent-coworker

publicmweinbach/agent-coworker
Overview Code History Branches Pull requestsIssuesInsights
main
HomeOverview Code PRsIssues

SQLite-backed memory store, memory tool refactor, and websocket memory protocol (#38)

7 months ago

c9b1ded
Authored
Max Weinbach3/14/2026, 1:31:40 AM
* Polish injected memory prompt section copy

* fix: resolve memory store bugs and add missing tests

- Fix ID collision: upsert without explicit id now generates a UUID
  instead of always normalizing to 'memory', preventing data loss
- Fix legacy import: deduplicate filesToImport by normalized id with
  a seenIds set to prevent SQLITE_CONSTRAINT_PRIMARYKEY on files that
  normalize to the same slug (e.g. 'foo bar.md' and 'foo-bar.md')
- Fix memoryRequireApproval default mismatch: align types.ts doc
  comment and AgentSession fallback to false (consistent with config.ts)
- Add tests: write-without-key generates unique IDs, enableMemory:false
  disables memory tool in createTools, memoryRequireApproval approve/deny
  flows, and legacy import duplicate-id deduplication

Co-authored-by: Max Weinbach <mweinbach@users.noreply.github.com>

* Add desktop memory management UI and fix PR #38 feedback

- Fix legacy import duplicate normalized IDs (seenIds dedup)
- Refresh cached system prompt after websocket memory upsert/delete
- Refresh cached system prompt when memory enablement toggled via setConfig
- Catch and surface memory store failures (no unhandled rejections)
- Consistent memoryRequireApproval defaults (?? false) everywhere
- Add desktop Memory settings page with full CRUD wired to control socket

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix memory prompt failure handling and cover PR feedback

* Fix memory scope editing restriction

* Reset memory loading flag on errors

* Fix memory hot cache defaults and precedence

* fix: use INSERT OR IGNORE for legacy memory import to handle concurrent access

Concurrent sessions (e.g., two desktop windows opening the same workspace)
could both pass the legacy_import_done check before either inserts, causing
SQLITE_CONSTRAINT_PRIMARYKEY on the second writer. INSERT OR IGNORE makes
concurrent first-access idempotent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Max Weinbach <mweinbach@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

Parent49fa806

31 files changed
  • apps/desktop/src/app/store.actions.ts+2−0
  • apps/desktop/src/app/store.actions/memory.ts+105−0
  • apps/desktop/src/app/store.helpers.ts+4−0
  • apps/desktop/src/app/store.helpers/controlSocket.ts+32−14
  • apps/desktop/src/app/store.helpers/runtimeState.ts+2−0
  • apps/desktop/src/app/types.ts+11−1
  • apps/desktop/src/ui/settings/SettingsShell.tsx+2−0
apps/desktop/src/ui/settings/pages/MemoryPage.tsx
+228
−0
  • apps/desktop/test/memory-page.test.ts+77−0
  • apps/desktop/test/protocol-v2-events.test.ts+24−0
  • docs/websocket-protocol.md+46−0
  • src/config.ts+16−0
  • src/memoryStore.ts+264−0
  • src/prompt.ts+36−3
  • src/server/protocol.ts+13−1
  • src/server/protocolEventParser.ts+13−0
  • src/server/protocolParser.ts+25−0
  • src/server/session/AgentSession.ts+76−0
  • src/server/session/SessionContext.ts+1−1
  • src/server/session/SessionMetadataManager.ts+16−1
  • src/server/session/mcp/McpRegistryFlow.ts+7−1
  • src/server/startServer.ts+5−3
  • src/server/startServer/dispatchClientMessage.ts+6−0
  • src/tools/index.ts+1−1
  • src/tools/memory.ts+59−126
  • src/types.ts+12−0
  • tasks/lessons.md+2−0
  • tasks/todo.md+142−1
  • test/prompt.test.ts+57−13
  • test/session.test.ts+130−1
  • test/tools.test.ts+102−146