Skip to content

Compounding Memory (API)

Everything you can do with the wiki — reading pages, searching, compiling, importing — is exposed through the GraphQL API. This page tells you what queries exist, who can call them, and what they return.

Start here if you’re building a client (the mobile app, an SDK, another service) that needs to talk to the wiki.

Read a page when you know its slug. Returns the full page including every section and alias.

Search an agent’s wiki with a free-text query. Two flavors:

  • Lexical search — looks for your query in titles, summaries, and body text.
  • Ranked wiki search for mobile — uses the same compiled-page FTS path, with prefix matching for partial mobile input.

Find what links to a page. Given a page id, get the list of pages that link to it.

Go from a memory to its pages. Any MemoryRecord you pull from the API has a wikiPages field that returns the pages citing it as a source.

Compile on demand (admin only). Queue a compile job for a specific agent.

Bulk-import from journal data (admin only). Kick off a background job that ingests everything and compiles at the end.

Reset an agent’s wiki (admin only). Clear the cursor, optionally archive pages.

All wiki reads are agent-scoped. Every query requires ownerId (the agent id), and the system checks that you’re either that agent yourself or an admin of the tenant.

There is no tenant-wide read path. If you want to know what’s in another agent’s wiki in the same tenant, you need admin rights.

Mutations (compileWikiNow, bootstrapJournalImport, resetWikiCursor) are admin-only across the board.

query GetPage($tenantId: ID!, $ownerId: ID!, $type: WikiPageType!, $slug: String!) {
wikiPage(tenantId: $tenantId, ownerId: $ownerId, type: $type, slug: $slug) {
id
title
summary
bodyMd
lastCompiledAt
aliases
sections {
sectionSlug
heading
bodyMd
position
lastSourceAt
}
}
}

Returns null if no such page exists. Page types are ENTITY, TOPIC, or DECISION.

Two options depending on what you’re building.

query Search($tenantId: ID!, $ownerId: ID!, $query: String!, $limit: Int = 20) {
wikiSearch(tenantId: $tenantId, ownerId: $ownerId, query: $query, limit: $limit) {
page { id type slug title summary }
score
matchedAlias
}
}

This is Postgres full-text search over the page’s title, summary, and body, with a +1.0 boost for any alias matching the query. Results are ranked by a ts_rank score + alias bonus.

query MobileSearch($userId: ID!, $query: String!, $limit: Int = 20) {
mobileWikiSearch(userId: $userId, query: $query, limit: $limit) {
score
matchingMemoryIds
page {
id
type
slug
title
summary
lastCompiledAt
}
}
}

Mobile search runs through the shared compiled-page FTS helper. It matches active wiki_pages rows with search_tsv, adds normalized prefix matching for partial input like empan, includes alias hits, and returns the same page card shape the mobile app already consumes.

The ranking comes from Postgres FTS plus alias boost. Higher is better, but scores are not comparable across queries.

matchingMemoryIds is preserved for mobile wire compatibility and is currently always [] on this FTS path.

Any MemoryRecord you get back from memorySearch or memoryRecords has a wikiPages field:

query MemoriesWithPages($assistantId: ID!, $query: String!) {
memorySearch(assistantId: $assistantId, query: $query) {
records {
memoryRecordId
content { text }
wikiPages {
id
type
slug
title
summary
}
}
totalCount
}
}

This is how the mobile timeline shows “this memory helped build these pages.” The list is scoped to the same agent as the memory — there’s no cross-agent leakage possible here.

One caveat: the wikiPages resolver does one DB round-trip per memory record in the result set. Fine for typical result sizes (≤25); if you’re annotating large result sets, you’ll want a DataLoader on the server side.

query Backlinks($pageId: ID!) {
wikiBacklinks(pageId: $pageId) {
id
type
slug
title
summary
}
}

Given a page, returns every page that links to it. Useful for “what references this?” UI affordances.

Admin only.

mutation CompileNow($tenantId: ID!, $ownerId: ID!) {
compileWikiNow(tenantId: $tenantId, ownerId: $ownerId) {
id
status
trigger
dedupeKey
attempt
createdAt
}
}

Returns the job row — either a fresh insert, or (if a compile is already running for that agent) the existing in-flight job. Check trigger to distinguish (admin for your request, memory_retain for a pre-existing post-retain job).

Admin only. Fire-and-forget — the mutation acknowledges immediately, the actual work happens on a dedicated worker Lambda.

mutation BulkImport($accountId: ID!, $tenantId: ID!, $agentId: ID!, $limit: Int) {
bootstrapJournalImport(
accountId: $accountId
tenantId: $tenantId
agentId: $agentId
limit: $limit
) {
dispatched
dispatchedAt
error
}
}

Watch progress through CloudWatch logs and the wiki_compile_jobs table. The terminal compile shows up as a row with trigger = 'bootstrap_import'.

Admin only. Destructive when force: true.

mutation Reset($tenantId: ID!, $ownerId: ID!, $force: Boolean) {
resetWikiCursor(tenantId: $tenantId, ownerId: $ownerId, force: $force) {
cursorCleared
pagesArchived
}
}
  • force: false (default) — clears the cursor. Next compile re-reads everything but likely makes no meaningful changes.
  • force: true — clears the cursor and archives every active page. Use when you want the next compile to visibly rebuild.

For a truly clean rebuild (including deleting provenance rows), see the operations guide.

  • Auth or scope failures surface as Agent not found or access denied (mobile paths) or Forbidden (admin paths). Scope mismatch is treated as unauthorized, not “not found.”
  • Compile job failures show up in the job row’s error field — common ones are Too many requests (Bedrock throttling) and adapter-not-implemented errors.
  • Read paths don’t call LLMs, so they don’t see Bedrock errors.

  • packages/database-pg/graphql/types/wiki.graphql — wiki types, queries, mutations
  • packages/database-pg/graphql/types/memory.graphqlMemoryRecord.wikiPages + mobileWikiSearch
packages/api/src/graphql/resolvers/memory/mobileWikiSearch.query.ts
// 1. Resolve the caller's user-scoped wiki scope.
// 2. Delegate to the shared wiki FTS helper.
// 3. Match active wiki_pages rows with search_tsv @@ plainto_tsquery(...)
// or the normalized prefix tsquery used for mobile-friendly partial input.
// 4. Include alias hits through wiki_page_aliases and boost those matches.
// 5. Sort by score DESC, then lastCompiledAt DESC.
// 6. Preserve the mobile wire shape with matchingMemoryIds = [].
  • packages/api/src/graphql/resolvers/wiki/wikiPage.query.ts
  • packages/api/src/graphql/resolvers/wiki/wikiSearch.query.ts
  • packages/api/src/graphql/resolvers/wiki/wikiBacklinks.query.ts
  • packages/api/src/graphql/resolvers/wiki/compileWikiNow.mutation.ts
  • packages/api/src/graphql/resolvers/wiki/bootstrapJournalImport.mutation.ts
  • packages/api/src/graphql/resolvers/wiki/resetWikiCursor.mutation.ts
  • packages/api/src/graphql/resolvers/memory/mobileWikiSearch.query.ts
  • packages/api/src/graphql/resolvers/memory/types.ts (the MemoryRecord.wikiPages field)