diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 4fe99f37..1c0f0ff6 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -495,4 +495,96 @@ jobs:
- name: Run tests
working-directory: ./hindsight-integrations/litellm
- run: uv run pytest tests -v
\ No newline at end of file
+ run: uv run pytest tests -v
+
+ test-doc-examples:
+ runs-on: ubuntu-latest
+ env:
+ HINDSIGHT_API_LLM_PROVIDER: groq
+ HINDSIGHT_API_LLM_API_KEY: ${{ secrets.GROQ_API_KEY }}
+ HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b
+ HINDSIGHT_API_URL: http://localhost:8888
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ UV_INDEX: pytorch=https://download.pytorch.org/whl/cpu
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install uv
+ uses: astral-sh/setup-uv@v5
+ with:
+ enable-cache: true
+ prune-cache: false
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version-file: ".python-version"
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'npm'
+ cache-dependency-path: package-lock.json
+
+ - name: Build and install API
+ working-directory: ./hindsight-api
+ run: |
+ uv build
+ uv sync --no-install-project --index-strategy unsafe-best-match
+
+ - name: Install Python client dependencies
+ working-directory: ./hindsight-clients/python
+ run: uv sync --extra test --index-strategy unsafe-best-match
+
+ - name: Install TypeScript client
+ run: |
+ npm ci --workspace=hindsight-clients/typescript
+ npm run build --workspace=hindsight-clients/typescript
+
+ - name: Create .env file
+ run: |
+ cat > .env << EOF
+ HINDSIGHT_API_LLM_PROVIDER=${{ env.HINDSIGHT_API_LLM_PROVIDER }}
+ HINDSIGHT_API_LLM_API_KEY=${{ env.HINDSIGHT_API_LLM_API_KEY }}
+ HINDSIGHT_API_LLM_MODEL=${{ env.HINDSIGHT_API_LLM_MODEL }}
+ EOF
+
+ - name: Start API server
+ run: |
+ ./scripts/dev/start-api.sh > /tmp/api-server.log 2>&1 &
+ echo "Waiting for API server to be ready..."
+ for i in {1..60}; do
+ if curl -sf http://localhost:8888/health > /dev/null 2>&1; then
+ echo "API server is ready after ${i}s"
+ break
+ fi
+ if [ $i -eq 60 ]; then
+ echo "API server failed to start after 60s"
+ cat /tmp/api-server.log
+ exit 1
+ fi
+ sleep 1
+ done
+
+ - name: Run Python doc examples
+ working-directory: ./hindsight-clients/python
+ run: |
+ for f in ../../hindsight-docs/examples/api/*.py; do
+ echo "Running $f..."
+ uv run python "$f"
+ done
+
+ - name: Run Node.js doc examples
+ run: |
+ for f in hindsight-docs/examples/api/*.mjs; do
+ echo "Running $f..."
+ node "$f"
+ done
+
+ - name: Show API server logs
+ if: always()
+ run: |
+ echo "=== API Server Logs ==="
+ cat /tmp/api-server.log || echo "No API server log found"
\ No newline at end of file
diff --git a/hindsight-clients/python/pyproject.toml b/hindsight-clients/python/pyproject.toml
index 0bdf6699..68b44435 100644
--- a/hindsight-clients/python/pyproject.toml
+++ b/hindsight-clients/python/pyproject.toml
@@ -20,6 +20,7 @@ dependencies = [
test = [
"pytest>=7.0.0",
"pytest-asyncio>=0.21.0",
+ "requests>=2.28.0",
]
[build-system]
diff --git a/hindsight-docs/docs/developer/api/retain-new.mdx b/hindsight-docs/docs/developer/api/retain-new.mdx
new file mode 100644
index 00000000..8d0b94c8
--- /dev/null
+++ b/hindsight-docs/docs/developer/api/retain-new.mdx
@@ -0,0 +1,71 @@
+---
+sidebar_position: 2
+---
+
+# Ingest Data (New Format)
+
+This is a demo of the new code snippet approach. Code examples are pulled from executable script files.
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import CodeSnippet from '@site/src/components/CodeSnippet';
+
+{/* Import raw source files */}
+import retainPy from '!!raw-loader!@site/examples/api/retain.py';
+import retainMjs from '!!raw-loader!@site/examples/api/retain.mjs';
+import retainSh from '!!raw-loader!@site/examples/api/retain.sh';
+
+:::tip How This Works
+The code examples below are extracted from actual runnable script files in `examples/api/`.
+When CI runs these scripts, it validates the documentation is correct.
+:::
+
+## Store a Single Memory
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Store with Context
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Batch Ingestion
+
+
+
+
+
+
+
+
+
+
+## Async Ingestion
+
+
+
+
+
+
+
+
+
diff --git a/hindsight-docs/examples/api/README.md b/hindsight-docs/examples/api/README.md
new file mode 100644
index 00000000..2d627236
--- /dev/null
+++ b/hindsight-docs/examples/api/README.md
@@ -0,0 +1,82 @@
+# API Documentation Examples
+
+This directory contains runnable example scripts that serve as the source of truth for code samples in the documentation.
+
+## How It Works
+
+1. **Scripts are runnable** - Each file can be executed as a smoke test
+2. **Markers define sections** - Code between `# [docs:section-name]` and `# [/docs:section-name]` markers is extracted
+3. **Docs import at build time** - MDX files use `raw-loader` to import scripts, then `CodeSnippet` extracts marked sections
+
+## File Structure
+
+| File | Documentation | Description |
+|------|---------------|-------------|
+| `quickstart.py/mjs/sh` | quickstart.md | Getting started examples |
+| `retain.py/mjs/sh` | retain.md | Memory ingestion examples |
+| `recall.py/mjs/sh` | recall.md | Memory retrieval examples |
+| `reflect.py/mjs/sh` | reflect.md | AI reflection examples |
+| `memory-banks.py/mjs` | memory-banks.md | Bank management examples |
+| `documents.py/mjs` | documents.md | Document CRUD examples |
+| `opinions.py` | opinions.md | Opinion management examples |
+| `main-methods.py` | main-methods.md | Core method examples |
+| `cli-reference.sh` | cli.md | CLI command examples |
+
+## Running Examples
+
+```bash
+# Run all Python examples
+for f in *.py; do python "$f"; done
+
+# Run all Node.js examples
+for f in *.mjs; do node "$f"; done
+
+# Run all CLI examples
+for f in *.sh; do bash "$f"; done
+```
+
+Requires a running Hindsight server at `http://localhost:8888` (or set `HINDSIGHT_API_URL`).
+
+## What's NOT Covered
+
+### 1. OpenAPI Auto-Generated Docs (`/api-reference/*`)
+
+These pages are generated directly from the OpenAPI specification. The spec itself is the source of truth, and the generated docs reflect it automatically. No manual code examples to validate.
+
+### 2. Interactive CLI Commands
+
+| Command | Reason |
+|---------|--------|
+| `hindsight configure` | Requires interactive user input (prompts for API URL, credentials) |
+| `hindsight configure --show` | Displays sensitive configuration, not suitable for automated tests |
+
+### 3. Installation/Setup Instructions
+
+Documentation sections covering `pip install`, `npm install`, or system setup are instructions, not executable code samples. These are validated by the CI environment setup itself.
+
+### 4. Error Handling Examples
+
+Some docs show error responses (e.g., "what happens when bank doesn't exist"). These require intentionally broken states that would fail smoke tests. Error behavior is covered by unit tests instead.
+
+## Adding New Examples
+
+1. Create or edit the appropriate script file
+2. Add markers around the new code section:
+ ```python
+ # [docs:my-new-section]
+ client.some_method(...)
+ # [/docs:my-new-section]
+ ```
+3. Reference in the MDX file:
+ ```mdx
+ import myScript from '!!raw-loader!@site/examples/api/my-script.py';
+
+ ```
+4. Run the script locally to verify it works
+
+## Marker Format
+
+- **Python/Bash**: `# [docs:section-name]` / `# [/docs:section-name]`
+- **JavaScript**: `// [docs:section-name]` / `// [/docs:section-name]`
+
+Section names should be kebab-case and descriptive (e.g., `retain-with-context`, `recall-basic`).
diff --git a/hindsight-docs/examples/api/cli-reference.sh b/hindsight-docs/examples/api/cli-reference.sh
new file mode 100755
index 00000000..36d7b4f2
--- /dev/null
+++ b/hindsight-docs/examples/api/cli-reference.sh
@@ -0,0 +1,209 @@
+#!/bin/bash
+# CLI Reference examples for Hindsight
+# Tests all documented CLI commands and flags
+# Run: bash examples/api/cli-reference.sh
+
+set -e
+
+HINDSIGHT_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
+BANK_ID="cli-test-bank"
+DOC_ID="test-document-001"
+
+# =============================================================================
+# Setup
+# =============================================================================
+hindsight configure --api-url "$HINDSIGHT_URL"
+
+# Create test data with a known document ID
+hindsight memory retain "$BANK_ID" "Alice works at Google as a software engineer" --document-id "$DOC_ID"
+hindsight memory retain "$BANK_ID" "Bob is a data scientist who collaborates with Alice" --document-id "$DOC_ID"
+hindsight memory retain "$BANK_ID" "Alice and Bob work on machine learning projects"
+
+# Wait a moment for processing
+sleep 2
+
+# =============================================================================
+# Configuration (cli.md - Configuration section)
+# =============================================================================
+
+# [docs:cli-configure]
+hindsight configure --api-url http://localhost:8888
+# [/docs:cli-configure]
+
+
+# =============================================================================
+# Core Memory Commands (cli.md - Core Commands section)
+# =============================================================================
+
+# [docs:cli-retain-basic]
+hindsight memory retain $BANK_ID "Alice works at Google as a software engineer"
+# [/docs:cli-retain-basic]
+
+
+# [docs:cli-retain-context]
+hindsight memory retain $BANK_ID "Bob loves hiking" --context "hobby discussion"
+# [/docs:cli-retain-context]
+
+
+# [docs:cli-retain-async]
+hindsight memory retain $BANK_ID "Meeting notes" --async
+# [/docs:cli-retain-async]
+
+
+# [docs:cli-recall-basic]
+hindsight memory recall $BANK_ID "What does Alice do?"
+# [/docs:cli-recall-basic]
+
+
+# [docs:cli-recall-options]
+hindsight memory recall $BANK_ID "hiking recommendations" \
+ --budget high \
+ --max-tokens 8192
+# [/docs:cli-recall-options]
+
+
+# [docs:cli-recall-fact-type]
+hindsight memory recall $BANK_ID "query" --fact-type world,opinion
+# [/docs:cli-recall-fact-type]
+
+
+# [docs:cli-recall-trace]
+hindsight memory recall $BANK_ID "query" --trace
+# [/docs:cli-recall-trace]
+
+
+# [docs:cli-reflect-basic]
+hindsight memory reflect $BANK_ID "What do you know about Alice?"
+# [/docs:cli-reflect-basic]
+
+
+# [docs:cli-reflect-context]
+hindsight memory reflect $BANK_ID "Should I learn Python?" --context "career advice"
+# [/docs:cli-reflect-context]
+
+
+# [docs:cli-reflect-budget]
+hindsight memory reflect $BANK_ID "Summarize my week" --budget high
+# [/docs:cli-reflect-budget]
+
+
+# =============================================================================
+# Bank Management (cli.md - Bank Management section)
+# =============================================================================
+
+# [docs:cli-bank-list]
+hindsight bank list
+# [/docs:cli-bank-list]
+
+
+# [docs:cli-bank-profile]
+hindsight bank profile $BANK_ID
+# [/docs:cli-bank-profile]
+
+
+# [docs:cli-bank-stats]
+hindsight bank stats $BANK_ID
+# [/docs:cli-bank-stats]
+
+
+# [docs:cli-bank-name]
+hindsight bank name $BANK_ID "My Assistant"
+# [/docs:cli-bank-name]
+
+
+# [docs:cli-bank-background]
+hindsight bank background $BANK_ID "I am a helpful AI assistant interested in technology"
+# [/docs:cli-bank-background]
+
+
+# [docs:cli-bank-background-no-disposition]
+hindsight bank background $BANK_ID "Background text" --no-update-disposition
+# [/docs:cli-bank-background-no-disposition]
+
+
+# =============================================================================
+# Document Management (cli.md - Document Management section)
+# =============================================================================
+
+# [docs:cli-document-list]
+hindsight document list $BANK_ID
+# [/docs:cli-document-list]
+
+
+# [docs:cli-document-get]
+hindsight document get $BANK_ID $DOC_ID
+# [/docs:cli-document-get]
+
+
+# [docs:cli-document-delete]
+# Create a temp document to delete
+hindsight memory retain $BANK_ID "Temporary content" --document-id "temp-doc-to-delete"
+sleep 1
+hindsight document delete $BANK_ID temp-doc-to-delete
+# [/docs:cli-document-delete]
+
+
+# =============================================================================
+# Entity Management (cli.md - Entity Management section)
+# =============================================================================
+
+# [docs:cli-entity-list]
+hindsight entity list $BANK_ID
+# [/docs:cli-entity-list]
+
+
+# Get an entity ID from the list output and use it
+ENTITY_ID=$(hindsight entity list $BANK_ID -o json 2>/dev/null | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4 || echo "")
+
+if [ -n "$ENTITY_ID" ]; then
+ # [docs:cli-entity-get]
+ hindsight entity get $BANK_ID $ENTITY_ID
+ # [/docs:cli-entity-get]
+
+ # [docs:cli-entity-regenerate]
+ hindsight entity regenerate $BANK_ID $ENTITY_ID
+ # [/docs:cli-entity-regenerate]
+else
+ echo "No entities found yet, skipping entity get/regenerate"
+fi
+
+
+# =============================================================================
+# Output Formats (cli.md - Output Formats section)
+# =============================================================================
+
+# [docs:cli-output-json]
+hindsight memory recall $BANK_ID "query" -o json
+# [/docs:cli-output-json]
+
+
+# [docs:cli-output-yaml]
+hindsight memory recall $BANK_ID "query" -o yaml
+# [/docs:cli-output-yaml]
+
+
+# =============================================================================
+# Global Options (cli.md - Global Options section)
+# =============================================================================
+
+# [docs:cli-verbose]
+hindsight memory recall $BANK_ID "Alice" -v
+# [/docs:cli-verbose]
+
+
+# [docs:cli-help]
+hindsight --help
+# [/docs:cli-help]
+
+
+# [docs:cli-version]
+hindsight --version
+# [/docs:cli-version]
+
+
+# =============================================================================
+# Cleanup
+# =============================================================================
+curl -s -X DELETE "${HINDSIGHT_URL}/v1/default/banks/${BANK_ID}" > /dev/null
+
+echo "cli-reference.sh: All examples passed"
diff --git a/hindsight-docs/examples/api/documents.mjs b/hindsight-docs/examples/api/documents.mjs
new file mode 100644
index 00000000..be6ba1be
--- /dev/null
+++ b/hindsight-docs/examples/api/documents.mjs
@@ -0,0 +1,68 @@
+#!/usr/bin/env node
+/**
+ * Documents API examples for Hindsight (Node.js)
+ * Run: node examples/api/documents.mjs
+ */
+import { HindsightClient, sdk, createClient, createConfig } from '@vectorize-io/hindsight-client';
+
+const HINDSIGHT_URL = process.env.HINDSIGHT_API_URL || 'http://localhost:8888';
+
+// =============================================================================
+// Setup (not shown in docs)
+// =============================================================================
+const client = new HindsightClient({ baseUrl: HINDSIGHT_URL });
+
+// =============================================================================
+// Doc Examples
+// =============================================================================
+
+// [docs:document-retain]
+// Retain with document ID
+await client.retain('my-bank', 'Alice presented the Q4 roadmap...', {
+ document_id: 'meeting-2024-03-15'
+});
+
+// Batch retain
+await client.retainBatch('my-bank', [
+ { content: 'Item 1: Product launch delayed to Q2' },
+ { content: 'Item 2: New hiring targets announced' },
+ { content: 'Item 3: Budget approved for ML team' }
+], { documentId: 'meeting-2024-03-15' });
+// [/docs:document-retain]
+
+
+// [docs:document-update]
+// Original
+await client.retain('my-bank', 'Project deadline: March 31', {
+ document_id: 'project-plan'
+});
+
+// Update
+await client.retain('my-bank', 'Project deadline: April 15 (extended)', {
+ document_id: 'project-plan'
+});
+// [/docs:document-update]
+
+
+// [docs:document-get]
+const apiClient = createClient(createConfig({ baseUrl: 'http://localhost:8888' }));
+
+// Get document to expand context from recall results
+const { data: doc } = await sdk.getDocument({
+ client: apiClient,
+ path: { bank_id: 'my-bank', document_id: 'meeting-2024-03-15' }
+});
+
+console.log(`Document: ${doc.id}`);
+console.log(`Original text: ${doc.original_text}`);
+console.log(`Memory count: ${doc.memory_unit_count}`);
+console.log(`Created: ${doc.created_at}`);
+// [/docs:document-get]
+
+
+// =============================================================================
+// Cleanup (not shown in docs)
+// =============================================================================
+await fetch(`${HINDSIGHT_URL}/v1/default/banks/my-bank`, { method: 'DELETE' });
+
+console.log('documents.mjs: All examples passed');
diff --git a/hindsight-docs/examples/api/documents.py b/hindsight-docs/examples/api/documents.py
new file mode 100644
index 00000000..58c2e668
--- /dev/null
+++ b/hindsight-docs/examples/api/documents.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+"""
+Documents API examples for Hindsight.
+Run: python examples/api/documents.py
+"""
+import os
+import requests
+
+HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+from hindsight_client import Hindsight
+
+client = Hindsight(base_url=HINDSIGHT_URL)
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:document-retain]
+# Retain with document ID
+client.retain(
+ bank_id="my-bank",
+ content="Alice presented the Q4 roadmap...",
+ document_id="meeting-2024-03-15"
+)
+
+# Batch retain for a document
+client.retain_batch(
+ bank_id="my-bank",
+ items=[
+ {"content": "Item 1: Product launch delayed to Q2"},
+ {"content": "Item 2: New hiring targets announced"},
+ {"content": "Item 3: Budget approved for ML team"}
+ ],
+ document_id="meeting-2024-03-15"
+)
+# [/docs:document-retain]
+
+
+# [docs:document-update]
+# Original
+client.retain(
+ bank_id="my-bank",
+ content="Project deadline: March 31",
+ document_id="project-plan"
+)
+
+# Update (deletes old facts, creates new ones)
+client.retain(
+ bank_id="my-bank",
+ content="Project deadline: April 15 (extended)",
+ document_id="project-plan"
+)
+# [/docs:document-update]
+
+
+# [docs:document-get]
+import asyncio
+from hindsight_client_api import ApiClient, Configuration
+from hindsight_client_api.api import DefaultApi
+
+async def get_document_example():
+ config = Configuration(host="http://localhost:8888")
+ api_client = ApiClient(config)
+ api = DefaultApi(api_client)
+
+ # Get document to expand context from recall results
+ doc = await api.get_document(
+ bank_id="my-bank",
+ document_id="meeting-2024-03-15"
+ )
+
+ print(f"Document: {doc.id}")
+ print(f"Original text: {doc.original_text}")
+ print(f"Memory count: {doc.memory_unit_count}")
+ print(f"Created: {doc.created_at}")
+
+asyncio.run(get_document_example())
+# [/docs:document-get]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/my-bank")
+
+print("documents.py: All examples passed")
diff --git a/hindsight-docs/examples/api/main-methods.py b/hindsight-docs/examples/api/main-methods.py
new file mode 100644
index 00000000..fed8f864
--- /dev/null
+++ b/hindsight-docs/examples/api/main-methods.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python3
+"""
+Main Methods overview examples for Hindsight.
+Run: python examples/api/main-methods.py
+"""
+import os
+import requests
+
+HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+from hindsight_client import Hindsight
+
+client = Hindsight(base_url=HINDSIGHT_URL)
+
+# =============================================================================
+# Doc Examples - Retain Section
+# =============================================================================
+
+# [docs:main-retain]
+# Store a single fact
+client.retain(
+ bank_id="my-bank",
+ content="Alice joined Google in March 2024 as a Senior ML Engineer"
+)
+
+# Store a conversation
+conversation = """
+User: What did you work on today?
+Assistant: I reviewed the new ML pipeline architecture.
+User: How did it look?
+Assistant: Promising, but needs better error handling.
+"""
+
+client.retain(
+ bank_id="my-bank",
+ content=conversation,
+ context="Daily standup conversation"
+)
+
+# Batch retain multiple items
+client.retain_batch(
+ bank_id="my-bank",
+ items=[
+ {"content": "Bob prefers Python for data science"},
+ {"content": "Alice recommends using pytest for testing"},
+ {"content": "The team uses GitHub for code reviews"}
+ ]
+)
+# [/docs:main-retain]
+
+
+# =============================================================================
+# Doc Examples - Recall Section
+# =============================================================================
+
+# [docs:main-recall]
+# Basic search
+results = client.recall(
+ bank_id="my-bank",
+ query="What does Alice do at Google?"
+)
+
+for result in results.results:
+ print(f"- {result.text}")
+
+# Search with options
+results = client.recall(
+ bank_id="my-bank",
+ query="What happened last spring?",
+ budget="high", # More thorough graph traversal
+ max_tokens=8192, # Return more context
+ types=["world"] # Only world facts
+)
+
+# Include entity information
+results = client.recall(
+ bank_id="my-bank",
+ query="Tell me about Alice",
+ include_entities=True,
+ max_entity_tokens=500
+)
+
+# Check entity details
+for entity in results.entities or []:
+ print(f"Entity: {entity.name}")
+ print(f"Observations: {entity.observations}")
+# [/docs:main-recall]
+
+
+# =============================================================================
+# Doc Examples - Reflect Section
+# =============================================================================
+
+# [docs:main-reflect]
+# Basic reflect
+response = client.reflect(
+ bank_id="my-bank",
+ query="Should we adopt TypeScript for our backend?"
+)
+
+print(response.text)
+print("\nBased on:", len(response.based_on or []), "facts")
+
+# Reflect with options
+response = client.reflect(
+ bank_id="my-bank",
+ query="What are Alice's strengths for the team lead role?",
+ budget="high" # More thorough reasoning
+)
+
+# See which facts influenced the response
+for fact in response.based_on or []:
+ print(f"- {fact.text}")
+# [/docs:main-reflect]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/my-bank")
+
+print("main-methods.py: All examples passed")
diff --git a/hindsight-docs/examples/api/memory-banks.mjs b/hindsight-docs/examples/api/memory-banks.mjs
new file mode 100644
index 00000000..6051dda0
--- /dev/null
+++ b/hindsight-docs/examples/api/memory-banks.mjs
@@ -0,0 +1,47 @@
+#!/usr/bin/env node
+/**
+ * Memory Banks API examples for Hindsight (Node.js)
+ * Run: node examples/api/memory-banks.mjs
+ */
+import { HindsightClient } from '@vectorize-io/hindsight-client';
+
+const HINDSIGHT_URL = process.env.HINDSIGHT_API_URL || 'http://localhost:8888';
+
+// =============================================================================
+// Setup (not shown in docs)
+// =============================================================================
+const client = new HindsightClient({ baseUrl: HINDSIGHT_URL });
+
+// =============================================================================
+// Doc Examples
+// =============================================================================
+
+// [docs:create-bank]
+await client.createBank('my-bank', {
+ name: 'Research Assistant',
+ background: 'I am a research assistant specializing in machine learning',
+ disposition: {
+ skepticism: 4,
+ literalism: 3,
+ empathy: 3
+ }
+});
+// [/docs:create-bank]
+
+
+// [docs:bank-background]
+await client.createBank('financial-advisor', {
+ background: `I am a conservative financial advisor with 20 years of experience.
+ I prioritize capital preservation over aggressive growth.
+ I have seen multiple market crashes and believe in diversification.`
+});
+// [/docs:bank-background]
+
+
+// =============================================================================
+// Cleanup (not shown in docs)
+// =============================================================================
+await fetch(`${HINDSIGHT_URL}/v1/default/banks/my-bank`, { method: 'DELETE' });
+await fetch(`${HINDSIGHT_URL}/v1/default/banks/financial-advisor`, { method: 'DELETE' });
+
+console.log('memory-banks.mjs: All examples passed');
diff --git a/hindsight-docs/examples/api/memory-banks.py b/hindsight-docs/examples/api/memory-banks.py
new file mode 100644
index 00000000..ba3b61f9
--- /dev/null
+++ b/hindsight-docs/examples/api/memory-banks.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+"""
+Memory Banks API examples for Hindsight.
+Run: python examples/api/memory-banks.py
+"""
+import os
+import requests
+
+HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+from hindsight_client import Hindsight
+
+client = Hindsight(base_url=HINDSIGHT_URL)
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:create-bank]
+client.create_bank(
+ bank_id="my-bank",
+ name="Research Assistant",
+ background="I am a research assistant specializing in machine learning",
+ disposition={
+ "skepticism": 4,
+ "literalism": 3,
+ "empathy": 3
+ }
+)
+# [/docs:create-bank]
+
+
+# [docs:bank-background]
+client.create_bank(
+ bank_id="financial-advisor",
+ background="""I am a conservative financial advisor with 20 years of experience.
+ I prioritize capital preservation over aggressive growth.
+ I have seen multiple market crashes and believe in diversification."""
+)
+# [/docs:bank-background]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/my-bank")
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/financial-advisor")
+
+print("memory-banks.py: All examples passed")
diff --git a/hindsight-docs/examples/api/opinions.py b/hindsight-docs/examples/api/opinions.py
new file mode 100644
index 00000000..848977e3
--- /dev/null
+++ b/hindsight-docs/examples/api/opinions.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+"""
+Opinions API examples for Hindsight.
+Run: python examples/api/opinions.py
+"""
+import os
+import requests
+
+HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+from hindsight_client import Hindsight
+
+client = Hindsight(base_url=HINDSIGHT_URL)
+
+# Seed some data about programming languages
+client.retain(bank_id="my-bank", content="Python is widely used for data science and machine learning")
+client.retain(bank_id="my-bank", content="Functional programming emphasizes immutability and pure functions")
+client.retain(bank_id="my-bank", content="Rust has better memory safety than C++")
+client.retain(bank_id="my-bank", content="C++ has a larger ecosystem and more libraries")
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:opinion-form]
+# Ask a question - the system may form opinions based on stored facts
+answer = client.reflect(
+ bank_id="my-bank",
+ query="What do you think about functional programming?"
+)
+
+print(answer.text)
+# [/docs:opinion-form]
+
+
+# [docs:opinion-search]
+# Search for facts about a topic
+results = client.recall(
+ bank_id="my-bank",
+ query="programming languages"
+)
+
+for result in results.results:
+ print(f"- {result.text}")
+# [/docs:opinion-search]
+
+
+# [docs:opinion-disposition]
+# Create two memory banks with different dispositions
+client.create_bank(
+ bank_id="open-minded",
+ disposition={"skepticism": 2, "literalism": 2, "empathy": 4}
+)
+
+client.create_bank(
+ bank_id="conservative",
+ disposition={"skepticism": 5, "literalism": 5, "empathy": 2}
+)
+
+# Store the same facts to both
+facts = [
+ "Rust has better memory safety than C++",
+ "C++ has a larger ecosystem and more libraries",
+ "Rust compile times are longer than C++"
+]
+for fact in facts:
+ client.retain(bank_id="open-minded", content=fact)
+ client.retain(bank_id="conservative", content=fact)
+
+# Ask both the same question - different dispositions lead to different responses
+q = "Should we rewrite our C++ codebase in Rust?"
+
+answer1 = client.reflect(bank_id="open-minded", query=q)
+print("Open-minded response:", answer1.text[:100], "...")
+
+answer2 = client.reflect(bank_id="conservative", query=q)
+print("Conservative response:", answer2.text[:100], "...")
+# [/docs:opinion-disposition]
+
+
+# [docs:opinion-in-reflect]
+answer = client.reflect(bank_id="my-bank", query="What language should I learn?")
+
+print("Response:", answer.text)
+
+# See which facts influenced the response
+if answer.based_on:
+ print("\nBased on these facts:")
+ for fact in answer.based_on:
+ print(f" - {fact.text}")
+# [/docs:opinion-in-reflect]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/my-bank")
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/open-minded")
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/conservative")
+
+print("opinions.py: All examples passed")
diff --git a/hindsight-docs/examples/api/quickstart.mjs b/hindsight-docs/examples/api/quickstart.mjs
new file mode 100644
index 00000000..7508476c
--- /dev/null
+++ b/hindsight-docs/examples/api/quickstart.mjs
@@ -0,0 +1,34 @@
+#!/usr/bin/env node
+/**
+ * Quickstart examples for Hindsight API (Node.js)
+ * Run: node examples/api/quickstart.mjs
+ */
+
+const HINDSIGHT_URL = process.env.HINDSIGHT_API_URL || 'http://localhost:8888';
+
+// =============================================================================
+// Doc Examples
+// =============================================================================
+
+// [docs:quickstart-full]
+import { HindsightClient } from '@vectorize-io/hindsight-client';
+
+const client = new HindsightClient({ baseUrl: 'http://localhost:8888' });
+
+// Retain: Store information
+await client.retain('my-bank', 'Alice works at Google as a software engineer');
+
+// Recall: Search memories
+await client.recall('my-bank', 'What does Alice do?');
+
+// Reflect: Generate response
+await client.reflect('my-bank', 'Tell me about Alice');
+// [/docs:quickstart-full]
+
+
+// =============================================================================
+// Cleanup (not shown in docs)
+// =============================================================================
+await fetch(`${HINDSIGHT_URL}/v1/default/banks/my-bank`, { method: 'DELETE' });
+
+console.log('quickstart.mjs: All examples passed');
diff --git a/hindsight-docs/examples/api/quickstart.py b/hindsight-docs/examples/api/quickstart.py
new file mode 100644
index 00000000..b09c3580
--- /dev/null
+++ b/hindsight-docs/examples/api/quickstart.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+"""
+Quickstart examples for Hindsight API.
+Run: python examples/api/quickstart.py
+"""
+import os
+import requests
+
+HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:quickstart-full]
+from hindsight_client import Hindsight
+
+client = Hindsight(base_url="http://localhost:8888")
+
+# Retain: Store information
+client.retain(bank_id="my-bank", content="Alice works at Google as a software engineer")
+
+# Recall: Search memories
+client.recall(bank_id="my-bank", query="What does Alice do?")
+
+# Reflect: Generate disposition-aware response
+client.reflect(bank_id="my-bank", query="Tell me about Alice")
+# [/docs:quickstart-full]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/my-bank")
+
+print("quickstart.py: All examples passed")
diff --git a/hindsight-docs/examples/api/quickstart.sh b/hindsight-docs/examples/api/quickstart.sh
new file mode 100755
index 00000000..26d444f7
--- /dev/null
+++ b/hindsight-docs/examples/api/quickstart.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Quickstart examples for Hindsight CLI
+# Run: bash examples/api/quickstart.sh
+
+set -e
+
+HINDSIGHT_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:quickstart-full]
+# Retain: Store information
+hindsight memory retain my-bank "Alice works at Google as a software engineer"
+
+# Recall: Search memories
+hindsight memory recall my-bank "What does Alice do?"
+
+# Reflect: Generate response
+hindsight memory reflect my-bank "Tell me about Alice"
+# [/docs:quickstart-full]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+curl -s -X DELETE "${HINDSIGHT_URL}/v1/default/banks/my-bank" > /dev/null
+
+echo "quickstart.sh: All examples passed"
diff --git a/hindsight-docs/examples/api/recall.mjs b/hindsight-docs/examples/api/recall.mjs
new file mode 100644
index 00000000..592c820e
--- /dev/null
+++ b/hindsight-docs/examples/api/recall.mjs
@@ -0,0 +1,61 @@
+#!/usr/bin/env node
+/**
+ * Recall API examples for Hindsight (Node.js)
+ * Run: node examples/api/recall.mjs
+ */
+import { HindsightClient } from '@vectorize-io/hindsight-client';
+
+const HINDSIGHT_URL = process.env.HINDSIGHT_API_URL || 'http://localhost:8888';
+
+// =============================================================================
+// Setup (not shown in docs)
+// =============================================================================
+const client = new HindsightClient({ baseUrl: HINDSIGHT_URL });
+
+// Seed some data for recall examples
+await client.retain('my-bank', 'Alice works at Google as a software engineer');
+await client.retain('my-bank', 'Alice loves hiking on weekends');
+await client.retain('my-bank', 'Bob is a data scientist who works with Alice');
+
+// =============================================================================
+// Doc Examples
+// =============================================================================
+
+// [docs:recall-basic]
+const response = await client.recall('my-bank', 'What does Alice do?');
+for (const r of response.results) {
+ console.log(`${r.text} (score: ${r.weight})`);
+}
+// [/docs:recall-basic]
+
+
+// [docs:recall-with-options]
+const detailedResponse = await client.recall('my-bank', 'What does Alice do?', {
+ types: ['world', 'experience'],
+ budget: 'high',
+ maxTokens: 8000,
+ trace: true
+});
+
+// Access results
+for (const r of detailedResponse.results) {
+ console.log(`${r.text} (score: ${r.weight})`);
+}
+// [/docs:recall-with-options]
+
+
+// [docs:recall-budget-levels]
+// Quick lookup
+const quickResults = await client.recall('my-bank', "Alice's email", { budget: 'low' });
+
+// Deep exploration
+const deepResults = await client.recall('my-bank', 'How are Alice and Bob connected?', { budget: 'high' });
+// [/docs:recall-budget-levels]
+
+
+// =============================================================================
+// Cleanup (not shown in docs)
+// =============================================================================
+await fetch(`${HINDSIGHT_URL}/v1/default/banks/my-bank`, { method: 'DELETE' });
+
+console.log('recall.mjs: All examples passed');
diff --git a/hindsight-docs/examples/api/recall.py b/hindsight-docs/examples/api/recall.py
new file mode 100644
index 00000000..aed8bdfd
--- /dev/null
+++ b/hindsight-docs/examples/api/recall.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+"""
+Recall API examples for Hindsight.
+Run: python examples/api/recall.py
+"""
+import os
+import requests
+
+HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+from hindsight_client import Hindsight
+
+client = Hindsight(base_url=HINDSIGHT_URL)
+
+# Seed some data for recall examples
+client.retain(bank_id="my-bank", content="Alice works at Google as a software engineer")
+client.retain(bank_id="my-bank", content="Alice loves hiking on weekends")
+client.retain(bank_id="my-bank", content="Bob is a data scientist who works with Alice")
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:recall-basic]
+response = client.recall(bank_id="my-bank", query="What does Alice do?")
+for r in response.results:
+ print(f"- {r.text}")
+# [/docs:recall-basic]
+
+
+# [docs:recall-with-options]
+response = client.recall(
+ bank_id="my-bank",
+ query="What does Alice do?",
+ types=["world", "experience"],
+ budget="high",
+ max_tokens=8000,
+ trace=True,
+ include_entities=True,
+ max_entity_tokens=500
+)
+
+# Access results
+for r in response.results:
+ print(f"- {r.text}")
+
+# Access entity observations (if include_entities=True)
+if response.entities:
+ for entity_id, entity in response.entities.items():
+ print(f"Entity: {entity.canonical_name}")
+# [/docs:recall-with-options]
+
+
+# [docs:recall-world-only]
+# Only world facts (objective information)
+world_facts = client.recall(
+ bank_id="my-bank",
+ query="Where does Alice work?",
+ types=["world"]
+)
+# [/docs:recall-world-only]
+
+
+# [docs:recall-experience-only]
+# Only experience (conversations and events)
+experience = client.recall(
+ bank_id="my-bank",
+ query="What have I recommended?",
+ types=["experience"]
+)
+# [/docs:recall-experience-only]
+
+
+# [docs:recall-opinions-only]
+# Only opinions (formed beliefs)
+opinions = client.recall(
+ bank_id="my-bank",
+ query="What do I think about Python?",
+ types=["opinion"]
+)
+# [/docs:recall-opinions-only]
+
+
+# [docs:recall-token-budget]
+# Fill up to 4K tokens of context with relevant memories
+results = client.recall(bank_id="my-bank", query="What do I know about Alice?", max_tokens=4096)
+
+# Smaller budget for quick lookups
+results = client.recall(bank_id="my-bank", query="Alice's email", max_tokens=500)
+# [/docs:recall-token-budget]
+
+
+# [docs:recall-include-entities]
+response = client.recall(
+ bank_id="my-bank",
+ query="What does Alice do?",
+ max_tokens=4096, # Budget for memories
+ include_entities=True,
+ max_entity_tokens=1000 # Budget for entity observations
+)
+
+# Access the additional context
+entities = response.entities or []
+# [/docs:recall-include-entities]
+
+
+# [docs:recall-budget-levels]
+# Quick lookup
+results = client.recall(bank_id="my-bank", query="Alice's email", budget="low")
+
+# Deep exploration
+results = client.recall(bank_id="my-bank", query="How are Alice and Bob connected?", budget="high")
+# [/docs:recall-budget-levels]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/my-bank")
+
+print("recall.py: All examples passed")
diff --git a/hindsight-docs/examples/api/recall.sh b/hindsight-docs/examples/api/recall.sh
new file mode 100755
index 00000000..241067cd
--- /dev/null
+++ b/hindsight-docs/examples/api/recall.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# Recall API examples for Hindsight CLI
+# Run: bash examples/api/recall.sh
+
+set -e
+
+HINDSIGHT_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+hindsight memory retain my-bank "Alice works at Google as a software engineer"
+hindsight memory retain my-bank "Alice loves hiking on weekends"
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:recall-basic]
+hindsight memory recall my-bank "What does Alice do?"
+# [/docs:recall-basic]
+
+
+# [docs:recall-with-options]
+hindsight memory recall my-bank "hiking recommendations" \
+ --budget high \
+ --max-tokens 8192
+# [/docs:recall-with-options]
+
+
+# [docs:recall-fact-type]
+hindsight memory recall my-bank "query" --fact-type world,opinion
+# [/docs:recall-fact-type]
+
+
+# [docs:recall-trace]
+hindsight memory recall my-bank "query" --trace
+# [/docs:recall-trace]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+curl -s -X DELETE "${HINDSIGHT_URL}/v1/default/banks/my-bank" > /dev/null
+
+echo "recall.sh: All examples passed"
diff --git a/hindsight-docs/examples/api/reflect.mjs b/hindsight-docs/examples/api/reflect.mjs
new file mode 100644
index 00000000..695c61fe
--- /dev/null
+++ b/hindsight-docs/examples/api/reflect.mjs
@@ -0,0 +1,78 @@
+#!/usr/bin/env node
+/**
+ * Reflect API examples for Hindsight (Node.js)
+ * Run: node examples/api/reflect.mjs
+ */
+import { HindsightClient } from '@vectorize-io/hindsight-client';
+
+const HINDSIGHT_URL = process.env.HINDSIGHT_API_URL || 'http://localhost:8888';
+
+// =============================================================================
+// Setup (not shown in docs)
+// =============================================================================
+const client = new HindsightClient({ baseUrl: HINDSIGHT_URL });
+
+// Seed some data for reflect examples
+await client.retain('my-bank', 'Alice works at Google as a software engineer');
+await client.retain('my-bank', 'Alice has been working there for 5 years');
+await client.retain('my-bank', 'Alice recently got promoted to senior engineer');
+
+// =============================================================================
+// Doc Examples
+// =============================================================================
+
+// [docs:reflect-basic]
+await client.reflect('my-bank', 'What should I know about Alice?');
+// [/docs:reflect-basic]
+
+
+// [docs:reflect-with-params]
+const response = await client.reflect('my-bank', 'What do you think about remote work?', {
+ budget: 'mid',
+ context: "We're considering a hybrid work policy"
+});
+// [/docs:reflect-with-params]
+
+
+// [docs:reflect-with-context]
+// Context helps the LLM understand the current situation
+const contextResponse = await client.reflect('my-bank', 'What do you think about the proposal?', {
+ context: "We're in a budget review meeting discussing Q4 spending"
+});
+// [/docs:reflect-with-context]
+
+
+// [docs:reflect-disposition]
+// Create a bank with specific disposition
+await client.createBank('cautious-advisor', {
+ background: 'I am a risk-aware financial advisor',
+ disposition: {
+ skepticism: 5,
+ literalism: 4,
+ empathy: 2
+ }
+});
+
+// Reflect responses will reflect this disposition
+const advisorResponse = await client.reflect('cautious-advisor', 'Should I invest in crypto?');
+// [/docs:reflect-disposition]
+
+
+// [docs:reflect-sources]
+const sourcesResponse = await client.reflect('my-bank', 'Tell me about Alice');
+
+console.log('Response:', sourcesResponse.text);
+console.log('\nBased on:');
+for (const fact of sourcesResponse.based_on || []) {
+ console.log(` - [${fact.type}] ${fact.text}`);
+}
+// [/docs:reflect-sources]
+
+
+// =============================================================================
+// Cleanup (not shown in docs)
+// =============================================================================
+await fetch(`${HINDSIGHT_URL}/v1/default/banks/my-bank`, { method: 'DELETE' });
+await fetch(`${HINDSIGHT_URL}/v1/default/banks/cautious-advisor`, { method: 'DELETE' });
+
+console.log('reflect.mjs: All examples passed');
diff --git a/hindsight-docs/examples/api/reflect.py b/hindsight-docs/examples/api/reflect.py
new file mode 100644
index 00000000..1487263c
--- /dev/null
+++ b/hindsight-docs/examples/api/reflect.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+"""
+Reflect API examples for Hindsight.
+Run: python examples/api/reflect.py
+"""
+import os
+import requests
+
+HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+from hindsight_client import Hindsight
+
+client = Hindsight(base_url=HINDSIGHT_URL)
+
+# Seed some data for reflect examples
+client.retain(bank_id="my-bank", content="Alice works at Google as a software engineer")
+client.retain(bank_id="my-bank", content="Alice has been working there for 5 years")
+client.retain(bank_id="my-bank", content="Alice recently got promoted to senior engineer")
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:reflect-basic]
+client.reflect(bank_id="my-bank", query="What should I know about Alice?")
+# [/docs:reflect-basic]
+
+
+# [docs:reflect-with-params]
+response = client.reflect(
+ bank_id="my-bank",
+ query="What do you think about remote work?",
+ budget="mid",
+ context="We're considering a hybrid work policy"
+)
+# [/docs:reflect-with-params]
+
+
+# [docs:reflect-with-context]
+# Context is passed to the LLM to help it understand the situation
+response = client.reflect(
+ bank_id="my-bank",
+ query="What do you think about the proposal?",
+ context="We're in a budget review meeting discussing Q4 spending"
+)
+# [/docs:reflect-with-context]
+
+
+# [docs:reflect-disposition]
+# Create a bank with specific disposition
+client.create_bank(
+ bank_id="cautious-advisor",
+ background="I am a risk-aware financial advisor",
+ disposition={
+ "skepticism": 5, # Very skeptical of claims
+ "literalism": 4, # Focuses on exact requirements
+ "empathy": 2 # Prioritizes facts over feelings
+ }
+)
+
+# Reflect responses will reflect this disposition
+response = client.reflect(
+ bank_id="cautious-advisor",
+ query="Should I invest in crypto?"
+)
+# Response will likely emphasize risks and caution
+# [/docs:reflect-disposition]
+
+
+# [docs:reflect-sources]
+response = client.reflect(bank_id="my-bank", query="Tell me about Alice")
+
+print("Response:", response.text)
+print("\nBased on:")
+for fact in response.based_on or []:
+ print(f" - [{fact.type}] {fact.text}")
+# [/docs:reflect-sources]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/my-bank")
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/cautious-advisor")
+
+print("reflect.py: All examples passed")
diff --git a/hindsight-docs/examples/api/reflect.sh b/hindsight-docs/examples/api/reflect.sh
new file mode 100755
index 00000000..30e46cc5
--- /dev/null
+++ b/hindsight-docs/examples/api/reflect.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Reflect API examples for Hindsight CLI
+# Run: bash examples/api/reflect.sh
+
+set -e
+
+HINDSIGHT_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+hindsight memory retain my-bank "Alice works at Google as a software engineer"
+hindsight memory retain my-bank "Alice has been working there for 5 years"
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:reflect-basic]
+hindsight memory reflect my-bank "What do you know about Alice?"
+# [/docs:reflect-basic]
+
+
+# [docs:reflect-with-context]
+hindsight memory reflect my-bank "Should I learn Python?" --context "career advice"
+# [/docs:reflect-with-context]
+
+
+# [docs:reflect-high-budget]
+hindsight memory reflect my-bank "Summarize my week" --budget high
+# [/docs:reflect-high-budget]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+curl -s -X DELETE "${HINDSIGHT_URL}/v1/default/banks/my-bank" > /dev/null
+
+echo "reflect.sh: All examples passed"
diff --git a/hindsight-docs/examples/api/retain.mjs b/hindsight-docs/examples/api/retain.mjs
new file mode 100644
index 00000000..e41322b3
--- /dev/null
+++ b/hindsight-docs/examples/api/retain.mjs
@@ -0,0 +1,58 @@
+#!/usr/bin/env node
+/**
+ * Retain API examples for Hindsight (Node.js)
+ * Run: node examples/api/retain.mjs
+ */
+import { HindsightClient } from '@vectorize-io/hindsight-client';
+
+const HINDSIGHT_URL = process.env.HINDSIGHT_API_URL || 'http://localhost:8888';
+
+// =============================================================================
+// Setup (not shown in docs)
+// =============================================================================
+const client = new HindsightClient({ baseUrl: HINDSIGHT_URL });
+
+// =============================================================================
+// Doc Examples
+// =============================================================================
+
+// [docs:retain-basic]
+await client.retain('my-bank', 'Alice works at Google as a software engineer');
+// [/docs:retain-basic]
+
+
+// [docs:retain-with-context]
+await client.retain('my-bank', 'Alice got promoted to senior engineer', {
+ context: 'career update',
+ timestamp: '2024-03-15T10:00:00Z'
+});
+// [/docs:retain-with-context]
+
+
+// [docs:retain-batch]
+await client.retainBatch('my-bank', [
+ { content: 'Alice works at Google', context: 'career' },
+ { content: 'Bob is a data scientist at Meta', context: 'career' },
+ { content: 'Alice and Bob are friends', context: 'relationship' }
+], { documentId: 'conversation_001' });
+// [/docs:retain-batch]
+
+
+// [docs:retain-async]
+// Start async ingestion (returns immediately)
+await client.retainBatch('my-bank', [
+ { content: 'Large batch item 1' },
+ { content: 'Large batch item 2' },
+], {
+ documentId: 'large-doc',
+ async: true
+});
+// [/docs:retain-async]
+
+
+// =============================================================================
+// Cleanup (not shown in docs)
+// =============================================================================
+await fetch(`${HINDSIGHT_URL}/v1/default/banks/my-bank`, { method: 'DELETE' });
+
+console.log('retain.mjs: All examples passed');
diff --git a/hindsight-docs/examples/api/retain.py b/hindsight-docs/examples/api/retain.py
new file mode 100644
index 00000000..82d11b3b
--- /dev/null
+++ b/hindsight-docs/examples/api/retain.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+"""
+Retain API examples for Hindsight.
+Run: python examples/api/retain.py
+"""
+import os
+import requests
+
+HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
+
+# =============================================================================
+# Setup (not shown in docs)
+# =============================================================================
+from hindsight_client import Hindsight
+
+client = Hindsight(base_url=HINDSIGHT_URL)
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:retain-basic]
+client.retain(
+ bank_id="my-bank",
+ content="Alice works at Google as a software engineer"
+)
+# [/docs:retain-basic]
+
+
+# [docs:retain-with-context]
+client.retain(
+ bank_id="my-bank",
+ content="Alice got promoted to senior engineer",
+ context="career update",
+ timestamp="2024-03-15T10:00:00Z"
+)
+# [/docs:retain-with-context]
+
+
+# [docs:retain-batch]
+client.retain_batch(
+ bank_id="my-bank",
+ items=[
+ {"content": "Alice works at Google", "context": "career"},
+ {"content": "Bob is a data scientist at Meta", "context": "career"},
+ {"content": "Alice and Bob are friends", "context": "relationship"}
+ ],
+ document_id="conversation_001"
+)
+# [/docs:retain-batch]
+
+
+# [docs:retain-async]
+# Start async ingestion (returns immediately)
+result = client.retain_batch(
+ bank_id="my-bank",
+ items=[
+ {"content": "Large batch item 1"},
+ {"content": "Large batch item 2"},
+ ],
+ document_id="large-doc",
+ retain_async=True
+)
+
+# Check if it was processed asynchronously
+print(result.var_async) # True
+# [/docs:retain-async]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+requests.delete(f"{HINDSIGHT_URL}/v1/default/banks/my-bank")
+
+print("retain.py: All examples passed")
diff --git a/hindsight-docs/examples/api/retain.sh b/hindsight-docs/examples/api/retain.sh
new file mode 100755
index 00000000..0b2ad2bf
--- /dev/null
+++ b/hindsight-docs/examples/api/retain.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Retain API examples for Hindsight CLI
+# Run: bash examples/api/retain.sh
+
+set -e
+
+HINDSIGHT_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
+
+# =============================================================================
+# Doc Examples
+# =============================================================================
+
+# [docs:retain-basic]
+hindsight memory retain my-bank "Alice works at Google as a software engineer"
+# [/docs:retain-basic]
+
+
+# [docs:retain-with-context]
+hindsight memory retain my-bank "Alice got promoted" \
+ --context "career update"
+# [/docs:retain-with-context]
+
+
+# [docs:retain-async]
+hindsight memory retain my-bank "Meeting notes" --async
+# [/docs:retain-async]
+
+
+# =============================================================================
+# Cleanup (not shown in docs)
+# =============================================================================
+curl -s -X DELETE "${HINDSIGHT_URL}/v1/default/banks/my-bank" > /dev/null
+
+echo "retain.sh: All examples passed"
diff --git a/hindsight-docs/examples/run-examples.sh b/hindsight-docs/examples/run-examples.sh
new file mode 100755
index 00000000..a8b0d59b
--- /dev/null
+++ b/hindsight-docs/examples/run-examples.sh
@@ -0,0 +1,129 @@
+#!/bin/bash
+# Run all documentation example scripts
+# Usage: ./examples/run-examples.sh [python|node|cli|all]
+
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+HINDSIGHT_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
+
+# Colors for output
+GREEN='\033[0;32m'
+RED='\033[0;31m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+passed=0
+failed=0
+skipped=0
+
+run_python_examples() {
+ echo -e "${YELLOW}Running Python examples...${NC}"
+ for f in "$SCRIPT_DIR"/api/*.py; do
+ if [ -f "$f" ]; then
+ echo -n " $(basename "$f"): "
+ if python "$f" 2>&1; then
+ echo -e "${GREEN}PASSED${NC}"
+ ((passed++))
+ else
+ echo -e "${RED}FAILED${NC}"
+ ((failed++))
+ fi
+ fi
+ done
+}
+
+run_node_examples() {
+ echo -e "${YELLOW}Running Node.js examples...${NC}"
+ for f in "$SCRIPT_DIR"/api/*.mjs; do
+ if [ -f "$f" ]; then
+ echo -n " $(basename "$f"): "
+ if node "$f" 2>&1; then
+ echo -e "${GREEN}PASSED${NC}"
+ ((passed++))
+ else
+ echo -e "${RED}FAILED${NC}"
+ ((failed++))
+ fi
+ fi
+ done
+}
+
+run_cli_examples() {
+ echo -e "${YELLOW}Running CLI examples...${NC}"
+
+ # Check if hindsight CLI is available
+ if ! command -v hindsight &> /dev/null; then
+ echo -e " ${YELLOW}SKIPPED (hindsight CLI not installed)${NC}"
+ for f in "$SCRIPT_DIR"/api/*.sh; do
+ if [ -f "$f" ]; then
+ ((skipped++))
+ fi
+ done
+ return
+ fi
+
+ for f in "$SCRIPT_DIR"/api/*.sh; do
+ if [ -f "$f" ]; then
+ echo -n " $(basename "$f"): "
+ if bash "$f" 2>&1; then
+ echo -e "${GREEN}PASSED${NC}"
+ ((passed++))
+ else
+ echo -e "${RED}FAILED${NC}"
+ ((failed++))
+ fi
+ fi
+ done
+}
+
+# Wait for server to be ready
+wait_for_server() {
+ echo "Waiting for Hindsight server at $HINDSIGHT_URL..."
+ for i in {1..30}; do
+ if curl -s "$HINDSIGHT_URL/health" > /dev/null 2>&1; then
+ echo "Server is ready!"
+ return 0
+ fi
+ sleep 1
+ done
+ echo "Server not available after 30 seconds"
+ return 1
+}
+
+# Main
+case "${1:-all}" in
+ python)
+ wait_for_server
+ run_python_examples
+ ;;
+ node)
+ wait_for_server
+ run_node_examples
+ ;;
+ cli)
+ wait_for_server
+ run_cli_examples
+ ;;
+ all)
+ wait_for_server
+ run_python_examples
+ echo ""
+ run_node_examples
+ echo ""
+ run_cli_examples
+ ;;
+ *)
+ echo "Usage: $0 [python|node|cli|all]"
+ exit 1
+ ;;
+esac
+
+echo ""
+echo "========================================"
+echo -e "Results: ${GREEN}$passed passed${NC}, ${RED}$failed failed${NC}, ${YELLOW}$skipped skipped${NC}"
+echo "========================================"
+
+if [ $failed -gt 0 ]; then
+ exit 1
+fi
diff --git a/hindsight-docs/package.json b/hindsight-docs/package.json
index 71d7c87e..2747dc07 100644
--- a/hindsight-docs/package.json
+++ b/hindsight-docs/package.json
@@ -22,6 +22,7 @@
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
+ "raw-loader": "^4.0.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"redocusaurus": "^2.5.0"
diff --git a/hindsight-docs/src/components/CodeSnippet.tsx b/hindsight-docs/src/components/CodeSnippet.tsx
new file mode 100644
index 00000000..8c8a1475
--- /dev/null
+++ b/hindsight-docs/src/components/CodeSnippet.tsx
@@ -0,0 +1,110 @@
+import React from 'react';
+import CodeBlock from '@theme/CodeBlock';
+
+interface CodeSnippetProps {
+ /** Raw file content (use raw-loader to import) */
+ code: string;
+ /** Section marker name (e.g., "retain-basic" for [docs:retain-basic]) */
+ section: string;
+ /** Language for syntax highlighting */
+ language: string;
+ /** Optional title for the code block */
+ title?: string;
+}
+
+/**
+ * Extracts a marked section from source code.
+ *
+ * Markers are in the format:
+ * - Start: `# [docs:section-name]` (Python/Bash) or `// [docs:section-name]` (JS/TS)
+ * - End: `# [/docs:section-name]` (Python/Bash) or `// [/docs:section-name]` (JS/TS)
+ */
+function extractSection(code: string, section: string): string {
+ // Match both Python/Bash (#) and JS/TS (//) comment styles
+ const startPattern = new RegExp(`(?:#|//)\\s*\\[docs:${section}\\]`);
+ const endPattern = new RegExp(`(?:#|//)\\s*\\[/docs:${section}\\]`);
+
+ const lines = code.split('\n');
+ let inSection = false;
+ const sectionLines: string[] = [];
+
+ for (const line of lines) {
+ if (startPattern.test(line)) {
+ inSection = true;
+ continue;
+ }
+ if (endPattern.test(line)) {
+ inSection = false;
+ continue;
+ }
+ if (inSection) {
+ sectionLines.push(line);
+ }
+ }
+
+ if (sectionLines.length === 0) {
+ console.warn(`CodeSnippet: Section "${section}" not found in code`);
+ return `// Section "${section}" not found`;
+ }
+
+ // Trim leading/trailing empty lines and normalize indentation
+ return trimAndNormalize(sectionLines);
+}
+
+/**
+ * Trims leading/trailing empty lines and removes common leading indentation.
+ */
+function trimAndNormalize(lines: string[]): string {
+ // Remove leading empty lines
+ while (lines.length > 0 && lines[0].trim() === '') {
+ lines.shift();
+ }
+ // Remove trailing empty lines
+ while (lines.length > 0 && lines[lines.length - 1].trim() === '') {
+ lines.pop();
+ }
+
+ if (lines.length === 0) return '';
+
+ // Find minimum indentation (ignoring empty lines)
+ const nonEmptyLines = lines.filter(l => l.trim() !== '');
+ if (nonEmptyLines.length === 0) return '';
+
+ const minIndent = Math.min(
+ ...nonEmptyLines.map(line => {
+ const match = line.match(/^(\s*)/);
+ return match ? match[1].length : 0;
+ })
+ );
+
+ // Remove common indentation
+ return lines
+ .map(line => line.slice(minIndent))
+ .join('\n');
+}
+
+/**
+ * CodeSnippet component for embedding code from example files.
+ *
+ * Usage in MDX:
+ * ```mdx
+ * import CodeSnippet from '@site/src/components/CodeSnippet';
+ * import retainPy from '!!raw-loader!@site/examples/api/retain.py';
+ *
+ *
+ * ```
+ */
+export default function CodeSnippet({
+ code,
+ section,
+ language,
+ title
+}: CodeSnippetProps): React.ReactElement {
+ const extractedCode = extractSection(code, section);
+
+ return (
+
+ {extractedCode}
+
+ );
+}
diff --git a/package-lock.json b/package-lock.json
index f7447d0d..6d07dc28 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -105,6 +105,7 @@
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
+ "raw-loader": "^4.0.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"redocusaurus": "^2.5.0"
@@ -24244,6 +24245,44 @@
"node": ">=0.10.0"
}
},
+ "node_modules/raw-loader": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
+ "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
+ "license": "MIT",
+ "dependencies": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.0.0 || ^5.0.0"
+ }
+ },
+ "node_modules/raw-loader/node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
"node_modules/rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
diff --git a/uv.lock b/uv.lock
index fff8eb16..8a1150bc 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1141,7 +1141,7 @@ wheels = [
[[package]]
name = "hindsight-all"
-version = "0.1.7"
+version = "0.1.8"
source = { editable = "hindsight" }
dependencies = [
{ name = "hindsight-api" },
@@ -1165,7 +1165,7 @@ provides-extras = ["test"]
[[package]]
name = "hindsight-api"
-version = "0.1.7"
+version = "0.1.8"
source = { editable = "hindsight-api" }
dependencies = [
{ name = "alembic" },
@@ -1269,7 +1269,7 @@ dev = [
[[package]]
name = "hindsight-client"
-version = "0.1.7"
+version = "0.1.8"
source = { editable = "hindsight-clients/python" }
dependencies = [
{ name = "aiohttp" },
@@ -1284,6 +1284,7 @@ dependencies = [
test = [
{ name = "pytest" },
{ name = "pytest-asyncio" },
+ { name = "requests" },
]
[package.metadata]
@@ -1294,6 +1295,7 @@ requires-dist = [
{ name = "pytest", marker = "extra == 'test'", specifier = ">=7.0.0" },
{ name = "pytest-asyncio", marker = "extra == 'test'", specifier = ">=0.21.0" },
{ name = "python-dateutil", specifier = ">=2.8.2" },
+ { name = "requests", marker = "extra == 'test'", specifier = ">=2.28.0" },
{ name = "typing-extensions", specifier = ">=4.7.1" },
{ name = "urllib3", specifier = ">=2.1.0,<3.0.0" },
]
@@ -1301,7 +1303,7 @@ provides-extras = ["test"]
[[package]]
name = "hindsight-dev"
-version = "0.1.7"
+version = "0.1.8"
source = { editable = "hindsight-dev" }
dependencies = [
{ name = "hindsight-api" },