Skip to content

README.md updated#322

Open
brukcodes wants to merge 2 commits into
rohitg00:mainfrom
brukcodes:main
Open

README.md updated#322
brukcodes wants to merge 2 commits into
rohitg00:mainfrom
brukcodes:main

Conversation

@brukcodes
Copy link
Copy Markdown

@brukcodes brukcodes commented May 13, 2026

I have enhanced the README.md to make it more professional. Here are the key improvements I made:

1 Added an Overview Section: Introduced a concise, formal description of agentmemory at the beginning, explaining its purpose, architecture, and key features.

2 Improved Language: Rephrased the introductory paragraph to use more professional and formal language, replacing casual phrases with clear, objective descriptions.

3 Added a Contributing Section: Included a dedicated section on how to contribute, with guidelines for forking, development setup, issue reporting, and adherence to the code of conduct.

4 Updated Table of Contents: Added links to the new Overview and Contributing sections for better navigation.

Summary by CodeRabbit

  • Documentation
    • Expanded navigation with new API link and rewritten Overview with example workflow.
    • Converted many sections (benchmarks, comparisons, search, embeddings, MCP Server, console, agent mappings, LLM providers, API endpoints, Contributing) into clearer markdown tables and step-by-step guidance.
  • Bug Fixes
    • Improved migration robustness to handle varied session/observation identifiers and database import edge cases.

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

@brukcodes is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

📝 Walkthrough

Walkthrough

The README is restructured into consistent markdown tables across navigation, Overview, benchmarks, agent integrations, features, MCP tooling, iii console pages, configuration, and API docs. Separately, migrate.ts loads better-sqlite3 via dynamic import and normalizes session/observation/summary IDs with fallbacks and generated IDs.

Changes

README Documentation Table-Driven Restructure

Layer / File(s) Summary
Navigation and overview refresh
README.md
Adds API link to table of contents, rewrites Overview header/text, and introduces Example Workflow narrative referencing JWT auth and recall rate-limiting.
Benchmarks and agent integration tables
README.md
Reformats Retrieval Accuracy and Token Savings benchmarks into markdown tables; expands agent integration mapping with per-agent config locations and Codex/OpenCode variants; converts Windows diagnostics into table format.
Feature comparison and search documentation
README.md
Structures "vs built-in agent memory" comparison, memory consolidation tiers, captured hooks, key capabilities, and search triple-stream model into tables; standardizes embedding provider list.
MCP Server tools and resources documentation
README.md
Overhauls MCP Server into tables for core and extended tools (gated by AGENTMEMORY_TOOLS=all) and resources/prompts/skills; minor whitespace/OpenCode snippet adjustments.
iii console pages and worker capabilities
README.md
Adds table of iii console pages and purposes; maps iii worker add commands to capabilities and rewrites "What iii replaces".
Configuration and API endpoint documentation
README.md
Converts LLM Providers matrix and Key endpoints into tables; clarifies defaults and expands Contributing subsections.

Migration robustness and sqlite import

Layer / File(s) Summary
Dynamic better-sqlite3 import
src/functions/migrate.ts
Loads better-sqlite3 via dynamic import() and supports sqlite.default ?? sqlite fallback to Database.
Normalize session & observation IDs
src/functions/migrate.ts
When migrating sessions/observations, compute sessionId/id from row.session_id, row.sessionId, row.id or generate via generateId("mig"); observations use row.id ?? generateId("mig") for obs id.
Session summaries normalization & KV write
src/functions/migrate.ts
Compute summarySessionId from multiple row fields and use it when writing SessionSummary.sessionId and performing the KV write instead of raw row.session_id.

Possibly Related PRs

  • rohitg00/agentmemory#106: Prior README polishing that reworks navigation, benchmarks, and example text—overlaps with the README table-driven changes.
  • rohitg00/agentmemory#242: README updates focused on iii Console and iii worker add → capabilities tables; related documentation area.
  • rohitg00/agentmemory#243: README fixes for iii console install/launch commands and console capability entries.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through headings, rows aligned,

Cells tidy now, no prose entwined.
Benchmarks, tools, and API in sight,
Migration IDs now set just right.
A little hop — docs and code delight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'README.md updated' is vague and overly generic. While technically related to the changeset, it fails to convey the specific nature or scope of the README improvements, making it uninformative for someone reviewing PR history. Use a more descriptive title that captures the main improvements, such as 'Restructure README with professional overview, enhanced documentation tables, and contributing guidelines' or 'Enhance README with comprehensive documentation tables and contributing section'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/functions/migrate.ts (1)

72-72: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add audit trail for migration operations.

The migration function performs state-changing operations (writing sessions, observations, and summaries to KV) but does not call recordAudit() to record these operations. As per coding guidelines, functions in src/functions/**/*.ts must record state-changing operations via recordAudit() for audit trail tracking.

📋 Proposed fix to add audit recording

