Compare commits
11
Commits
moltbot
...
docValidation
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e521914f0f | ||
|
|
7cb469ff75 | ||
|
|
9118e7b4cb | ||
|
|
841a66f375 | ||
|
|
eb06adb2be | ||
|
|
3913788fd8 | ||
|
|
6ea02eb023 | ||
|
|
55154384f6 | ||
|
|
19e4e2d635 | ||
|
|
8f2396f04a | ||
|
|
bffc0ee0d0 |
@@ -495,4 +495,96 @@ jobs:
|
||||
|
||||
- name: Run tests
|
||||
working-directory: ./hindsight-integrations/litellm
|
||||
run: uv run pytest tests -v
|
||||
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"
|
||||
@@ -20,6 +20,7 @@ dependencies = [
|
||||
test = [
|
||||
"pytest>=7.0.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
"requests>=2.28.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
|
||||
@@ -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
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={retainPy} section="retain-basic" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={retainMjs} section="retain-basic" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
<CodeSnippet code={retainSh} section="retain-basic" language="bash" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Store with Context
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={retainPy} section="retain-with-context" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={retainMjs} section="retain-with-context" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
<CodeSnippet code={retainSh} section="retain-with-context" language="bash" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Batch Ingestion
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={retainPy} section="retain-batch" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={retainMjs} section="retain-batch" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Async Ingestion
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={retainPy} section="retain-async" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={retainMjs} section="retain-async" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -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';
|
||||
<CodeSnippet code={myScript} section="my-new-section" language="python" />
|
||||
```
|
||||
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`).
|
||||
Executable
+209
@@ -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"
|
||||
@@ -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');
|
||||
@@ -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")
|
||||
@@ -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")
|
||||
@@ -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');
|
||||
@@ -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")
|
||||
@@ -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")
|
||||
@@ -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');
|
||||
@@ -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")
|
||||
Executable
+30
@@ -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"
|
||||
@@ -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');
|
||||
@@ -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")
|
||||
Executable
+46
@@ -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"
|
||||
@@ -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');
|
||||
@@ -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")
|
||||
Executable
+39
@@ -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"
|
||||
@@ -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');
|
||||
@@ -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")
|
||||
Executable
+34
@@ -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"
|
||||
Executable
+129
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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';
|
||||
*
|
||||
* <CodeSnippet code={retainPy} section="retain-basic" language="python" />
|
||||
* ```
|
||||
*/
|
||||
export default function CodeSnippet({
|
||||
code,
|
||||
section,
|
||||
language,
|
||||
title
|
||||
}: CodeSnippetProps): React.ReactElement {
|
||||
const extractedCode = extractSection(code, section);
|
||||
|
||||
return (
|
||||
<CodeBlock language={language} title={title}>
|
||||
{extractedCode}
|
||||
</CodeBlock>
|
||||
);
|
||||
}
|
||||
Generated
+39
@@ -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",
|
||||
|
||||
@@ -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" },
|
||||
|
||||
Reference in New Issue
Block a user