Skip to content

Add shared agent memory and ordered code graph context - #1097

Open
tirth8205 wants to merge 4 commits into
stagingfrom
feat/shared-agent-memory-lens
Open

tirth8205 wants to merge 4 commits into
stagingfrom
feat/shared-agent-memory-lens

Conversation

@tirth8205

@tirth8205 tirth8205 commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

User prompts from coding tools now accumulate in one persistent Agent memory graph per local workspace. Natural-language corrections and Forget update that graph, and context retrieval reads memory first before querying the separate existing code knowledge graph. Native chats remain source provenance rather than creating separate graphs.

The implementation is additive under agent-memory/, with separate commits for the SQLite/OpenAI API, portable CLI/MCP/hooks and code-graph adapter, Lovable source review mirror and documentation, and product-film/live-connection refinements. The existing Python graph engine and repository configuration are unchanged. The video source renders seven distinct animated scenes at native 4K with narration and music. Live mode retains the explicitly paired connection across reloads.

Validation: 84/84 offline synthetic tests pass in the exact PR subtree, covering shared ownership, user-only capture, provenance, migration/history restoration, idempotency, CAS, manual-edit protection, authenticated local API, provider boundaries and ordered retrieval. The local live workflow and original code-index retrieval were verified separately. The delivered video passes a complete decode and is exactly 60 seconds at 3840 by 2160 with H.264 video and stereo AAC audio. Run cd agent-memory && npm test to verify the standalone package.

Frontend files are a reviewed Lovable source mirror. Cloud deployment is outside this PR. Generated videos, audio, images, credentials, runtime databases and machine-specific launchers/configuration are excluded.

This PR is for review only; do not merge automatically.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

code-review-graph review

Overall risk: 0.85 (CRITICAL) — 500 changed function(s)/class(es), 29 affected flow(s), 325 test gap(s) (281 with no tested caller found, 44 reached only through a caller)

Risk-scored changes

Risk Level Symbol Location Tested
0.85 critical agent-memory/bridge/existing-graph.mjs::hash agent-memory/bridge/existing-graph.mjs:6 no
0.85 critical agent-memory/bridge/existing-graph.mjs::ExistingCodeGraph.signalGroup agent-memory/bridge/existing-graph.mjs:265 indirect
0.80 high agent-memory/bridge/api.mjs::configuration agent-memory/bridge/api.mjs:9 no
0.80 high agent-memory/bridge/client.mjs::sameSession agent-memory/bridge/client.mjs:123 no
0.80 high agent-memory/bridge/client.mjs::validateLayeredContext agent-memory/bridge/client.mjs:131 no
0.75 high agent-memory/bridge/client.mjs::MemoryBridge.context agent-memory/bridge/client.mjs:104 no
0.70 high agent-memory/bridge/api.mjs::api agent-memory/bridge/api.mjs:19 no
0.70 high agent-memory/bridge/api.mjs::safeError agent-memory/bridge/api.mjs:39 no
0.70 high agent-memory/bridge/client.mjs::MemoryBridge.flush agent-memory/bridge/client.mjs:85 no
0.65 medium agent-memory/backend/graph.mjs::normalize agent-memory/backend/graph.mjs:6 no

Affected execution flows

  • MemoryLens — criticality 0.71, 33 node(s) across 5 file(s)
  • main — criticality 0.71, 44 node(s) across 7 file(s)
  • resolve — criticality 0.56, 11 node(s) across 3 file(s)
  • cachedRevision — criticality 0.47, 6 node(s) across 2 file(s)
  • constructor — criticality 0.44, 3 node(s) across 1 file(s)
  • ...and 24 more affected flow(s)

Test gaps

  • agent-memory/backend/errors.mjs::ApiError (agent-memory/backend/errors.mjs:1)
  • agent-memory/backend/errors.mjs::ApiError.constructor (agent-memory/backend/errors.mjs:2)
  • agent-memory/backend/errors.mjs::invalid (agent-memory/backend/errors.mjs:9)
  • agent-memory/backend/errors.mjs::upstream (agent-memory/backend/errors.mjs:10)
  • agent-memory/backend/errors.mjs::stringField (agent-memory/backend/errors.mjs:12)
  • ...and 276 more with no direct test

Reached only through a caller

