Bug: Canvas Memory tab reads K/V store, agent commit_memory writes are invisible #1734

Closed
opened 2026-05-23 19:55:50 +00:00 by hongming · 0 comments
Owner

Bug: Canvas Memory tab reads K/V store, agent commit_memory writes are invisible

Symptom

Agent says "I committed a memory" in chat, the call returns success, but the workspace's Memory tab shows nothing.

Root cause

canvas/src/components/tabs/MemoryTab.tsx:60 fetches from the K/V endpoint:

const data = await api.get<MemoryEntry[]>(`/workspaces/${workspaceId}/memory`);

That endpoint (workspace-server/internal/handlers/memory.go:30) reads the workspace_memory table — the K/V store backing memory_set / memory_get. It is not where agent commit_memory writes end up.

Where agent writes actually go today:

  • commit_memory (legacy MCP name) → mcp_tools_memory_legacy_shim.go → either v2 plugin namespace OR direct SQL on agent_memories (v1 fallback). See #1733 — v2 is unset on the controlplane, so today every write lands in agent_memories.
  • commit_memory_v2 → v2 plugin's memory_records table (when wired; currently no-op in prod).

So:

Store Tab that displays it
workspace_memory (K/V) MemoryTab.tsx (the user-facing tab)
agent_memories (v1) nothing in the canvas
v2 plugin memory_records MemoryInspectorPanel.tsx (separate panel)

The Memory tab and the agent-write path haven't been pointed at the same store since the v1→v2 split started.

Additional findings while investigating

  • MemoryInspectorPanel.tsx:216 correctly calls /workspaces/:id/v2/memories, so it would show v2 writes — but v2 is currently unset on the controlplane (see #1733), so the panel is also empty.
  • MemoryTab.tsx:37-262 embeds an <iframe> reading NEXT_PUBLIC_AWARENESS_URL — unrelated to the memory display but more dead surface. Tracked in a separate RFC.
  • No optimistic UI hook exists: ChatTab.tsx / activityLog.ts do not watch for commit_memory / commit_memory_v2 tool results to refresh the tab. Even after we point the tab at the right store, the user will have to refresh to see new entries until that hook lands.

Fix

Gated on #1733 landing first. After v2 is wired in production:

  1. Replace the fetch in MemoryTab.tsx:60 with /workspaces/${workspaceId}/v2/memories.
  2. Render the v2 memory shape (namespace, kind, source, embedding-score where available). Reuse the row component from MemoryInspectorPanel.tsx to keep one layout.
  3. Add a refetch hook on commit_memory* tool-result completion in the chat pipeline (likely a hook into activityLog.ts consumers).
  4. Delete the K/V write UI in this tab — after the K/V deprecation in #1733 PR-B, the K/V endpoints stop existing.
  5. Remove the awareness iframe block (handled in the awareness-removal RFC).

Reproduction

  1. Open a workspace in the canvas.
  2. Ask the agent: "Commit a memory: testing 123."
  3. Agent confirms success.
  4. Open the Memory tab.
  5. Observe: empty list. Expected: the new memory.

Tier / approval

area:memory area:frontend tier:medium-risk — user-visible, but the fix is well-scoped once #1733 unblocks it.

References

  • canvas/src/components/tabs/MemoryTab.tsx:60 (smoking gun)
  • canvas/src/components/tabs/MemoryInspectorPanel.tsx:216 (correct fetch)
  • workspace-server/internal/handlers/memory.go:30 (K/V handler)
  • workspace-server/internal/handlers/mcp_tools_memory_v2.go:165 (v2 search handler)
  • Blocking: #1733 (SSOT consolidation)
# Bug: Canvas Memory tab reads K/V store, agent `commit_memory` writes are invisible ## Symptom Agent says "I committed a memory" in chat, the call returns success, but the workspace's **Memory** tab shows nothing. ## Root cause `canvas/src/components/tabs/MemoryTab.tsx:60` fetches from the K/V endpoint: ```ts const data = await api.get<MemoryEntry[]>(`/workspaces/${workspaceId}/memory`); ``` That endpoint (`workspace-server/internal/handlers/memory.go:30`) reads the `workspace_memory` table — the K/V store backing `memory_set` / `memory_get`. It is **not** where agent `commit_memory` writes end up. Where agent writes actually go today: - `commit_memory` (legacy MCP name) → `mcp_tools_memory_legacy_shim.go` → either v2 plugin namespace OR direct SQL on `agent_memories` (v1 fallback). See #1733 — v2 is unset on the controlplane, so today every write lands in `agent_memories`. - `commit_memory_v2` → v2 plugin's `memory_records` table (when wired; currently no-op in prod). So: | Store | Tab that displays it | |---|---| | `workspace_memory` (K/V) | **`MemoryTab.tsx`** (the user-facing tab) | | `agent_memories` (v1) | nothing in the canvas | | v2 plugin `memory_records` | `MemoryInspectorPanel.tsx` (separate panel) | The Memory tab and the agent-write path haven't been pointed at the same store since the v1→v2 split started. ## Additional findings while investigating - `MemoryInspectorPanel.tsx:216` correctly calls `/workspaces/:id/v2/memories`, so it would show v2 writes — but v2 is currently unset on the controlplane (see #1733), so the panel is also empty. - `MemoryTab.tsx:37-262` embeds an `<iframe>` reading `NEXT_PUBLIC_AWARENESS_URL` — unrelated to the memory display but more dead surface. Tracked in a separate RFC. - No optimistic UI hook exists: `ChatTab.tsx` / `activityLog.ts` do not watch for `commit_memory` / `commit_memory_v2` tool results to refresh the tab. Even after we point the tab at the right store, the user will have to refresh to see new entries until that hook lands. ## Fix Gated on #1733 landing first. After v2 is wired in production: 1. Replace the fetch in `MemoryTab.tsx:60` with `/workspaces/${workspaceId}/v2/memories`. 2. Render the v2 memory shape (namespace, kind, source, embedding-score where available). Reuse the row component from `MemoryInspectorPanel.tsx` to keep one layout. 3. Add a refetch hook on `commit_memory*` tool-result completion in the chat pipeline (likely a hook into `activityLog.ts` consumers). 4. Delete the K/V write UI in this tab — after the K/V deprecation in #1733 PR-B, the K/V endpoints stop existing. 5. Remove the awareness iframe block (handled in the awareness-removal RFC). ## Reproduction 1. Open a workspace in the canvas. 2. Ask the agent: "Commit a memory: testing 123." 3. Agent confirms success. 4. Open the Memory tab. 5. Observe: empty list. Expected: the new memory. ## Tier / approval `area:memory` `area:frontend` `tier:medium-risk` — user-visible, but the fix is well-scoped once #1733 unblocks it. ## References - `canvas/src/components/tabs/MemoryTab.tsx:60` (smoking gun) - `canvas/src/components/tabs/MemoryInspectorPanel.tsx:216` (correct fetch) - `workspace-server/internal/handlers/memory.go:30` (K/V handler) - `workspace-server/internal/handlers/mcp_tools_memory_v2.go:165` (v2 search handler) - Blocking: #1733 (SSOT consolidation)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#1734