Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Knowledge Base

Knowledge is reference material for the agent, such as policies, terminology, and procedures, kept in amodal/knowledge/. It takes three forms:

  • A Markdown document, loaded whole.
  • A corpus, a searchable collection committed with the agent.
  • A library, a searchable collection your application files documents into while the agent runs, scoped per document.

Use stores for changing structured records and connections for live API access. Knowledge reaches the model, so do not put secrets in it.

Document Format

Small documents are Markdown files:

amodal/knowledge/
├── support-policy.md
└── product-glossary.md
---
description: Use when a support ticket involves account access or a disputed charge.
category: support
tags: [account-access, billing]
---
 
# Support Policy
 
- Check account-access verification before recommending account changes.
- Confirm a refund's status in the billing system before reporting it as complete.
- Escalate a disputed charge to the billing team with the invoice and ticket IDs.

The filename without .md is the document name: support-policy. The title comes from frontmatter title, then the first # heading, then the filename. Optional frontmatter includes description, category, and tags.

A root session's prompt lists document names and descriptions. The model retrieves a body with:

load_knowledge({ knowledge: 'support-policy' });

Without frontmatter description, the body's first paragraph is used, truncated to 400 characters. Write the description to say when the document applies.

A delegated subagent receives its authored prompt rather than the root's compiled knowledge index. Declare load_knowledge in the subagent's tools; the tool description lists available documents.

Searchable Corpora

A corpus is a directory with a knowledge.json manifest beside its pages:

amodal/knowledge/reference-manual/
├── knowledge.json
├── _SECTIONS.tsv
└── pages/
    ├── 01-overview.md
    └── 02-procedures.md
{
  "type": "corpus",
  "title": "Reference Manual",
  "description": "Operating procedures and section references.",
  "pages": "pages",
  "index": "_SECTIONS.tsv",
  "provenance": {
    "edition": "2026-01",
    "source": "https://example.com/manual"
  }
}

pages defaults to pages. The optional TSV index has section, title, page, and line columns, with a header row. Without it, citations identify pages and lines instead of sections.

knowledge_search has sections, files, content, and documents modes, plus hybrid when the corpus has a semantic index. knowledge_read reads a section or a line range. A named agent must declare both tools in its tools. Build a semantic index with amodal corpus index.

Runtime Libraries

A library uses the same retrieval as a corpus, over documents your application files at runtime. Declare it with a manifest and no pages:

amodal/knowledge/team-library/
└── knowledge.json
{
  "type": "library",
  "title": "Team library",
  "description": "SOPs and agreements operators filed for the agent to consult.",
  "scope": { "keys": ["mission_id"] },
  "parsing": { "preference": ["docling", "builtin"] }
}

scope.keys names the scope context keys a document may be scoped by. A document filed with { "mission_id": "m1" } is visible only to sessions that carry that value. A document filed with no scope is visible to every session. Search runs only over the visible set.

scope.source sets where a session's values come from. The default, claims, reads only the verified token claims, so a caller cannot widen its view through the request body. Set "source": "context" only when your application enforces access itself and passes the current scope in the request body.

The document routes require an API key or a token minted with role: "operator". End-user chat tokens are refused; users reach a library only through the agent's tools, under their own scope.

Filing documents

The runtime parses, chunks, embeds, and indexes the document. Your application keeps the original file.

POST /api/knowledge/team-library/documents
Authorization: Bearer <runtime token>
 
{
  "doc_id": "doc-a1b2c3",
  "title": "Retrans SOP",
  "filename": "retrans-sop.pdf",
  "mime_type": "application/pdf",
  "bytes_base64": "...",
  "scope": { "mission_id": "m1" },
  "tags": ["sop"],
  "parser": "auto"
}
  • Send text in place of bytes_base64 when you already hold the text.
  • The response's document carries status (ready, or parsing with status 202 while a service parser runs), parser, outline, chunks, and warnings.
  • GET /api/knowledge/:library/documents lists documents. GET .../documents/:id?text=1 returns the parsed text. A GET also advances a pending parse.
  • PATCH .../documents/:id changes title, description, scope, tags, metadata, and enabled without re-parsing. enabled: false hides the document from the agent.
  • DELETE .../documents/:id retires the document.
  • To re-parse with another parser, POST the same doc_id with parser set.

Parsers

GET /api/knowledge/parsers lists the parsers a deployment can use:

ParserKindConfigured by
builtinlocalAlways available: PDF text layer, DOCX, XLSX, Markdown, text.
doclingserviceDOCLING_URL (a docling-serve instance), optional DOCLING_API_KEY.
textractserviceAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION; TEXTRACT_S3_BUCKET for multi-page PDFs.
google-document-aiserviceGOOGLE_DOCUMENT_AI_PROCESSOR plus GOOGLE_APPLICATION_CREDENTIALS_JSON or GOOGLE_DOCUMENT_AI_ACCESS_TOKEN.
azure-document-intelligenceserviceAZURE_DOCUMENT_INTELLIGENCE_ENDPOINT, AZURE_DOCUMENT_INTELLIGENCE_KEY.

Without a parser in the request, the runtime tries the library's parsing.preference, then KNOWLEDGE_PARSER_PREFERENCE, then builtin. A service failure falls through to the next parser and adds a warning to the document. A scanned PDF with no text layer fails builtin and needs an OCR-capable service.

What the model sees each turn

A corpus is described once in the cached prompt. A library is described on every turn, after the cache breakpoint, as the list of documents the session can see with their titles and descriptions. retrieval with auto: true runs one hybrid search with each user message and shows the top hits (1 to 10, default 3) to the model:

{
  "type": "library",
  "scope": { "keys": ["mission_id"] },
  "retrieval": { "auto": true, "hits": 3 }
}

auto defaults to false, so retrieval does not run without it. Automatic retrieval costs a search and a few hundred tokens per turn.

Inspecting what the runtime holds

  • GET /api/knowledge lists every corpus and library with its embedding settings, whether it is indexed, and, for a library, document counts by status.
  • GET /api/knowledge/:library/search?q=&mode=&scope= runs the agent's knowledge_search. Without scope it searches every document. With scope set to a session's scope context as JSON, it returns what that session would see.

Both routes use the operator authentication of the filing routes.

Storage

Hosted runtimes store library documents on the platform with no configuration. A self-run runtime uses CORPUS_DATABASE_URL, or DATABASE_URL, with pgvector. Set "embedding": { "store": "memory" } for an in-process store during local development.

One request carries one document, so parsed text is limited to a few megabytes. Without CORPUS_EMBEDDING_URL, a library is searchable by words only, and each document's warnings say so.