fix(engram): correct the docs against the live API, the server spec, and the SDK - #525
Open
g-despot wants to merge 15 commits into
Open
fix(engram): correct the docs against the live API, the server spec, and the SDK#525g-despot wants to merge 15 commits into
g-despot wants to merge 15 commits into
Conversation
…he copy Replace static/specs/engram-openapi.json wholesale with weaviate/engram's openapi.json at 67a0248 (server v0.0.40). The committed copy dated from 2026-05-28 and every path was missing its /v1 prefix, so the Scalar page at /engram/api/rest -- and its copy-as-curl -- pointed at URLs that 404. The refresh also adds GET /v1/auth/verify and GET /v1/groups, the Group, GroupList, Topic and TopicScoping schemas, created_at/updated_at on StringInput, and the limit bounds on RetrievalConfigDTO and ListMemoriesRequest. Give the file a real section in static/specs/README.md: source repo, path and commit, refresh-by-copy steps, the "every path starts with /v1" check, and the two known upstream inaccuracies to fix in the server rather than here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
Add an API overview page and wire it into the sidebar, the introduction, the quickstart and install-integrate. It covers what was previously scattered or missing: the base URL including the required /v1 prefix and the absence of a project ID in the path, the bearer header and the five ways to get a 401, GET /v1/auth/verify, the RFC 9457 problem+json error body with a status-code table (including the 422 and 429 the spec prose omits), the SDK's exception types, GET /v1/groups with an example response, the unauthenticated /health endpoint, and the free plan's 1,000 runs per month and 1 project. Also: document POST /v1/memories/list as a "List memories" section in the manage-memories guide, marked REST-only because the Python SDK has no list() method, and point the multi-tenant RAG tutorial's deletion step at it instead of leaving search() as an enumeration; state plainly in groups.md and console.md that projects, groups and topics are console-only with no create API; source the plan claims in pipelines.md and concepts/index.md against the pricing page; and note that no official npm package exists. The new curl snippets live in _includes/api_overview.sh and are registered with tests/test_engram.py, so the verify, groups, health and missing-prefix claims are checked live rather than asserted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
…rules concepts/search.md said Engram has three search strategies while two pages already used a fourth. Add fetch to the table, explain that it applies scope and topic filters without ranking (and still requires a non-empty query it ignores), and state the defaults nothing documented: hybrid with a limit of 10 when retrieval_config is omitted, limit 1-100, no pagination. Mirror the defaults in the search guide's "Retrieval types" intro and give fetch a subsection with Python, async and cURL examples. Also fix a cross-page contradiction in concepts/scopes.md, which told readers that scope parameters are optional when searching. user_id follows the same union rule as storing -- required if any targeted topic is user-scoped -- and only properties are optional filters, which is what scopes.md itself says higher up and what the search guide says. The new snippets are exercised by the existing harness files, and search_memories.sh gains a fetch assertion. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
FilteredTextBlock renders only the lines between START and END, so an import above the marker is invisible on the page and the block it belongs to does not run when a reader copies it. The quickstart's Connect block was the worst case -- one bare EngramClient(...) call on the site's busiest Engram guide -- and every retrieval class, the pre-extracted input models, and all three tutorial setup blocks had the same problem. Each rendered block now imports what it uses, following the pattern store_memories.py already had. Test-only imports (time, APIError, the uuid that only feeds test user IDs) stay outside. Duplicate imports across blocks are intentional: a snippet has to stand on its own. Also add the missing import to the inline retrieval-tuning block in the context-window tutorial. All eleven touched files still compile and still run top to bottom. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
The Hermes plugin install was wrong: `pip install hermes-weaviate-engram` 404s, the package is not on PyPI. Install it from the repository instead, and warn that it requires weaviate-engram>=0.6,<1, so it downgrades an environment holding the current 1.x SDK. The Claude Code plugin section named a "Coding Assistant" template that the plugin's README never mentions, and left out everything the plugin actually needs. Replace it with what the README and the plugin's scope resolver document: ENGRAM_USER_ID and its git-email default, the two config files and what each may contain, how a property value resolves, the search narrowing keys, and the "Engram · …" in-reply notice. Most importantly, `repo_name` and `session_id` are the only properties the plugin can resolve on its own, so a project with a topic scoped by anything else fails to store on every turn until a .engram.json maps it -- that now has its own admonition with an example. Also stop implying the template choice is free: presets beyond the personalization pipeline start at the Starter plan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
Match the wire/SDK names: pre_extracted, and topic_name for a topic's identifier. Document what the SDK actually exposes — user_id is case-insensitive and auto-created, root is REST-only, runs.get versus runs.wait (and that wait never returns on in_buffer), the typed exceptions, and the created_at/updated_at/metadata fields that no page mentioned. Also correct "content is an array": a bare Python list is serialized as a conversation, so multiple strings need StringInput. Standardise on "managed memory service", drop the self-hosted claim, and name the optional Buffer step on the landing page. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
Sentence-case the three tutorial titles and make every index entry and cross-link use the title verbatim. Point the dual-memory paragraph at Step 3, where that pattern actually is, and render the token-comparison snippet that computes the table instead of leaving it orphaned. Give the RAG tutorial the environment-variable block it was missing, the current Auth.api_key idiom, and an up-front note that its Weaviate half is illustrative and untested. Show a plain user_id in the chat app's setup block rather than a test-generated one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
…rs consistent Give the Guideflow iframe a title and a numbered text fallback, so the click path survives a blocked third-party embed or a screen reader, and drop the three non-standard React props plus the script tag React never executed. Merge the duplicated "use the Personalization template" instruction, and remove a stray blank line. Use the same placeholders everywhere: alice for user_id, and <run-id> / <memory-id> for path segments, matching the site's convention and the Python tab. Those strings live inside the DOCSNIPPETS heredoc of each shell include, which the harness never executes. Show fractional hybrid scores instead of a flat 1. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
Order the Concepts sidebar the way the pages introduce each other — groups before topics — matching the Concepts index. Render the three snippet blocks that no page pointed at (the quickstart's run check, and the context-window tutorial's setup and token count) and move the cleanup helper, which was neither documented nor tested, out of the docs tree into tests/. Settle on one name, "Engram console", fix the escaped underscore in one feedback import, and answer the question the page never did: a scope is a Weaviate tenant. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
…eval-type count The Claude Code plugin does not search broadly by default: cross-topic properties default to repo_name, so recall is confined to the repository you are working in until search.properties overrides it or an empty array clears it. Say so, and note that the default is inert unless the group is actually scoped by repo_name. Wave 1 raised three retrieval types to four on the search pages but left five enumerations behind, so the section contradicted itself; all of them now name fetch. The quickstart's text fallback is now an equal alternative to the embed rather than a failure path: it covers the group and topic screen the embed shows, including the Conversation Summary option that makes conversation_id required on every write. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
Settle the console reference so the term always links to the page and the sign-in URL always attaches to Weaviate Cloud. Give illustrative topic names the PascalCase the API actually matches case-sensitively, on the same pages that now warn a wrong case is a 422. Put List memories ahead of Get and Delete, the order the page intro and every other page already use. Deep-link bounded-topic and get/wait references, and give two internal links the .md the link checker needs to see them. Say what a reader of the rendered page can act on: the REST reference's overview text rather than the spec's info.description, the REST shape of retrieval_config alongside the Python models, a retrieval-type heading that matches its block, and a Manage-memories description that is not a survivor of the pre-List page. Plan limits now live in one place. Align "managed memory service" across the FAQ, the navbar, the announcement bar and the spec README, and correct that README's claim that 67a0248 is the v0.0.40 release commit — it is the dev-deploy commit, byte-identical to the production build f2e6cbb. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
The retrieval-type sweep left "returns ranked results" covering fetch, which concepts/search.md says does not rank. Attribute ranking to the query-based types. Also note that an explicitly configured repo_name is resolved whatever the group's schema says, so the plugin's default recall filter can apply even to a group that is not scoped by it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
api_overview.sh assigned the group listing to GROUPS, which bash reserves for the caller's group IDs: the assignment is discarded, $GROUPS expands to the numeric primary GID, and jq fails with "Cannot index number with string". The check could never pass on any machine. Rename it, and leave a comment so it does not come back. The lockfile pinned weaviate-engram 0.6.0, which has neither the timestamp fields on StringInput nor the four retrieval models these snippets import, so the documented 1.x surface could not run under it. Require 1.0.1 and relock. In the context-window tutorial, only the search was guarded, but the add that carries conversation_id is rejected first on a project where no topic declares that key. Guard the whole sequence, which is what the block's own comment already claimed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
Six claims did not survive a run against a real project. Input timestamps do not order memories: the stored created_at/updated_at are ingest wall-clock and nothing on the memory carries the time you sent. What they demonstrably do is anchor relative-time resolution during extraction, which is the better reason to send them anyway. scope_properties is omitted, not empty, for a topic that has none, so reading it as an array raises. properties appears only on memories whose topic declares scope properties — a UserKnowledge memory has no such key even when the write carried a conversation_id. created_at is refreshed when a memory is rewritten, so it is a last-write time. /health returns $schema like every other body, and a validation error omits value when the rejected value was null. Also record that a mistyped topic name is silent until the scope has data: searching a user with no memories returns 200 and an empty list for a topic that does not exist, which is exactly when a reader is hunting a typo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E74iUw2NdCfeUBf9eRqqJb
Ivan removed docs/engram/api-overview.md, its _includes/api_overview.sh snippets, the SDK exception list, the TypeScript note and the Claude Code plugin deep-dive, leaving the plugin section pointing at the upstream README. That left four links resolving to nothing. console.md and concepts/groups.md now point GET /v1/groups at the REST reference — deliberately with no anchor, since Scalar generates those — and each sentence gained a clause saying what the endpoint returns, so neither depends on the reader following the link. index.md drops the API-overview bullet, whose neighbour already covers the same ground, and console.md's Plans section points at pipeline runs. The plan numbers came home. An earlier pass had emptied console.md of them on the premise that api-overview.md owned them; that premise died with the page, so the free plan's 1,000 runs per month, its 1-project cap and the 429 at the cap are stated where the reader meets them. One sentence survives from the deleted plugin deep-dive: recall defaults to the current repository via the repo_name property. The upstream README says the opposite in one place and the truth in another, so a bare pointer would route readers to the wrong claim. Also fixes an unclosed </details tag in quickstart.md that broke the client bundle: MDX consumed forward from it and choked on an apostrophe two lines below.
There was a problem hiding this comment.
Orca Security Scan Summary
| Status | Check | Issues by priority | |
|---|---|---|---|
| Infrastructure as Code | View in Orca | ||
| SAST | View in Orca | ||
| Secrets | View in Orca | ||
| Vulnerabilities | View in Orca |
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.
A deep review of the Engram docs — read against the server repo, the Python SDK and the production API — found the published spec stale and a set of claims that don't match what the service does. This fixes them.
The spec.
static/specs/engram-openapi.jsonis replaced wholesale from the server repo; the committed copy was from May and its paths lacked the/v1prefix, so every URL the Scalar page rendered 404'd. It's now byte-identical to what production serves (sha256 matches both the dev-deploy commit and the v0.0.40 prod tag), andstatic/specs/README.mddocuments the refresh, including thatinfo.versionis pinned at 1.0.0 and does not track the server release.Claims corrected against production.
fetchis documented as the fourth retrieval type (three pages said three); defaults and limits are stated (hybrid, 10, range 1–100);concepts/scopes.mdno longer says scope parameters are optional when searching — a write must satisfy the union of every topic's scope in the group, which is why snippets fail against a project with a scoped bounded topic. Input timestamps steer extraction but are not stored, so the page no longer implies you can order by them. Terminology follows the wire format (pre_extracted,topic_name), and topic names are case-sensitive whereuser_idis not.Snippets. Every rendered
FilteredTextBlockspan now carries its own imports, so blocks are copy-pasteable standalone.pyproject.tomlrequiredweaviate-engram>=0.3.0while the lock pinned 0.6.0 — a version whereStringInputhas no timestamp fields and none of the four retrieval models exist, so the includes could not run; now>=1.0.1with the lock refreshed.Verification. Nine API claims were checked live and two write paths exercised (22 memories created and deleted, none left). The build passes with no new warnings.
Known, not fixed here: the snippet harness cannot pass against a project whose group contains a scoped topic — it needs a project created without the ConversationSummary option. Some claims (
403,429, the list default of 20) remain unverified.