No test names these directly, but a tested caller reaches them along the call path shown. That is a path in the call graph, not a record of execution -- the caller's tests may never take this branch. Treat it as where to look, not as coverage: these count as gaps and are scored as untested.

  • agent-memory/bridge/api.mjs::required (agent-memory/bridge/api.mjs:5) — via agent-memory/bridge/hooks.mjs::referenceContext, 1 hop(s)
  • agent-memory/bridge/existing-graph.mjs::clipped (agent-memory/bridge/existing-graph.mjs:10) — via agent-memory/bridge/existing-graph.mjs::ExistingCodeGraph.retrieve, 2 hop(s)
  • agent-memory/bridge/existing-graph.mjs::searchQuery (agent-memory/bridge/existing-graph.mjs:23) — via agent-memory/bridge/existing-graph.mjs::ExistingCodeGraph.retrieve, 2 hop(s)
  • agent-memory/bridge/existing-graph.mjs::normalizedGraph (agent-memory/bridge/existing-graph.mjs:33) — via agent-memory/bridge/existing-graph.mjs::ExistingCodeGraph.retrieve, 2 hop(s)
  • agent-memory/bridge/existing-graph.mjs::ExistingCodeGraph.result (agent-memory/bridge/existing-graph.mjs:87) — via agent-memory/bridge/existing-graph.mjs::ExistingCodeGraph.retrieve, 2 hop(s)
  • ...and 39 more reached only through a caller

Token savings: this graph-backed report used ~67,695 fewer tokens (~40%) than reading every changed file in full (estimated, chars/4 approximation).

Note: analysis was capped at the configured maximum number of changed functions (set CRG_MAX_CHANGED_FUNCS to adjust).


Powered by code-review-graph — local-first analysis; no code leaves the CI runner.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Obsolete imports and workspace-contract mismatches prevent the frontend from loading, while additional memory-handling defects can restore forgotten preferences and exclude newly captured ones.

7 open issues
What changed in this PR

Adds a standalone agent-memory layer alongside the existing Python code graph. User prompts contribute to one workspace-wide memory graph, while retrieval reads memory before querying the separate code index.

Changes:

  • Adds a persistent SQLite API with provenance, corrections, forgetting, migration and concurrency protection.
  • Adds CLI, MCP and Codex-hook integration with private retry storage and ordered context retrieval.
  • Includes a Lovable source mirror, regression tests, setup documentation and 4K explainer source.
File Description
agent-memory/​tests/​layered-bridge.test.mjs Tests layered hook context and capability discovery.
agent-memory/​tests/​layered-api.test.mjs Tests retrieval ordering, readiness and revision conflicts.
agent-memory/​tests/​integration-bridge-api.test.mjs Exercises prompt capture through the bridge and API.
agent-memory/​tests/​backend-shared.test.mjs Tests shared ownership, provenance and legacy migration.
agent-memory/​README.md Introduces shared memory and delivery scope.
agent-memory/​README-bridge.md Documents tool integration and offline behavior.
agent-memory/​README-backend.md Documents API setup, persistence and limits.
agent-memory/​package.json Defines Node requirements and package commands.
agent-memory/​lovable-app/​src/​routes/​index.tsx Registers the memory workspace route and metadata.
agent-memory/​lovable-app/​src/​routes/​__root.tsx Adds the application shell and error boundaries.
agent-memory/​lovable-app/​src/​lib/​memory/​live.test.ts Tests live API validation and request handling.
agent-memory/​lovable-app/​src/​lib/​memory/​graph.test.ts Adds memory replay and mutation assertions.
agent-memory/​lovable-app/​src/​lib/​codegraph/​handoff.ts Implements staged demo retrieval and context preparation.
agent-memory/​lovable-app/​src/​lib/​codegraph/​handoff.test.ts Tests handoff ordering and graph separation.
agent-memory/​lovable-app/​src/​lib/​codegraph/​existing.ts Defines code-graph adapters and sample data.
agent-memory/​lovable-app/​src/​components/​memory/​TwoGraphStage.tsx Visualizes the two-graph retrieval sequence.
agent-memory/​lovable-app/​src/​components/​memory/​TwoGraphStage.test.tsx Tests visualization and replay controls.
agent-memory/​lovable-app/​src/​components/​memory/​RetrievalStatus.tsx Displays retrieval readiness and context previews.
agent-memory/​lovable-app/​src/​components/​memory/​MemoryDrawers.tsx Adds context and connection drawers.
agent-memory/​lovable-app/​src/​components/​memory/​LiveReconnect.test.tsx Tests saved-mode and paired-tab reconnection.
agent-memory/​lovable-app/​roadmap.md Records frontend milestones and deployment exclusions.
agent-memory/​docs/​video/​voiceover.txt Supplies the timed narration script.
agent-memory/​docs/​video/​voiceover.srt Supplies timed captions.
agent-memory/​docs/​video/​motion/​render.mjs Bundles, renders and muxes the explainer.
agent-memory/​docs/​video/​motion/​README.md Documents rendering inputs and workflow.
agent-memory/​docs/​video/​motion/​package.json Declares animation and rendering dependencies.
agent-memory/​docs/​video/​motion/​index.jsx Registers the 60-second 4K composition.
agent-memory/​docs/​video/​motion/​.gitignore Excludes rendering dependencies and generated directories.
agent-memory/​docs/​verification.md Records reported synthetic and live verification.
agent-memory/​docs/​superpowers/​specs/​2026-10-06-memory-lens-live-design.md Defines shared-memory boundaries and retrieval order.
agent-memory/​docs/​superpowers/​plans/​2026-10-06-memory-lens-live.md Records implementation milestones and remaining steps.
agent-memory/​docs/​diagrams/​memory-flow.svg Illustrates capture, editing and separate graph retrieval.
agent-memory/​bridge/​state.mjs Persists private bridge state and prompt tombstones.
agent-memory/​bridge/​mcp.mjs Exposes memory operations over stdio MCP.
agent-memory/​bridge/​install.mjs Installs project-local Codex hooks with backups.
agent-memory/​bridge/​hooks.mjs Captures user prompts and formats bounded context.
agent-memory/​bridge/​existing-graph.mjs Queries an operator-selected code-graph MCP server.
agent-memory/​bridge/​client.mjs Coordinates ingestion, retries and revision caching.
agent-memory/​bridge/​api.mjs Handles authenticated requests and endpoint validation.
agent-memory/​bin/​memory-lens.mjs Provides CLI, hook and MCP entry points.
agent-memory/​backend/​store.mjs Stores shared memory and migrates legacy graphs.
agent-memory/​backend/​service.mjs Coordinates mutations and memory-first retrieval.
agent-memory/​backend/​server.mjs Hosts the authenticated local HTTP API.
agent-memory/​backend/​provider.mjs Requests structured, user-only memory extraction.
agent-memory/​backend/​graph.mjs Validates graph edits and ranks active context.
agent-memory/​backend/​errors.mjs Defines API errors and field validation.