Import recordAudit at the top of the file:

import { recordAudit } from "../state/audit.js";

Then add an audit record after the migration completes (after line 139):

         await kv.set(KV.summaries, summarySessionId, summary);
         summaryCount++;
       }
+
+      await recordAudit({
+        operation: "mem::migrate",
+        metadata: {
+          dbPath: data.dbPath,
+          sessionCount,
+          obsCount,
+          summaryCount,
+        },
+      });

       logger.info("Migration complete", {

As per coding guidelines, state-changing operations in src/functions/**/*.ts must call recordAudit() for audit trail tracking.

🤖 Prompt for 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.

In `@src/functions/migrate.ts` at line 72, The migration writes state to KV (e.g.,
await kv.set(KV.sessions, session.id, session)) but doesn't record an audit
entry; import recordAudit from "../state/audit.js" and call recordAudit(...)
from the migrate function after the migration's state-changing operations
complete (include context such as operation type "migration", target identifiers
like session.id or observation ids, and any summary data) so every write
(sessions, observations, summaries) is logged for audit trail tracking.
🧹 Nitpick comments (1)
src/functions/migrate.ts (1)

60-74: ⚡ Quick win

Consider parallelizing independent KV writes.

The migration loops perform sequential await kv.set() operations. Since each write is independent, batching them with Promise.all() would improve performance for large migrations. As per coding guidelines, "Use parallel operations where possible with Promise.all for independent kv writes/reads."

⚡ Example refactor for session migration
-        for (const row of sessions) {
+        await Promise.all(sessions.map(async (row) => {
           const sessionId = String(row.session_id ?? row.id ?? generateId("mig"));
           const session: Session = {
             id: sessionId,
             project: row.project_path || row.project || "unknown",
             cwd: row.cwd || row.project_path || "",
             startedAt:
               row.created_at || row.started_at || new Date().toISOString(),
             endedAt: row.ended_at || row.updated_at,
             status: "completed",
             observationCount: 0,
           };
           await kv.set(KV.sessions, session.id, session);
-          sessionCount++;
-        }
+        }));
+        sessionCount = sessions.length;

Apply the same pattern to observations and summaries loops.

As per coding guidelines, parallel operations should be used where possible for independent KV writes.

🤖 Prompt for 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.

In `@src/functions/migrate.ts` around lines 60 - 74, The migration currently
awaits each independent kv.set sequentially inside the sessions loop (for const
row of sessions) which is slow; instead collect promises for each write (using
kv.set with the computed session id and session object) into an array and then
await Promise.all(promises), and update sessionCount by sessions.length (or the
number of promises) after the Promise.all resolves; locate the session migration
logic (variables: sessions, sessionId, Session, sessionCount, generateId,
kv.set) to implement this change and apply the same Promise.all batching pattern
to the observations and summaries migration loops as well.
🤖 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 `@src/functions/migrate.ts`:
- Around line 123-125: summarySessionId currently falls back to the hardcoded
string "migrated" when row.session_id, row.sessionId, and row.id are all
missing, which causes key collisions when calling kv.set(KV.summaries,
summarySessionId, summary); change the fallback to a guaranteed-unique string
(for example by appending a stable unique identifier like a UUID, a timestamp
plus the loop index, or a hash of the row contents) so each summary gets a
distinct key; update the code paths that build summarySessionId (references:
summarySessionId, row.session_id, row.sessionId, row.id) and ensure the new key
is a string before calling kv.set(KV.summaries, summarySessionId, summary).
- Line 94: The fallback for sessionId currently uses the hardcoded string
"migrated" which groups unrelated rows together; change the assignment of
sessionId in migrate.ts (the const sessionId = ...) to call generateId() when
neither row.session_id nor row.sessionId exist so each migrated observation gets
a unique session identifier, and ensure generateId is imported/available in the
module (or reference the existing utility function) so the code compiles and
produces unique fallback IDs.
- Around line 35-36: The dynamic import of better-sqlite3 uses a fallback
`sqlite.default ?? sqlite` which can yield a namespace object (not a
constructor); replace that pattern by destructuring the default export directly
so Database references the constructor. Change the import to use `const {
default: Database } = await import("better-sqlite3");` and remove the fallback
assignment; update any subsequent references to the existing Database variable
if needed to match the destructured name.

---

Outside diff comments:
In `@src/functions/migrate.ts`:
- Line 72: The migration writes state to KV (e.g., await kv.set(KV.sessions,
session.id, session)) but doesn't record an audit entry; import recordAudit from
"../state/audit.js" and call recordAudit(...) from the migrate function after
the migration's state-changing operations complete (include context such as
operation type "migration", target identifiers like session.id or observation
ids, and any summary data) so every write (sessions, observations, summaries) is
logged for audit trail tracking.

---

Nitpick comments:
In `@src/functions/migrate.ts`:
- Around line 60-74: The migration currently awaits each independent kv.set
sequentially inside the sessions loop (for const row of sessions) which is slow;
instead collect promises for each write (using kv.set with the computed session
id and session object) into an array and then await Promise.all(promises), and
update sessionCount by sessions.length (or the number of promises) after the
Promise.all resolves; locate the session migration logic (variables: sessions,
sessionId, Session, sessionCount, generateId, kv.set) to implement this change
and apply the same Promise.all batching pattern to the observations and
summaries migration loops as well.
🪄 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

Run ID: 6da9296e-1e95-40a9-98d6-e054a3a81b8b

📥 Commits

Reviewing files that changed from the base of the PR and between 5da19e8 and 8a13f0f.

📒 Files selected for processing (1)
  • src/functions/migrate.ts

Comment thread src/functions/migrate.ts
Comment on lines +35 to +36
const sqlite = await import("better-sqlite3");
Database = sqlite.default ?? sqlite;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify better-sqlite3 export structure and correct import pattern

# Check if better-sqlite3 is installed and examine its package.json
if [ -f "node_modules/better-sqlite3/package.json" ]; then
  echo "=== better-sqlite3 package.json ==="
  cat node_modules/better-sqlite3/package.json | jq '{name, version, main, module, type, exports}'
fi

# Look for TypeScript definitions to understand export structure
if [ -f "node_modules/better-sqlite3/lib/index.d.ts" ]; then
  echo "=== Type definitions ==="
  cat node_modules/better-sqlite3/lib/index.d.ts | head -20
fi

# Check package-lock.json for installed version
echo "=== Installed version ==="
cat package-lock.json | jq '.packages["node_modules/better-sqlite3"].version // .dependencies["better-sqlite3"].version' 2>/dev/null || echo "Not found in package-lock.json"

Repository: rohitg00/agentmemory

Length of output: 158


🌐 Web query:

How to dynamically import better-sqlite3 in ESM TypeScript with proper default export handling

💡 Result:

In ESM TypeScript, better-sqlite3 should be treated as a CommonJS module whose module.exports becomes the ESM default export, so you must read the constructor from the default property when using dynamic import(). 1) Correct dynamic import with proper default export handling (Node ESM) import better-sqlite3 dynamically and create the DB: const { default: BetterSqlite3 } = await import('better-sqlite3'); const db = new BetterSqlite3('foobar.db'); This is required because when a CommonJS module is imported into ESM via import(), Node maps module.exports to the ESM default export; with dynamic import() the module.exports value is available under namespace.default [1]. The better-sqlite3 package is intended to be instantiated as a default export Database/constructor in ES module notation (import Database from 'better-sqlite3') [2][3]. 2) TypeScript typing (constructor vs Database type) The typings define a DatabaseConstructor interface with new(...) and call signatures, and a Database interface for instances [4]. In practice, you can type the default-imported value and/or the return type: // db.ts import type { Database, DatabaseConstructor } from 'better-sqlite3'; export async function openDb(path: string): Promise { const { default: BetterSqlite3 } = await import('better-sqlite3'); const ctor = BetterSqlite3 as unknown as DatabaseConstructor; return new ctor(path); } If you previously used incorrect interop (e.g., import BetterSqlite3 from 'better-sqlite3' with dynamic import without reading .default, or used the wrong import shape), you can hit runtime errors like better_sqlite3_1.default is not a constructor; dynamic import interop via .default is the fix [5] (and the underlying rule is the CommonJS→ESM default mapping for import() [1]). 3) When you don’t need dynamic import If you can use static ESM imports, the simplest form is: import Database from 'better-sqlite3'; const db = new Database('foobar.db'); This is the documented/typical ES module usage [2][3]. Notes - This pattern is especially relevant for native addons: ESM static/dynamic loading still has to synchronize the module loading shape, but the default export mapping rule is what determines whether the constructor is at namespace.default or not [1].

Citations:


Use explicit destructuring for the better-sqlite3 dynamic import.

The fallback pattern sqlite.default ?? sqlite is problematic because sqlite (the namespace object) is not a constructor. Since better-sqlite3 is a CommonJS module imported via ESM, the constructor is always at the .default property. Replace with explicit destructuring:

Current code
const sqlite = await import("better-sqlite3");
Database = sqlite.default ?? sqlite;
Recommended change
const { default: Database } = await import("better-sqlite3");
🤖 Prompt for 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.

In `@src/functions/migrate.ts` around lines 35 - 36, The dynamic import of
better-sqlite3 uses a fallback `sqlite.default ?? sqlite` which can yield a
namespace object (not a constructor); replace that pattern by destructuring the
default export directly so Database references the constructor. Change the
import to use `const { default: Database } = await import("better-sqlite3");`
and remove the fallback assignment; update any subsequent references to the
existing Database variable if needed to match the destructured name.

Comment thread src/functions/migrate.ts
Comment thread src/functions/migrate.ts
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.

1 participant