npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@eidentic/convex

v0.8.1

Published

Convex store adapter for Eidentic — durable agent memory, session state, and a temporal knowledge graph backed by Convex (StorePort + GraphPort + VectorPort).

Readme

@eidentic/convex

A Convex-backed adapter for Eidentic.

Recommended path: install Eidentic as a Convex Component so Eidentic's sessions, events, memory, graph, vector, checkpoint, idempotency, and decision tables live inside an isolated component schema instead of being spread into your host app schema.

The older app-functions/HTTP runner path is still supported for external workers and server processes. Existing @eidentic/convex, @eidentic/convex/schema, and @eidentic/convex/server imports continue to work.

Install

npm i @eidentic/convex convex

convex is a peer dependency.

Component Setup

Add the component to convex/convex.config.ts:

import { defineApp } from "convex/server";
import eidentic from "@eidentic/convex/convex.config.js";

const app = defineApp();

app.use(eidentic, { name: "eidentic" });

export default app;

Run Convex codegen as usual:

npx convex dev

Use the component from a host action or mutation after your app has authenticated the caller and resolved workspace/org/business context:

import { components } from "./_generated/api";
import { action } from "./_generated/server";
import { fromActionCtx } from "@eidentic/convex/component";

export const runAgent = action({
  args: {},
  handler: async (ctx) => {
    const { store, vectors } = fromActionCtx(ctx, components.eidentic);

    await store.upsertBlock(
      { kind: "agent", agentId: "support-bot" },
      { label: "profile", value: "Name: Ada" },
    );

    return await vectors.list("agent:support-bot");
  },
});

fromActionCtx accepts Convex's generated ActionCtx directly and normalizes the stricter FunctionReference runner signatures inside the SDK. Host apps no longer need a local unknown -> FunctionReference bridge. If you prefer manual construction, EidenticComponentStore and EidenticComponentVectorStore also accept the generated action context directly.

Component tables use singular snake_case names internally:

session, event, block, block_history, memory, fact, vector,
checkpoint, idempotency, decision

Those tables are owned by the component and do not appear in the host app's schema.

Security Model

Do not expose component functions directly as your product API. Route client calls through host app functions such as api.ai.eidentic.draftReply, authenticate there, check workspace/org/role permissions, assemble business context, and then call the component.

This keeps Eidentic focused on durable agent runtime state while your app remains the authority for users, tenants, model credentials, and final side effects.

App-Functions Path

Use app-functions when the Eidentic runtime runs outside Convex and talks to a deployment through ConvexHttpClient.

Legacy schema spread

This is unchanged and remains source-compatible:

import { defineSchema } from "convex/server";
import { eidenticTables } from "@eidentic/convex/schema";

export default defineSchema({
  ...eidenticTables,
});

Prefixed app-functions schema

For new app-functions installs, prefer prefixed table names:

// convex/schema.ts
import { defineSchema } from "convex/server";
import { createEidenticTableNames, createEidenticTables } from "@eidentic/convex/app-functions/schema";

export const eidenticTableNames = createEidenticTableNames({ prefix: "eidentic_" });

export default defineSchema({
  ...createEidenticTables({ names: eidenticTableNames }),
});

Register handlers with the same table map:

// convex/eidentic.ts
import { eidenticFunctions, type EidenticAuthorize } from "@eidentic/convex/app-functions/server";
import { eidenticTableNames } from "./schema.js";

const authorize: EidenticAuthorize = async (ctx, { op, args }) => {
  const identity = await ctx.auth.getUserIdentity();
  if (!identity) throw new Error("unauthenticated");

  const sessionId = args["sessionId"];
  if (typeof sessionId === "string" && !sessionId.startsWith(identity.subject)) {
    throw new Error(`forbidden: ${op}`);
  }
};

export const {
  createSession, getSession, listSessions, appendEvents, readEvents,
  getBlocks, getBlock, upsertBlock, appendBlock, getBlockHistory, listBlocks,
  indexMemory, searchMemory, assertFact, queryFacts, corroborate, expireFacts,
  sweepExpired, eraseScope, writeCheckpoint, lastCheckpoint, recordIntent,
  recordCompletion, getIdempotency, recordDecision, getDecision,
  vectorUpsert, vectorSearch, vectorDelete, vectorEraseScope, vectorList,
} = eidenticFunctions({
  tables: eidenticTableNames,
  authorize,
});

The bare named handlers exported by @eidentic/convex/server now fail closed. Public invocations throw until the host registers eidenticFunctions({ authorize }); the authorization hook must authenticate the caller and enforce ownership for every referenced scope, session, and owner key.

For a short, controlled migration only, eidenticFunctions({ unsafeAllowUnauthenticated: true }) and unsafeLegacyPublicEidenticFunctions restore the old behavior. Both are deliberately named as unsafe and must not be exposed by a multi-tenant deployment.

HTTP runner

import { ConvexHttpClient } from "convex/browser";
import { ConvexStore, ConvexVectorStore, convexHttpRunner } from "@eidentic/convex";

const client = new ConvexHttpClient(process.env.CONVEX_URL!);
client.setAuth(process.env.CONVEX_AUTH_TOKEN!);

const runner = convexHttpRunner(client);
const store = new ConvexStore(runner);
const vectors = new ConvexVectorStore(runner);

Durable Idempotency Metadata

recordIntent, recordCompletion, and getIdempotency accept optional ownership metadata:

await store.recordIntent("sess1:send_email:[email protected]", "args-hash", {
  sessionId: "sess1",
  ownerKey: "user:u1",
});

This gives Convex authorization hooks structured fields to check instead of parsing opaque keys. Eidentic core passes sessionId automatically for durable tool dispatch.

Vector Strategy

ConvexVectorStore remains a zero-infra vector adapter that stores vectors in Convex and scores with deterministic JS cosine ranking. It is suitable for demos, tests, and small deployments.

For production semantic memory at scale, prefer an external VectorPort such as @eidentic/qdrant and keep a separate collection for Eidentic memory.

Migration Notes

  • Existing app-functions imports still compile, but bare named public handlers now deny at runtime. Migrate the host module to eidenticFunctions({ authorize }) before deploying this version.
  • New Convex apps should use the component path.
  • Existing app-functions installs that want prefixed table names need a data migration or a fresh Convex deployment; changing table names is not automatic.
  • The unsafe compatibility factory/object is temporary migration scaffolding, not a production authorization boundary. Prefer eidenticFunctions({ authorize }) or the component path.

Testing

This package is covered by Convex store/vector/durable conformance tests via convex-test, plus tests for table-name factories, authorization metadata, and in-process runners.

test/live.test.ts runs the same store, durable, vector, and fail-closed authorization checks against a real Convex backend when EIDENTIC_TEST_CONVEX_URL is set. The target must be a disposable test deployment that exposes a destructive test-only reset:all mutation; never point the live suite at shared development or production data.

License

Apache-2.0