Review effort: Balanced

import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Sheet, SheetContent, SheetDescription, SheetTitle } from "@/components/ui/sheet";
import { demoAdapter, sessionNames, type GraphState } from "@/lib/memory/graph";
| { kind: "stage"; caption: string }
| { kind: "edit"; command: string; caption: string };

export const demoScripts: Record<SessionId, DemoStep[]> = {
} else if (operation.op === 'update') {
const node = scopedNode(operation.node_id);
const content = contentField(operation.content);
if (kind === 'turn' && (node.status === 'forgotten' || node.history.some(entry => normalize(entry.content) === normalize(content)))) continue;
Comment on lines +101 to +102
const lastChange = node => node.history.at(-1)?.changed_at || '';
const ranked = active.sort((a, b) => Number(b.pinned) - Number(a.pinned) || score(b) - score(a) || lastChange(b).localeCompare(lastChange(a)));
const historical = new Set((original.history || []).filter(entry => ['superseded', 'forgotten'].includes(entry.status)).map(entry => normalize(entry.content)));
const predecessors = [...nodes.entries()].filter(([content]) => content !== key && historical.has(content));
const inherited = [...nodes.values()].find(node => node.history.some(entry => normalize(entry.content) === key));
if (!existing && !predecessors.length && inherited && original.source_kind !== 'command') {
Comment on lines +122 to +125
fireEvent.click(screen.getByRole("button", { name: /Deployment fix/ }));
expect(screen.queryByText(/1\/11/)).toBeNull();
fireEvent.click(screen.getByRole("button", { name: /Billing feature/ }));
expect(screen.getByText(/1\/11/)).toBeTruthy();
describe("Memory graph replay adapter", () => {
it("starts Billing with exactly five scoped memories and legible relationships", () => {
const state = initialState("billing");
expect(state.memories).toHaveLength(5);

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for (const { path, value } of entries) {
const event = value.event;
if (!event || (selection && !sameSession(event, selection))) continue;
const sessionKey = JSON.stringify([event.source, event.external_session_id, event.session_id]);
Comment on lines +59 to +61
await bridge.flush();
await bridge.ensure(selection.source, selection.external_session_id);
base_revision = await bridge.cachedRevision(selection);

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants