feat(sdk): v0.9.0 — @memmesh/sdk rename, raw-text observe, knowledge graph - #21
Merged
Merged
Conversation
…graph
Publishes as `@memmesh/sdk`. `@thinkfleet/memory-sdk` tops out at 0.7.1, so
this release also carries the unpublished 0.8.0 work.
`memory.observe()` now takes raw text and returns what the engine kept:
const { saved, candidateCount } = await tf.memory.observe({
text, role: 'user', userId, sessionId,
})
Hand it the turn verbatim and the engine runs extraction, dedupe, graph
wiring, and embedding. `candidateCount` is what extraction proposed;
`saved` is what survived. The legacy `content` path still stores a
pre-decided fact verbatim, so existing callers keep working — but its
return type changes from `MemoryItem` to `{ saved, candidateCount }`.
`userId` / `agentId` / `sessionId` are now forwarded. The server route has
always accepted them; the SDK was dropping them, so provenance never
arrived. They are provenance only, NOT a tenancy boundary: `admin.search`
filters `chatIdentityId IS NULL OR = $1`, permissively by design.
New `tf.memory.admin.graph` — stats, listEntities, getEntity, listEdges,
traverse. There was no graph surface at all before, so the structural half
of memory was unreachable from the SDK. Read-only: entities and edges are
written by extraction during observe, and a hand-maintained graph is the
work the engine exists to do.
Prefer `graph.stats()` over `listEntities().length` for any size question —
the list routes page, so their length is the page size, not the total.
Also: `MemMesh` exported as the brand-consistent client alias
(`ThinkFleetMemory` retained), README documents `observe()` for the first
time, and a tag-triggered npm publish workflow.
BREAKING: package renamed; `observe()` return type changed.
This was referenced Aug 19, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the SDK up to what the API actually supports, and unblocks the
chat-with-memoryexample, which needs both the raw-text observe pipeline andthe graph counters.
@thinkfleet/memory-sdktops out at 0.7.1 on npm, so this release alsocarries the unpublished 0.8.0 work (procedural memory, precedence policy).
What changed
memory.observe()takes raw textHand it the turn verbatim — the engine runs extraction, dedupe, graph
wiring, and embedding, and keeps only what is worth remembering.
candidateCountis what extraction proposed,savedis what survived. Fillercomes back as
saved: [].Identity fields are forwarded
userId/agentId/sessionIdnow reach the server. The route has alwaysaccepted them; the SDK was silently dropping them, so provenance never
arrived on anything written through
observe().They are provenance, not a tenancy boundary —
admin.searchfilterschatIdentityId IS NULL OR = $1, permissive by design so project-wide memoriesstay visible. Isolating one end user's memories from another's still needs a
project per tenant. Documented as such in the README and the type.
New
tf.memory.admin.graphstats()GET /admin/memory/graph/statslistEntities(params?)GET /admin/memory/entitiesgetEntity(id, params?)GET /admin/memory/entities/:idlistEdges(params?)GET /admin/memory/graph/edgestraverse(id, params?)POST /admin/memory/graph/traverseThere was no graph surface at all before, so the structural half of memory was
unreachable from the SDK. Read-only on purpose: entities and edges are written
by extraction during
observe(), and exposing the manual create/retire routeswould invite hand-maintained graphs — the work the engine exists to do.
Use
stats(), notlistEntities().length, for any "how big is it" question:the list routes page, so their length is the page size rather than the total.
(That exact bug was live in the example app before this change.)
Also
MemMeshexported as the brand-consistent client alias;ThinkFleetMemoryretained for back-compat.
observe()for the first time — it was the primary writepath and absent from the resource tables entirely.
v*→npm publish).Breaking
@memmesh/sdk. Consumers of@thinkfleet/memory-sdkdo not get this via a version bump; they must change the dependency name.
observe()return type changed fromMemoryItemto{ saved, candidateCount }, on the legacycontentpath too.test-app.tsis updated accordingly.
Verification
npm run typecheck,npm run build,npm run check:proto(47 RPCs — 42covered, 5 internal) all pass.
admin.search→ Claude →observe(both halves) →graph.stats. Confirmedon the wire that identity now arrives:
{"text":"I just moved to Denver.","role":"user","userId":"u-verify-123","sessionId":"s-verify-456"}Before merging / after
@memmeshnpm org must exist andNPM_TOKENmust be set in reposecrets — I could not verify either (npm is not authenticated locally).
git tag v0.9.0 && git push origin v0.9.0.memmesh-exampleshas four examples still on@thinkfleet/memory-sdk(three
^0.4.0, one^0.7.1). They keep working, but the repo now spans twopackage names — worth migrating once this is on npm.