@connordb/client
v1.8.5
Published
TypeScript / JavaScript client for the connordb database engine — atomic multi-modal commits, async embedding freshness, hybrid search.
Downloads
774
Maintainers
Readme
@connordb/client
TypeScript / JavaScript SDK for ConnorDB — the system of record for agent memory. One ACID engine that gives a swarm of agents durable, auditable, tamper-evident memory: atomic multi-modal commit (row + BM25 + dense vector + sparse + typed payload under one fsync), in-process embed worker, LSN-watermark read-your-writes, server-side hybrid search. That engine also collapses the 5-service RAG stack (vector DB + row store + embedder + queue + cache) into one process.
ConnorDB is machine-only post-pivot (ADR 0006). The canonical transport is gRPC; the previous HTTP Client was removed in v1.0.0.
Install
npm install @connordb/client@grpc/grpc-js and @grpc/proto-loader are pulled as regular dependencies — no extras to enable.
Quick start
import { GrpcClient } from "@connordb/client";
const c = await GrpcClient.connect({
target: "localhost:50051",
apiKey: process.env.CONNORDB_API_KEY,
});
try {
// Atomic multi-modal commit.
const lsn = await c.insert({
id: "doc-1",
text: "ship the patch",
embedding: [0.1, 0.2, 0.3, 0.4], // match the engine's --embedding-dim
payload: { category: "urgent" },
collection: "notes",
});
// Read-your-writes on the vector index.
await c.waitForEmbed(lsn);
// Hybrid search: BM25 + dense fused via RRF.
const hits = await c.searchHybrid({ query: "patch", k: 10, includeText: true });
for (const h of hits) {
console.log(h.rank, h.id, h.distance ?? h.score);
}
} finally {
c.close();
}Surface
GrpcClient exposes every canonical RPC: insert, get, getAsOf,
getHistory, delete, count, deleteByFilter, searchText, searchVector,
searchHybrid, executePlan, waitForEmbed, embedRebuild, listCollections,
createSnapshot, listSnapshots, getSnapshot, deleteSnapshot, auditQuery,
verifyAuditChain, timeTravelResolve, tuneRecommend, llmCacheLookup,
llmCacheStore, llmCacheDeleteNamespace, getStats, getGrammar,
clusterTopology.
Agent-facing API (selected)
| Method | RPC | Notes |
|---|---|---|
| insert({ id, text, embedding?, payload?, collection? }) | EngineService.Insert | Atomic multi-modal commit. |
| insertIfUnchanged({ id, expectedLsn, text, embedding }) | EngineService.InsertIfLsnMatches | CAS by LSN (ADR 0013). |
| searchHybrid({ query, k, includeText? }) | EngineService.SearchHybrid | BM25 + dense + sparse RRF fused server-side (ADR 0004). |
| waitForEmbed(lsn) / waitForProjection(name, lsn) | EngineService.EmbedWait / WaitForProjection | Read-your-writes watermarks (ADR 0005, 0010). |
| snapshotAsOf({ asOf, collection?, filter? }) | EngineService.SnapshotAsOf | Whole-tenant time travel (ADR 0014). |
| subscribe(...) | EngineService.Subscribe | Push-based change feed (ADR 0008). |
| clusterTopology({ clusterTarget }) | ClusterService.ClusterTopology | ADR 0016 Phase 7: epoch + leader + per-member view (id, addr, inSync, lastAckLsn). clusterTarget is the cluster-internal port (--cluster-port), not --grpc-port. |
| recordToolCall({ toolName, args, result, citedLsns }) | EngineService.RecordToolCall | ADR 0017 Phase A: tamper-evident record of an external tool invocation. Returns the LSN of the ToolCall causal frame. |
| recordDecision({ decisionId, citedLsns, summary }) | EngineService.RecordDecision | ADR 0017 Phase A: agent decision with verified citations. Cross-tenant cites raise PERMISSION_DENIED. |
| traceback(rootLsn, maxDepth?) | EngineService.Traceback | ADR 0017 Phase A: walk the citation graph rooted at rootLsn. Returns {rootLsn, nodes, edges} in BFS order. |
| endorseRow(targetLsn) | EngineService.EndorseRow | ADR 0018 Phase A: durably endorse another agent's row. Idempotent on (targetLsn, callerAgentId). Returns the LSN of the Endorse belief frame. |
| disputeRow(targetLsn, reason) | EngineService.DisputeRow | ADR 0018 Phase A: durably dispute another agent's row with a free-form reason. Sticky — the row is never overwritten. Returns the LSN of the Dispute belief frame. |
| setStorageMode({ mode }) | EngineService.SetStorageMode | ADR 0019 Phase B: switch the tenant between "rowstore" and "dual". "field" is reserved for Phase C. |
| fieldInsert({ id, text, payload, vector }) | EngineService.FieldInsert | ADR 0019 §4: mirrored rowstore + field deformation under one fsync. Returns {rowLsn, fieldLsn}. |
| fieldSample({ region, k, basisId?, asOfLsn? }) | EngineService.ExecutePlan (FieldSample stage) | ADR 0020 §4: sample k coords from a Region (anchor / anchor_lsn / tile / union / intersection / difference). Returns {samples, aggregateQuality}. |
| fieldSeal() | EngineService.FieldSeal | ADR 0019 §4: freeze the current field epoch. |
| fieldEvolveBasis({ seed? }) | EngineService.FieldEvolveBasis | ADR 0019 §4: explicit audited basis relearn. |
v1.8.0 — continuous-field storage (ADR 0019 / 0020 / 0021)
Tenants can opt into the continuous-field projection alongside the rowstore. Five new methods, one new builder class, two new response shapes (additive — every 1.7.x call site stays byte-identical).
import { GrpcClient, Region } from "@connordb/client";
const c = await GrpcClient.connect({
target: "localhost:50051",
apiKey: "...",
});
// 1. Opt the tenant into dual-mode storage.
await c.setStorageMode({ mode: "dual" });
// 2. Insert a row — committed atomically into rowstore + field.
const { fieldLsn } = await c.fieldInsert({
id: "doc-1",
text: "hello world",
payload: Buffer.from("..."),
vector: new Array(384).fill(0.1),
});
// 3. Sample the latent space addressed by a region AST.
const region = Region.union([
Region.anchorLsn(fieldLsn, { radius: 0.25 }),
Region.tile("tile-east-1"),
]);
const { samples, aggregateQuality } = await c.fieldSample({
region,
k: 16,
});
for (const s of samples) {
console.log(s.fieldCoordId, s.quality?.residualNorm);
}
console.log(aggregateQuality); // ADR 0021 §6 summarysearchHybrid(...) grew an optional withFieldHits: true overload
that returns { hits, fieldHits, aggregateQuality? } instead of the
default Hit[]. executePlan(...) surfaces fieldHits +
aggregateQuality automatically when the response carries them.
Every text / vector / field hit now exposes a source discriminator
("rowstore" / "field" / "mixed_fused") — UNSPECIFIED on the
wire maps to "rowstore" per the ADR 0020 §4 contract.
The tenantId kwarg on every field-mode method is a forward-compat
override sent as x-tenant-id metadata. The engine derives the
active tenant from the API-key auth context; the override is
validated against it.
v1.3.0 — multi-agent belief primitives (ADR 0018 Phase A)
The audit chain becomes the team's shared belief register. Two new methods let agents mark what they have team-validated, and durably dispute what they disagree on:
import { GrpcClient } from "@connordb/client";
const planner = await GrpcClient.connect({
target: "localhost:50051",
apiKey: "…",
agentId: "planner",
});
const verifier = await GrpcClient.connect({
target: "localhost:50051",
apiKey: "…",
agentId: "verifier",
});
const lsn = await planner.insert({ id: "fact-1", text: "Launch is Friday" });
await verifier.endorseRow(lsn); // team-validated
// await verifier.disputeRow(lsn, "actually Monday");Cross-tenant target → NOT_FOUND. Self-endorse → PERMISSION_DENIED.
Empty / >1024-byte reason → INVALID_ARGUMENT. Disputes are
sticky: the engine never silently merges or overwrites.
v1.2.0 — causal tracing (ADR 0017 Phase A)
The audit chain becomes the public reasoning API. Three new methods let an agent answer "why did the swarm decide X" in one RPC, with structural atomicity no external trace store can match:
import { GrpcClient } from "@connordb/client";
const c = await GrpcClient.connect({ target: "localhost:50051", apiKey: "…" });
const toolLsn = await c.recordToolCall({
toolName: "web_search",
args: { q: "connordb" },
result: { hits: 3 },
});
const decisionLsn = await c.recordDecision({
decisionId: "deploy-friday",
citedLsns: [toolLsn],
summary: "green retrieval, deploying",
});
const graph = await c.traceback(decisionLsn, 5);
for (const n of graph.nodes) console.log(n.kind, n.lsn, n.label);
for (const e of graph.edges) console.log(e.fromLsn, "→", e.toLsn, e.edgeType);Cross-tenant cites are rejected with PERMISSION_DENIED; future
LSNs with INVALID_ARGUMENT. The cited set is hash-bound into
the per-tenant SHA-256 audit chain — post-hoc re-citation breaks
the chain on verifyAuditChain.
v1.1.0 — cluster topology
ADR 0016 Phase 7 ships clusterTopology({ clusterTarget }) returning a
ClusterTopology interface with epoch, leaderNodeId, leaderAddr, and
members: ClusterMember[]. Each member carries id, addr, inSync, and
lastAckLsn. Available on every node; the leader's view is strongly
consistent, a follower's is eventually consistent.
The full type definitions are in src/grpc.ts. The canonical
wire contract is the proto under
proto/connordb/v1/ (shipped inside the package) and
the QueryPlan JSON Schema served by Grammar.GetGrammar (also at
docs/query_grammar.schema.json).
v1.0.0 — the transport cut
The HTTP Client from v0.x was deleted in this release (Sprint 6, ADR 0006).
ConnorDB is machine-only post-pivot; the engine no longer exposes HTTP, so
the SDK does not either.
Migration:
- Replace
new Client({ url, apiKey })withawait GrpcClient.connect({ target, apiKey }). url(http://host:port) becomestarget(host:port).- Method names are camelCase as before. Many method shapes are identical;
see
src/grpc.tsfor the canonical signatures.
Subpath export @connordb/client/grpc is identical to the package
root import — kept as an alias for callers that adopted it during
the HTTP-to-gRPC migration.
