Compare commits
12
Commits
doc-ref
...
finalizeDocs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
457160e88c | ||
|
|
b84630f06c | ||
|
|
b113bd4221 | ||
|
|
56d808ef77 | ||
|
|
1676bdd952 | ||
|
|
6914e1ed48 | ||
|
|
81524ef7ff | ||
|
|
33bfcf02b5 | ||
|
|
8bea492cd2 | ||
|
|
655d38995a | ||
|
|
e25139343d | ||
|
|
a3fda3549e |
@@ -173,6 +173,13 @@ jobs:
|
||||
working-directory: hindsight-cli
|
||||
run: cargo build --release
|
||||
|
||||
- name: Upload CLI artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: hindsight-cli
|
||||
path: hindsight-cli/target/release/hindsight
|
||||
retention-days: 1
|
||||
|
||||
lint-helm-chart:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -558,6 +565,7 @@ jobs:
|
||||
|
||||
test-doc-examples:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-rust-cli
|
||||
env:
|
||||
HINDSIGHT_API_LLM_PROVIDER: groq
|
||||
HINDSIGHT_API_LLM_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
||||
@@ -569,6 +577,15 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download CLI artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: hindsight-cli
|
||||
path: /usr/local/bin
|
||||
|
||||
- name: Make CLI executable
|
||||
run: chmod +x /usr/local/bin/hindsight
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
@@ -642,6 +659,16 @@ jobs:
|
||||
node "$f"
|
||||
done
|
||||
|
||||
- name: Configure CLI
|
||||
run: hindsight configure --api-url http://localhost:8888
|
||||
|
||||
- name: Run CLI doc examples
|
||||
run: |
|
||||
for f in hindsight-docs/examples/api/*.sh; do
|
||||
echo "Running $f..."
|
||||
bash "$f"
|
||||
done
|
||||
|
||||
- name: Show API server logs
|
||||
if: always()
|
||||
run: |
|
||||
|
||||
@@ -944,7 +944,7 @@ fn render_banks(f: &mut Frame, app: &mut App, area: Rect) {
|
||||
.banks
|
||||
.iter()
|
||||
.map(|bank| {
|
||||
let name = if bank.name.is_empty() { "Unnamed" } else { &bank.name };
|
||||
let name = bank.name.as_deref().filter(|s| !s.is_empty()).unwrap_or("Unnamed");
|
||||
let content = format!("{} - {}", bank.bank_id, name);
|
||||
ListItem::new(content).style(Style::default().fg(Color::White))
|
||||
})
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# Documents
|
||||
|
||||
Track and manage document sources in your memory bank. Documents provide traceability — knowing where memories came from.
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
:::tip Prerequisites
|
||||
Make sure you've completed the [Quick Start](./quickstart) and understand [how retain works](./retain).
|
||||
:::
|
||||
|
||||
## What Are Documents?
|
||||
|
||||
Documents are containers for retained content. They help you:
|
||||
|
||||
- **Track sources** — Know which PDF, conversation, or file a memory came from
|
||||
- **Update content** — Re-retain a document to update its facts
|
||||
- **Delete in bulk** — Remove all memories from a document at once
|
||||
- **Organize memories** — Group related facts by source
|
||||
|
||||
## Chunks
|
||||
|
||||
When you retain content, Hindsight splits it into chunks before extracting facts. These chunks are stored alongside the extracted memories, preserving the original text segments.
|
||||
|
||||
**Why chunks matter:**
|
||||
- **Context preservation** — Chunks contain the raw text that generated facts, useful when you need the exact wording
|
||||
- **Richer recall** — Including chunks in recall provides surrounding context for matched facts
|
||||
|
||||
:::tip Include Chunks in Recall
|
||||
Use `include_chunks=True` in your recall calls to get the original text chunks alongside fact results. See [Recall](./recall) for details.
|
||||
:::
|
||||
|
||||
## Retain with Document ID
|
||||
|
||||
Associate retained content with a document:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
from hindsight_client import Hindsight
|
||||
|
||||
client = Hindsight(base_url="http://localhost:8888")
|
||||
|
||||
# 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"
|
||||
)
|
||||
|
||||
# From file
|
||||
with open("notes.txt") as f:
|
||||
client.retain(
|
||||
bank_id="my-bank",
|
||||
content=f.read(),
|
||||
document_id="notes-2024-03-15"
|
||||
)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
import { HindsightClient } from '@vectorize-io/hindsight-client';
|
||||
|
||||
const client = new HindsightClient({ baseUrl: 'http://localhost:8888' });
|
||||
|
||||
// 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' });
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Retain file with document ID
|
||||
hindsight retain my-bank --file notes.txt --document-id notes-2024-03-15
|
||||
|
||||
# Batch retain directory
|
||||
hindsight retain my-bank --files docs/*.md --document-id project-docs
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Update Documents
|
||||
|
||||
Re-retaining with the same document_id **replaces** the old content:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# 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"
|
||||
)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
// 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'
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Original
|
||||
hindsight retain my-bank "Project deadline: March 31" --document-id project-plan
|
||||
|
||||
# Update
|
||||
hindsight retain my-bank "Project deadline: April 15 (extended)" --document-id project-plan
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Get Document
|
||||
|
||||
Retrieve a document's original text and metadata. This is useful for expanding document context after a recall operation returns memories with document references.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
from hindsight_client_api import ApiClient, Configuration
|
||||
from hindsight_client_api.api import DefaultApi
|
||||
|
||||
config = Configuration(host="http://localhost:8888")
|
||||
api_client = ApiClient(config)
|
||||
api = DefaultApi(api_client)
|
||||
|
||||
# Get document to expand context from recall results
|
||||
doc = 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}")
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
import { sdk, createClient, createConfig } from '@vectorize-io/hindsight-client';
|
||||
|
||||
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}`);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
hindsight documents get my-bank meeting-2024-03-15
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Document Response Format
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "meeting-2024-03-15",
|
||||
"bank_id": "my-bank",
|
||||
"original_text": "Alice presented the Q4 roadmap...",
|
||||
"content_hash": "abc123def456",
|
||||
"memory_unit_count": 12,
|
||||
"created_at": "2024-03-15T14:00:00Z",
|
||||
"updated_at": "2024-03-15T14:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [**Entities**](./entities) — Track people, places, and concepts
|
||||
- [**Operations**](./operations) — Monitor background tasks
|
||||
- [**Memory Banks**](./memory-banks) — Configure bank settings
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# Documents
|
||||
|
||||
Track and manage document sources in your memory bank. Documents provide traceability — knowing where memories came from.
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeSnippet from '@site/src/components/CodeSnippet';
|
||||
|
||||
{/* Import raw source files */}
|
||||
import documentsPy from '!!raw-loader!@site/examples/api/documents.py';
|
||||
import documentsMjs from '!!raw-loader!@site/examples/api/documents.mjs';
|
||||
|
||||
:::tip Prerequisites
|
||||
Make sure you've completed the [Quick Start](./quickstart) and understand [how retain works](./retain).
|
||||
:::
|
||||
|
||||
## What Are Documents?
|
||||
|
||||
Documents are containers for retained content. They help you:
|
||||
|
||||
- **Track sources** — Know which PDF, conversation, or file a memory came from
|
||||
- **Update content** — Re-retain a document to update its facts
|
||||
- **Delete in bulk** — Remove all memories from a document at once
|
||||
- **Organize memories** — Group related facts by source
|
||||
|
||||
## Chunks
|
||||
|
||||
When you retain content, Hindsight splits it into chunks before extracting facts. These chunks are stored alongside the extracted memories, preserving the original text segments.
|
||||
|
||||
**Why chunks matter:**
|
||||
- **Context preservation** — Chunks contain the raw text that generated facts, useful when you need the exact wording
|
||||
- **Richer recall** — Including chunks in recall provides surrounding context for matched facts
|
||||
|
||||
:::tip Include Chunks in Recall
|
||||
Use `include_chunks=True` in your recall calls to get the original text chunks alongside fact results. See [Recall](./recall) for details.
|
||||
:::
|
||||
|
||||
## Retain with Document ID
|
||||
|
||||
Associate retained content with a document:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={documentsPy} section="document-retain" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={documentsMjs} section="document-retain" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Retain content with document ID
|
||||
hindsight memory retain my-bank "Meeting notes content..." --doc-id notes-2024-03-15
|
||||
|
||||
# Batch retain from files
|
||||
hindsight memory retain-files my-bank docs/
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Update Documents
|
||||
|
||||
Re-retaining with the same document_id **replaces** the old content:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={documentsPy} section="document-update" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={documentsMjs} section="document-update" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Original
|
||||
hindsight memory retain my-bank "Project deadline: March 31" --doc-id project-plan
|
||||
|
||||
# Update
|
||||
hindsight memory retain my-bank "Project deadline: April 15 (extended)" --doc-id project-plan
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Get Document
|
||||
|
||||
Retrieve a document's original text and metadata. This is useful for expanding document context after a recall operation returns memories with document references.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={documentsPy} section="document-get" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={documentsMjs} section="document-get" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
hindsight document get my-bank meeting-2024-03-15
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Document Response Format
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "meeting-2024-03-15",
|
||||
"bank_id": "my-bank",
|
||||
"original_text": "Alice presented the Q4 roadmap...",
|
||||
"content_hash": "abc123def456",
|
||||
"memory_unit_count": 12,
|
||||
"created_at": "2024-03-15T14:00:00Z",
|
||||
"updated_at": "2024-03-15T14:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [**Entities**](./entities) — Track people, places, and concepts
|
||||
- [**Operations**](./operations) — Monitor background tasks
|
||||
- [**Memory Banks**](./memory-banks) — Configure bank settings
|
||||
@@ -1,315 +0,0 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Main Methods
|
||||
|
||||
Hindsight provides three core operations: **retain**, **recall**, and **reflect**.
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
:::tip Prerequisites
|
||||
Make sure you've [installed Hindsight](../installation) and completed the [Quick Start](./quickstart).
|
||||
:::
|
||||
|
||||
## Retain: Store Information
|
||||
|
||||
Store conversations, documents, and facts into a memory bank.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# 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",
|
||||
contents=[
|
||||
{"content": "Bob prefers Python for data science"},
|
||||
{"content": "Alice recommends using pytest for testing"},
|
||||
{"content": "The team uses GitHub for code reviews"}
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```javascript
|
||||
// Store a single fact
|
||||
await client.retain({
|
||||
bankId: 'my-bank',
|
||||
content: 'Alice joined Google in March 2024 as a Senior ML Engineer'
|
||||
});
|
||||
|
||||
// Store a conversation
|
||||
await client.retain({
|
||||
bankId: 'my-bank',
|
||||
content: `
|
||||
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.
|
||||
`,
|
||||
context: 'Daily standup conversation'
|
||||
});
|
||||
|
||||
// Batch retain
|
||||
await client.retainBatch({
|
||||
bankId: 'my-bank',
|
||||
contents: [
|
||||
{ content: 'Bob prefers Python for data science' },
|
||||
{ content: 'Alice recommends using pytest for testing' },
|
||||
{ content: 'The team uses GitHub for code reviews' }
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Store a single fact
|
||||
hindsight retain my-bank "Alice joined Google in March 2024 as a Senior ML Engineer"
|
||||
|
||||
# Store from a file
|
||||
hindsight retain my-bank --file conversation.txt --context "Daily standup"
|
||||
|
||||
# Store multiple files
|
||||
hindsight retain my-bank --files docs/*.md
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
**What happens:** Content is processed by an LLM to extract rich facts, identify entities, and build connections in a knowledge graph.
|
||||
|
||||
**See:** [Retain Details](./retain) for advanced options and parameters.
|
||||
|
||||
---
|
||||
|
||||
## Recall: Search Memories
|
||||
|
||||
Search for relevant memories using multi-strategy retrieval.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# Basic search
|
||||
results = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="What does Alice do at Google?"
|
||||
)
|
||||
|
||||
for result in results:
|
||||
print(f"[{result['weight']:.2f}] {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
|
||||
fact_type="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"]:
|
||||
print(f"Entity: {entity['name']}")
|
||||
print(f"Observations: {entity['observations']}")
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```javascript
|
||||
// Basic search
|
||||
const results = await client.recall({
|
||||
bankId: 'my-bank',
|
||||
query: 'What does Alice do at Google?'
|
||||
});
|
||||
|
||||
results.forEach(r => {
|
||||
console.log(`[${r.weight.toFixed(2)}] ${r.text}`);
|
||||
});
|
||||
|
||||
// Search with options
|
||||
const detailedResults = await client.recall({
|
||||
bankId: 'my-bank',
|
||||
query: 'What happened last spring?',
|
||||
budget: 'high',
|
||||
maxTokens: 8192,
|
||||
factType: 'world'
|
||||
});
|
||||
|
||||
// Include entity information
|
||||
const withEntities = await client.recall({
|
||||
bankId: 'my-bank',
|
||||
query: 'Tell me about Alice',
|
||||
includeEntities: true,
|
||||
maxEntityTokens: 500
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Basic search
|
||||
hindsight recall my-bank "What does Alice do at Google?"
|
||||
|
||||
# Search with options
|
||||
hindsight recall my-bank "What happened last spring?" \
|
||||
--budget high \
|
||||
--max-tokens 8192 \
|
||||
--fact-type world
|
||||
|
||||
# Verbose output (shows weights and sources)
|
||||
hindsight recall my-bank "Tell me about Alice" -v
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
**What happens:** Four search strategies (semantic, keyword, graph, temporal) run in parallel, results are fused and reranked.
|
||||
|
||||
**See:** [Recall Details](./recall) for tuning quality vs latency.
|
||||
|
||||
---
|
||||
|
||||
## Reflect: Reason with Disposition
|
||||
|
||||
Generate disposition-aware responses that form opinions based on evidence.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# 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"]["world"]), "facts")
|
||||
print("New opinions:", len(response["new_opinions"]))
|
||||
|
||||
# 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
|
||||
include_entities=True
|
||||
)
|
||||
|
||||
# Access formed opinions
|
||||
for opinion in response["new_opinions"]:
|
||||
print(f"Opinion: {opinion['text']}")
|
||||
print(f"Confidence: {opinion['confidence']}")
|
||||
|
||||
# See which facts influenced the response
|
||||
for fact in response["based_on"]["world"]:
|
||||
print(f"[{fact['weight']:.2f}] {fact['text']}")
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```javascript
|
||||
// Basic reflect
|
||||
const response = await client.reflect({
|
||||
bankId: 'my-bank',
|
||||
query: 'Should we adopt TypeScript for our backend?'
|
||||
});
|
||||
|
||||
console.log(response.text);
|
||||
console.log(`\nBased on: ${response.basedOn.world.length} facts`);
|
||||
console.log(`New opinions: ${response.newOpinions.length}`);
|
||||
|
||||
// Reflect with options
|
||||
const detailed = await client.reflect({
|
||||
bankId: 'my-bank',
|
||||
query: "What are Alice's strengths for the team lead role?",
|
||||
budget: 'high',
|
||||
includeEntities: true
|
||||
});
|
||||
|
||||
// Access formed opinions
|
||||
detailed.newOpinions.forEach(op => {
|
||||
console.log(`Opinion: ${op.text}`);
|
||||
console.log(`Confidence: ${op.confidence}`);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Basic reflect
|
||||
hindsight reflect my-bank "Should we adopt TypeScript for our backend?"
|
||||
|
||||
# Verbose output (shows sources and opinions)
|
||||
hindsight reflect my-bank "What are Alice's strengths for the team lead role?" -v
|
||||
|
||||
# With higher reasoning budget
|
||||
hindsight reflect my-bank "Analyze our tech stack" --budget high
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
**What happens:** Memories are recalled, bank disposition is loaded, LLM reasons through evidence, new opinions are formed and stored.
|
||||
|
||||
**See:** [Reflect Details](./reflect) for disposition configuration.
|
||||
|
||||
---
|
||||
|
||||
## Comparison
|
||||
|
||||
| Feature | Retain | Recall | Reflect |
|
||||
|---------|--------|--------|---------|
|
||||
| **Purpose** | Store information | Find information | Reason about information |
|
||||
| **Input** | Raw text/documents | Search query | Question/prompt |
|
||||
| **Output** | Memory IDs | Ranked facts | Reasoned response + opinions |
|
||||
| **Uses LLM** | Yes (extraction) | No | Yes (generation) |
|
||||
| **Forms opinions** | No | No | Yes |
|
||||
| **Disposition** | No | No | Yes |
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [**Retain**](./retain) — Advanced options for storing memories
|
||||
- [**Recall**](./recall) — Tuning search quality and performance
|
||||
- [**Reflect**](./reflect) — Configuring disposition and opinions
|
||||
- [**Memory Banks**](./memory-banks) — Managing memory bank disposition
|
||||
@@ -0,0 +1,141 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Main Methods
|
||||
|
||||
Hindsight provides three core operations: **retain**, **recall**, and **reflect**.
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeSnippet from '@site/src/components/CodeSnippet';
|
||||
|
||||
{/* Import raw source files */}
|
||||
import mainMethodsPy from '!!raw-loader!@site/examples/api/main-methods.py';
|
||||
import mainMethodsMjs from '!!raw-loader!@site/examples/api/main-methods.mjs';
|
||||
|
||||
:::tip Prerequisites
|
||||
Make sure you've [installed Hindsight](../installation) and completed the [Quick Start](./quickstart).
|
||||
:::
|
||||
|
||||
## Retain: Store Information
|
||||
|
||||
Store conversations, documents, and facts into a memory bank.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={mainMethodsPy} section="main-retain" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={mainMethodsMjs} section="main-retain" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Store a single fact
|
||||
hindsight retain my-bank "Alice joined Google in March 2024 as a Senior ML Engineer"
|
||||
|
||||
# Store from a file
|
||||
hindsight retain my-bank --file conversation.txt --context "Daily standup"
|
||||
|
||||
# Store multiple files
|
||||
hindsight retain my-bank --files docs/*.md
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
**What happens:** Content is processed by an LLM to extract rich facts, identify entities, and build connections in a knowledge graph.
|
||||
|
||||
**See:** [Retain Details](./retain) for advanced options and parameters.
|
||||
|
||||
---
|
||||
|
||||
## Recall: Search Memories
|
||||
|
||||
Search for relevant memories using multi-strategy retrieval.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={mainMethodsPy} section="main-recall" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={mainMethodsMjs} section="main-recall" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Basic search
|
||||
hindsight recall my-bank "What does Alice do at Google?"
|
||||
|
||||
# Search with options
|
||||
hindsight recall my-bank "What happened last spring?" \
|
||||
--budget high \
|
||||
--max-tokens 8192 \
|
||||
--fact-type world
|
||||
|
||||
# Verbose output (shows weights and sources)
|
||||
hindsight recall my-bank "Tell me about Alice" -v
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
**What happens:** Four search strategies (semantic, keyword, graph, temporal) run in parallel, results are fused and reranked.
|
||||
|
||||
**See:** [Recall Details](./recall) for tuning quality vs latency.
|
||||
|
||||
---
|
||||
|
||||
## Reflect: Reason with Disposition
|
||||
|
||||
Generate disposition-aware responses that form opinions based on evidence.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={mainMethodsPy} section="main-reflect" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={mainMethodsMjs} section="main-reflect" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
# Basic reflect
|
||||
hindsight reflect my-bank "Should we adopt TypeScript for our backend?"
|
||||
|
||||
# Verbose output (shows sources and opinions)
|
||||
hindsight reflect my-bank "What are Alice's strengths for the team lead role?" -v
|
||||
|
||||
# With higher reasoning budget
|
||||
hindsight reflect my-bank "Analyze our tech stack" --budget high
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
**What happens:** Memories are recalled, bank disposition is loaded, LLM reasons through evidence, new opinions are formed and stored.
|
||||
|
||||
**See:** [Reflect Details](./reflect) for disposition configuration.
|
||||
|
||||
---
|
||||
|
||||
## Comparison
|
||||
|
||||
| Feature | Retain | Recall | Reflect |
|
||||
|---------|--------|--------|---------|
|
||||
| **Purpose** | Store information | Find information | Reason about information |
|
||||
| **Input** | Raw text/documents | Search query | Question/prompt |
|
||||
| **Output** | Memory IDs | Ranked facts | Reasoned response + opinions |
|
||||
| **Uses LLM** | Yes (extraction) | No | Yes (generation) |
|
||||
| **Forms opinions** | No | No | Yes |
|
||||
| **Disposition** | No | No | Yes |
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [**Retain**](./retain) — Advanced options for storing memories
|
||||
- [**Recall**](./recall) — Tuning search quality and performance
|
||||
- [**Reflect**](./reflect) — Configuring disposition and opinions
|
||||
- [**Memory Banks**](./memory-banks) — Managing memory bank disposition
|
||||
+9
-54
@@ -8,6 +8,11 @@ Memory banks are isolated containers that store all memory-related data for a sp
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeSnippet from '@site/src/components/CodeSnippet';
|
||||
|
||||
{/* Import raw source files */}
|
||||
import memoryBanksPy from '!!raw-loader!@site/examples/api/memory-banks.py';
|
||||
import memoryBanksMjs from '!!raw-loader!@site/examples/api/memory-banks.mjs';
|
||||
|
||||
## What is a Memory Bank?
|
||||
|
||||
@@ -30,43 +35,10 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
from hindsight_client import Hindsight
|
||||
|
||||
client = Hindsight(base_url="http://localhost:8888")
|
||||
|
||||
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
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
<CodeSnippet code={memoryBanksPy} section="create-bank" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
import { HindsightClient } from '@vectorize-io/hindsight-client';
|
||||
|
||||
const client = new HindsightClient({ baseUrl: 'http://localhost:8888' });
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
<CodeSnippet code={memoryBanksMjs} section="create-bank" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
@@ -98,27 +70,10 @@ The background is a first-person narrative providing context for opinion formati
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
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."""
|
||||
)
|
||||
```
|
||||
|
||||
<CodeSnippet code={memoryBanksPy} section="bank-background" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
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.`
|
||||
});
|
||||
```
|
||||
|
||||
<CodeSnippet code={memoryBanksMjs} section="bank-background" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
+25
-71
@@ -8,6 +8,11 @@ How memory banks form, store, and evolve beliefs.
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeSnippet from '@site/src/components/CodeSnippet';
|
||||
|
||||
{/* Import raw source files */}
|
||||
import opinionsPy from '!!raw-loader!@site/examples/api/opinions.py';
|
||||
import opinionsMjs from '!!raw-loader!@site/examples/api/opinions.mjs';
|
||||
|
||||
:::tip Prerequisites
|
||||
Make sure you've completed the [Quick Start](./quickstart) to install the client and start the server.
|
||||
@@ -41,20 +46,10 @@ graph LR
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# Ask a question that might form an opinion
|
||||
answer = client.reflect(
|
||||
bank_id="my-bank",
|
||||
query="What do you think about functional programming?"
|
||||
)
|
||||
|
||||
# Check if new opinions were formed
|
||||
for opinion in answer.get("new_opinions", []):
|
||||
print(f"New opinion: {opinion['text']}")
|
||||
print(f"Confidence: {opinion['confidence']}")
|
||||
```
|
||||
|
||||
<CodeSnippet code={opinionsPy} section="opinion-form" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={opinionsMjs} section="opinion-form" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -62,19 +57,10 @@ for opinion in answer.get("new_opinions", []):
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# Search only opinions
|
||||
opinions = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="programming languages",
|
||||
types=["opinion"]
|
||||
)
|
||||
|
||||
for op in opinions:
|
||||
print(f"{op['text']} (confidence: {op['confidence_score']:.2f})")
|
||||
```
|
||||
|
||||
<CodeSnippet code={opinionsPy} section="opinion-search" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={opinionsMjs} section="opinion-search" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
@@ -113,39 +99,10 @@ Different dispositions form different opinions from the same facts:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# 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
|
||||
q = "Should we rewrite our C++ codebase in Rust?"
|
||||
|
||||
answer1 = client.reflect(bank_id="open-minded", query=q)
|
||||
# Likely: "Yes, Rust's safety benefits outweigh migration costs"
|
||||
|
||||
answer2 = client.reflect(bank_id="conservative", query=q)
|
||||
# Likely: "No, C++'s ecosystem and our team's expertise make it the safer choice"
|
||||
```
|
||||
|
||||
<CodeSnippet code={opinionsPy} section="opinion-disposition" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={opinionsMjs} section="opinion-disposition" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -153,17 +110,14 @@ answer2 = client.reflect(bank_id="conservative", query=q)
|
||||
|
||||
When `reflect` uses opinions, they appear in `based_on`:
|
||||
|
||||
```python
|
||||
answer = client.reflect(bank_id="my-bank", query="What language should I learn?")
|
||||
|
||||
print("World facts used:")
|
||||
for f in answer.based_on.get("world", []):
|
||||
print(f" {f['text']}")
|
||||
|
||||
print("\nOpinions used:")
|
||||
for o in answer.based_on.get("opinion", []):
|
||||
print(f" {o['text']} (confidence: {o['confidence_score']})")
|
||||
```
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={opinionsPy} section="opinion-in-reflect" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={opinionsMjs} section="opinion-in-reflect" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Confidence Thresholds
|
||||
|
||||
+9
-38
@@ -8,6 +8,12 @@ Get up and running with Hindsight in 60 seconds.
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeSnippet from '@site/src/components/CodeSnippet';
|
||||
|
||||
{/* Import raw source files */}
|
||||
import quickstartPy from '!!raw-loader!@site/examples/api/quickstart.py';
|
||||
import quickstartMjs from '!!raw-loader!@site/examples/api/quickstart.mjs';
|
||||
import quickstartSh from '!!raw-loader!@site/examples/api/quickstart.sh';
|
||||
|
||||
## Start the API Server
|
||||
|
||||
@@ -59,20 +65,7 @@ See [LLM Providers](/developer/models#llm) for more details.
|
||||
pip install hindsight-client
|
||||
```
|
||||
|
||||
```python
|
||||
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")
|
||||
```
|
||||
<CodeSnippet code={quickstartPy} section="quickstart-full" language="python" />
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
@@ -81,20 +74,7 @@ client.reflect(bank_id="my-bank", query="Tell me about Alice")
|
||||
npm install @vectorize-io/hindsight-client
|
||||
```
|
||||
|
||||
```javascript
|
||||
const { HindsightClient } = require('@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');
|
||||
```
|
||||
<CodeSnippet code={quickstartMjs} section="quickstart-full" language="javascript" />
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
@@ -103,16 +83,7 @@ await client.reflect('my-bank', 'Tell me about Alice');
|
||||
curl -fsSL https://hindsight.vectorize.io/get-cli | bash
|
||||
```
|
||||
|
||||
```bash
|
||||
# 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"
|
||||
```
|
||||
<CodeSnippet code={quickstartSh} section="quickstart-full" language="bash" />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
+27
-140
@@ -8,6 +8,12 @@ Retrieve memories using multi-strategy recall.
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeSnippet from '@site/src/components/CodeSnippet';
|
||||
|
||||
{/* Import raw source files */}
|
||||
import recallPy from '!!raw-loader!@site/examples/api/recall.py';
|
||||
import recallMjs from '!!raw-loader!@site/examples/api/recall.mjs';
|
||||
import recallSh from '!!raw-loader!@site/examples/api/recall.sh';
|
||||
|
||||
:::info How Recall Works
|
||||
Learn about the four retrieval strategies (semantic, keyword, graph, temporal) and RRF fusion in the [Recall Architecture](/developer/retrieval) guide.
|
||||
@@ -21,38 +27,13 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
from hindsight_client import Hindsight
|
||||
|
||||
client = Hindsight(base_url="http://localhost:8888")
|
||||
|
||||
response = client.recall(bank_id="my-bank", query="What does Alice do?")
|
||||
for r in response.results:
|
||||
print(f"{r.text} (score: {r.weight:.2f})")
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallPy} section="recall-basic" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
import { HindsightClient } from '@vectorize-io/hindsight-client';
|
||||
|
||||
const client = new HindsightClient({ baseUrl: 'http://localhost:8888' });
|
||||
|
||||
const response = await client.recall('my-bank', 'What does Alice do?');
|
||||
for (const r of response.results) {
|
||||
console.log(`${r.text} (score: ${r.weight})`);
|
||||
}
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallMjs} section="recall-basic" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
hindsight recall my-bank "What does Alice do?"
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallSh} section="recall-basic" language="bash" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -70,46 +51,10 @@ hindsight recall my-bank "What does Alice do?"
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
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} (score: {r.weight:.2f})")
|
||||
|
||||
# Access entity observations (if include_entities=True)
|
||||
if response.entities:
|
||||
for entity in response.entities:
|
||||
print(f"Entity: {entity.name}")
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallPy} section="recall-with-options" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
const response = await client.recall('my-bank', 'What does Alice do?', {
|
||||
types: ['world', 'experience'],
|
||||
budget: 'high',
|
||||
maxTokens: 8000,
|
||||
trace: true
|
||||
});
|
||||
|
||||
// Access results
|
||||
for (const r of response.results) {
|
||||
console.log(`${r.text} (score: ${r.weight})`);
|
||||
}
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallMjs} section="recall-with-options" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -119,45 +64,12 @@ Recall specific memory types:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# Only world facts (objective information)
|
||||
world_facts = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="Where does Alice work?",
|
||||
types=["world"]
|
||||
)
|
||||
|
||||
# Only experience (conversations and events)
|
||||
experience = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="What have I recommended?",
|
||||
types=["experience"]
|
||||
)
|
||||
|
||||
# Only opinions (formed beliefs)
|
||||
opinions = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="What do I think about Python?",
|
||||
types=["opinion"]
|
||||
)
|
||||
|
||||
# World facts and experience (exclude opinions)
|
||||
facts = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="What happened?",
|
||||
types=["world", "experience"]
|
||||
)
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallPy} section="recall-world-only" language="python" />
|
||||
<CodeSnippet code={recallPy} section="recall-experience-only" language="python" />
|
||||
<CodeSnippet code={recallPy} section="recall-opinions-only" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
hindsight recall my-bank "Python" --fact-type opinion
|
||||
hindsight recall my-bank "Alice" --fact-type world,experience
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallSh} section="recall-fact-type" language="bash" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -174,13 +86,11 @@ Hindsight is built for AI agents, not humans. Traditional retrieval systems retu
|
||||
|
||||
The `max_tokens` parameter lets you control how much of your agent's context budget to spend on memories:
|
||||
|
||||
```python
|
||||
# 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)
|
||||
```
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={recallPy} section="recall-token-budget" language="python" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This design means you never have to guess whether 10 results or 50 results will fit your context. Just specify the token budget and Hindsight returns as many relevant memories as will fit.
|
||||
|
||||
@@ -193,18 +103,11 @@ Beyond the core memory results, you can optionally retrieve additional context
|
||||
| **Chunks** | `include_chunks`, `max_chunk_tokens` | Raw text chunks that generated the memories |
|
||||
| **Entity Observations** | `include_entities`, `max_entity_tokens` | Related observations about entities mentioned in results |
|
||||
|
||||
```python
|
||||
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 []
|
||||
```
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={recallPy} section="recall-include-entities" language="python" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This gives your agent richer context while maintaining precise control over total token consumption.
|
||||
|
||||
@@ -218,25 +121,9 @@ The `budget` parameter controls graph traversal depth:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# 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")
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallPy} section="recall-budget-levels" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
// Quick lookup
|
||||
const results = await client.recall('my-bank', "Alice's email", { budget: 'low' });
|
||||
|
||||
// Deep exploration
|
||||
const deep = await client.recall('my-bank', 'How are Alice and Bob connected?', { budget: 'high' });
|
||||
```
|
||||
|
||||
<CodeSnippet code={recallMjs} section="recall-budget-levels" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
+17
-117
@@ -16,6 +16,12 @@ The response includes the generated answer along with the facts that were used,
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeSnippet from '@site/src/components/CodeSnippet';
|
||||
|
||||
{/* Import raw source files */}
|
||||
import reflectPy from '!!raw-loader!@site/examples/api/reflect.py';
|
||||
import reflectMjs from '!!raw-loader!@site/examples/api/reflect.mjs';
|
||||
import reflectSh from '!!raw-loader!@site/examples/api/reflect.sh';
|
||||
|
||||
:::info How Reflect Works
|
||||
Learn about disposition-driven reasoning and opinion formation in the [Reflect Architecture](/developer/reflect) guide.
|
||||
@@ -29,33 +35,13 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
from hindsight_client import Hindsight
|
||||
|
||||
client = Hindsight(base_url="http://localhost:8888")
|
||||
|
||||
client.reflect(bank_id="my-bank", query="What should I know about Alice?")
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectPy} section="reflect-basic" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
import { HindsightClient } from '@vectorize-io/hindsight-client';
|
||||
|
||||
const client = new HindsightClient({ baseUrl: 'http://localhost:8888' });
|
||||
|
||||
await client.reflect('my-bank', 'What should I know about Alice?');
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectMjs} section="reflect-basic" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
hindsight memory think my-bank "What should I know about Alice?"
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectSh} section="reflect-basic" language="bash" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -69,26 +55,10 @@ hindsight memory think my-bank "What should I know about Alice?"
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
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"
|
||||
)
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectPy} section="reflect-with-params" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
const response = await client.reflect('my-bank', 'What do you think about remote work?', {
|
||||
budget: 'mid',
|
||||
context: "We're considering a hybrid work policy"
|
||||
});
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectMjs} section="reflect-with-params" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -103,26 +73,10 @@ The `context` parameter steers how the reflection is performed without impacting
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# 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"
|
||||
)
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectPy} section="reflect-with-context" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
// Context helps the LLM understand the current situation
|
||||
const response = await client.reflect('my-bank', 'What do you think about the proposal?', {
|
||||
context: "We're in a budget review meeting discussing Q4 spending"
|
||||
});
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectMjs} section="reflect-with-context" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -149,45 +103,10 @@ The bank's disposition affects reflect responses:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# 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
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectPy} section="reflect-disposition" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
// 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 response = await client.reflect('cautious-advisor', 'Should I invest in crypto?');
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectMjs} section="reflect-disposition" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -197,29 +116,10 @@ The `based_on` field shows which memories informed the response:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
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}")
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectPy} section="reflect-sources" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
const response = await client.reflect('my-bank', 'Tell me about Alice');
|
||||
|
||||
console.log('Response:', response.text);
|
||||
console.log('\nBased on:');
|
||||
for (const fact of response.based_on || []) {
|
||||
console.log(` - [${fact.type}] ${fact.text}`);
|
||||
}
|
||||
```
|
||||
|
||||
<CodeSnippet code={reflectMjs} section="reflect-sources" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
---
|
||||
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>
|
||||
+19
-105
@@ -10,6 +10,12 @@ When you **retain** content, Hindsight doesn't just store the raw text—it inte
|
||||
|
||||
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';
|
||||
|
||||
:::info How Retain Works
|
||||
Learn about fact extraction, entity resolution, and graph construction in the [Retain Architecture](/developer/retain) guide.
|
||||
@@ -23,36 +29,13 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
from hindsight_client import Hindsight
|
||||
|
||||
client = Hindsight(base_url="http://localhost:8888")
|
||||
|
||||
client.retain(
|
||||
bank_id="my-bank",
|
||||
content="Alice works at Google as a software engineer"
|
||||
)
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainPy} section="retain-basic" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
import { HindsightClient } from '@vectorize-io/hindsight-client';
|
||||
|
||||
const client = new HindsightClient({ baseUrl: 'http://localhost:8888' });
|
||||
|
||||
await client.retain('my-bank', 'Alice works at Google as a software engineer');
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainMjs} section="retain-basic" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
hindsight memory put my-bank "Alice works at Google as a software engineer"
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainSh} section="retain-basic" language="bash" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -71,35 +54,13 @@ Always provide context and event dates for optimal memory extraction:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
client.retain(
|
||||
bank_id="my-bank",
|
||||
content="Alice got promoted to senior engineer",
|
||||
context="career update",
|
||||
timestamp="2024-03-15T10:00:00Z"
|
||||
)
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainPy} section="retain-with-context" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
await client.retain('my-bank', 'Alice got promoted to senior engineer', {
|
||||
context: 'career update',
|
||||
timestamp: '2024-03-15T10:00:00Z'
|
||||
});
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainMjs} section="retain-with-context" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
|
||||
```bash
|
||||
hindsight memory put my-bank "Alice got promoted" \
|
||||
--context "career update" \
|
||||
--event-date "2024-03-15"
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainSh} section="retain-with-context" language="bash" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -111,30 +72,10 @@ Store multiple items in a single request. **Batch ingestion is the recommended a
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
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"
|
||||
)
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainPy} section="retain-batch" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
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' });
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainMjs} section="retain-batch" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -147,13 +88,10 @@ The `document_id` groups related memories for later management.
|
||||
|
||||
```bash
|
||||
# Single file
|
||||
hindsight memory put-files my-bank document.txt
|
||||
hindsight memory retain-files my-bank document.txt
|
||||
|
||||
# Multiple files
|
||||
hindsight memory put-files my-bank doc1.txt doc2.md notes.txt
|
||||
|
||||
# With document ID
|
||||
hindsight memory put-files my-bank report.pdf --document-id "q4-report"
|
||||
# Directory (recursive by default)
|
||||
hindsight memory retain-files my-bank ./documents/
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -166,33 +104,9 @@ For large batches, use async ingestion to avoid blocking:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
# Start async ingestion (returns immediately)
|
||||
result = client.retain_batch(
|
||||
bank_id="my-bank",
|
||||
items=[...large batch...],
|
||||
document_id="large-doc",
|
||||
retain_async=True
|
||||
)
|
||||
|
||||
# Check if it was processed asynchronously
|
||||
print(result.var_async) # True
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainPy} section="retain-async" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
|
||||
```typescript
|
||||
// Start async ingestion (returns immediately)
|
||||
const result = await client.retainBatch('my-bank', largeItems, {
|
||||
documentId: 'large-doc',
|
||||
async: true
|
||||
});
|
||||
|
||||
console.log(result.async); // true
|
||||
```
|
||||
|
||||
<CodeSnippet code={retainMjs} section="retain-async" language="javascript" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -102,10 +102,10 @@ hindsight memory reflect <bank_id> "Summarize my week" --budget high
|
||||
hindsight bank list
|
||||
```
|
||||
|
||||
### View Profile
|
||||
### View Disposition
|
||||
|
||||
```bash
|
||||
hindsight bank profile <bank_id>
|
||||
hindsight bank disposition <bank_id>
|
||||
```
|
||||
|
||||
### View Statistics
|
||||
@@ -241,6 +241,6 @@ hindsight memory recall demo "Who works with Alice?"
|
||||
# Generate a response
|
||||
hindsight memory reflect demo "What do you know about the team?"
|
||||
|
||||
# Check bank profile
|
||||
hindsight bank profile demo
|
||||
# Check bank disposition
|
||||
hindsight bank disposition demo
|
||||
```
|
||||
|
||||
@@ -15,12 +15,14 @@ DOC_ID="test-document-001"
|
||||
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 works at Google as a software engineer" --doc-id "$DOC_ID"
|
||||
hindsight memory retain "$BANK_ID" "Bob is a data scientist who collaborates with Alice" --doc-id "$DOC_ID"
|
||||
hindsight memory retain "$BANK_ID" "Alice and Bob work on machine learning projects"
|
||||
# Create document for delete test early so it has time to index
|
||||
hindsight memory retain "$BANK_ID" "Carol is a project manager who coordinates the engineering team" --doc-id "temp-doc-to-delete"
|
||||
|
||||
# Wait a moment for processing
|
||||
sleep 2
|
||||
# Wait for memories to be indexed (LLM processing takes time)
|
||||
sleep 5
|
||||
|
||||
# =============================================================================
|
||||
# Configuration (cli.md - Configuration section)
|
||||
@@ -96,9 +98,9 @@ hindsight bank list
|
||||
# [/docs:cli-bank-list]
|
||||
|
||||
|
||||
# [docs:cli-bank-profile]
|
||||
hindsight bank profile $BANK_ID
|
||||
# [/docs:cli-bank-profile]
|
||||
# [docs:cli-bank-disposition]
|
||||
hindsight bank disposition $BANK_ID
|
||||
# [/docs:cli-bank-disposition]
|
||||
|
||||
|
||||
# [docs:cli-bank-stats]
|
||||
@@ -136,9 +138,6 @@ hindsight document get $BANK_ID $DOC_ID
|
||||
|
||||
|
||||
# [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]
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Main Methods overview examples for Hindsight (Node.js)
|
||||
* Run: node examples/api/main-methods.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 - Retain Section
|
||||
// =============================================================================
|
||||
|
||||
// [docs:main-retain]
|
||||
// Store a single fact
|
||||
await client.retain('my-bank', 'Alice joined Google in March 2024 as a Senior ML Engineer');
|
||||
|
||||
// Store a conversation
|
||||
const 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.
|
||||
`;
|
||||
|
||||
await client.retain('my-bank', conversation, {
|
||||
context: 'Daily standup conversation'
|
||||
});
|
||||
|
||||
// Batch retain multiple items
|
||||
await client.retainBatch('my-bank', [
|
||||
{ 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
|
||||
const results = await client.recall('my-bank', 'What does Alice do at Google?');
|
||||
|
||||
for (const result of results.results) {
|
||||
console.log(`- ${result.text}`);
|
||||
}
|
||||
|
||||
// Search with options
|
||||
const filteredResults = await client.recall('my-bank', 'What happened last spring?', {
|
||||
budget: 'high',
|
||||
maxTokens: 8192,
|
||||
types: ['world']
|
||||
});
|
||||
|
||||
// Include entity information
|
||||
const entityResults = await client.recall('my-bank', 'Tell me about Alice', {
|
||||
includeEntities: true,
|
||||
maxEntityTokens: 500
|
||||
});
|
||||
|
||||
// Check entity details
|
||||
for (const [entityId, entity] of Object.entries(entityResults.entities || {})) {
|
||||
console.log(`Entity: ${entity.canonical_name}`);
|
||||
console.log(`Observations: ${entity.observations}`);
|
||||
}
|
||||
// [/docs:main-recall]
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Doc Examples - Reflect Section
|
||||
// =============================================================================
|
||||
|
||||
// [docs:main-reflect]
|
||||
// Basic reflect
|
||||
const response = await client.reflect('my-bank', 'Should we adopt TypeScript for our backend?');
|
||||
|
||||
console.log(response.text);
|
||||
console.log('\nBased on:', (response.based_on || []).length, 'facts');
|
||||
|
||||
// Reflect with options
|
||||
const detailedResponse = await client.reflect('my-bank', "What are Alice's strengths for the team lead role?", {
|
||||
budget: 'high'
|
||||
});
|
||||
|
||||
// See which facts influenced the response
|
||||
for (const fact of detailedResponse.based_on || []) {
|
||||
console.log(`- ${fact.text}`);
|
||||
}
|
||||
// [/docs:main-reflect]
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Doc Examples - List Memories Section
|
||||
// =============================================================================
|
||||
|
||||
// [docs:main-list-memories]
|
||||
// List all memories in a bank
|
||||
const memories = await client.listMemories('my-bank', {
|
||||
limit: 10
|
||||
});
|
||||
|
||||
for (const memory of memories.items) {
|
||||
console.log(`- [${memory.fact_type}] ${memory.text}`);
|
||||
}
|
||||
|
||||
// Filter by type
|
||||
const worldFacts = await client.listMemories('my-bank', {
|
||||
type: 'world',
|
||||
limit: 5
|
||||
});
|
||||
|
||||
// Search within memories
|
||||
const searchResults = await client.listMemories('my-bank', {
|
||||
q: 'Alice',
|
||||
limit: 10
|
||||
});
|
||||
// [/docs:main-list-memories]
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Cleanup (not shown in docs)
|
||||
// =============================================================================
|
||||
await fetch(`${HINDSIGHT_URL}/v1/default/banks/my-bank`, { method: 'DELETE' });
|
||||
|
||||
console.log('main-methods.mjs: All examples passed');
|
||||
@@ -84,8 +84,8 @@ results = client.recall(
|
||||
)
|
||||
|
||||
# Check entity details
|
||||
for entity in results.entities or []:
|
||||
print(f"Entity: {entity.name}")
|
||||
for entity_id, entity in (results.entities or {}).items():
|
||||
print(f"Entity: {entity.canonical_name}")
|
||||
print(f"Observations: {entity.observations}")
|
||||
# [/docs:main-recall]
|
||||
|
||||
@@ -117,6 +117,61 @@ for fact in response.based_on or []:
|
||||
# [/docs:main-reflect]
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Doc Examples - List Memories Section
|
||||
# =============================================================================
|
||||
|
||||
# [docs:main-list-memories]
|
||||
# List all memories in a bank
|
||||
memories = client.list_memories(
|
||||
bank_id="my-bank",
|
||||
limit=10
|
||||
)
|
||||
|
||||
for memory in memories.items:
|
||||
print(f"- [{memory['fact_type']}] {memory['text']}")
|
||||
|
||||
# Filter by type
|
||||
world_facts = client.list_memories(
|
||||
bank_id="my-bank",
|
||||
type="world",
|
||||
limit=5
|
||||
)
|
||||
|
||||
# Search within memories
|
||||
search_results = client.list_memories(
|
||||
bank_id="my-bank",
|
||||
search_query="Alice",
|
||||
limit=10
|
||||
)
|
||||
# [/docs:main-list-memories]
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Doc Examples - Async Methods Section
|
||||
# =============================================================================
|
||||
|
||||
# [docs:main-async]
|
||||
import asyncio
|
||||
|
||||
async def async_example():
|
||||
# Create a fresh client for async operations
|
||||
async_client = Hindsight(base_url=HINDSIGHT_URL)
|
||||
|
||||
# All sync methods have async versions prefixed with 'a'
|
||||
await async_client.aretain(bank_id="my-bank", content="Async memory")
|
||||
|
||||
results = await async_client.arecall(bank_id="my-bank", query="Async")
|
||||
for r in results:
|
||||
print(f"- {r.text}")
|
||||
|
||||
response = await async_client.areflect(bank_id="my-bank", query="What was stored?")
|
||||
print(response.text)
|
||||
|
||||
asyncio.run(async_example())
|
||||
# [/docs:main-async]
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Cleanup (not shown in docs)
|
||||
# =============================================================================
|
||||
|
||||
@@ -31,6 +31,7 @@ await client.createBank('my-bank', {
|
||||
|
||||
// [docs:bank-background]
|
||||
await client.createBank('financial-advisor', {
|
||||
name: '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.`
|
||||
|
||||
@@ -36,6 +36,7 @@ client.create_bank(
|
||||
# [docs:bank-background]
|
||||
client.create_bank(
|
||||
bank_id="financial-advisor",
|
||||
name="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."""
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Opinions API examples for Hindsight (Node.js)
|
||||
* Run: node examples/api/opinions.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 about programming languages
|
||||
await client.retain('my-bank', 'Python is widely used for data science and machine learning');
|
||||
await client.retain('my-bank', 'Functional programming emphasizes immutability and pure functions');
|
||||
await client.retain('my-bank', 'Rust has better memory safety than C++');
|
||||
await client.retain('my-bank', '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
|
||||
const answer = await client.reflect('my-bank', 'What do you think about functional programming?');
|
||||
|
||||
console.log(answer.text);
|
||||
// [/docs:opinion-form]
|
||||
|
||||
|
||||
// [docs:opinion-search]
|
||||
// Search for facts about a topic
|
||||
const results = await client.recall('my-bank', 'programming languages');
|
||||
|
||||
for (const result of results.results) {
|
||||
console.log(`- ${result.text}`);
|
||||
}
|
||||
// [/docs:opinion-search]
|
||||
|
||||
|
||||
// [docs:opinion-disposition]
|
||||
// Create two memory banks with different dispositions
|
||||
await client.createBank('open-minded', {
|
||||
name: 'Open Minded',
|
||||
disposition: { skepticism: 2, literalism: 2, empathy: 4 }
|
||||
});
|
||||
|
||||
await client.createBank('conservative', {
|
||||
name: 'Conservative',
|
||||
disposition: { skepticism: 5, literalism: 5, empathy: 2 }
|
||||
});
|
||||
|
||||
// Store the same facts to both
|
||||
const facts = [
|
||||
'Rust has better memory safety than C++',
|
||||
'C++ has a larger ecosystem and more libraries',
|
||||
'Rust compile times are longer than C++'
|
||||
];
|
||||
for (const fact of facts) {
|
||||
await client.retain('open-minded', fact);
|
||||
await client.retain('conservative', fact);
|
||||
}
|
||||
|
||||
// Ask both the same question - different dispositions lead to different responses
|
||||
const q = 'Should we rewrite our C++ codebase in Rust?';
|
||||
|
||||
const answer1 = await client.reflect('open-minded', q);
|
||||
console.log('Open-minded response:', answer1.text.slice(0, 100), '...');
|
||||
|
||||
const answer2 = await client.reflect('conservative', q);
|
||||
console.log('Conservative response:', answer2.text.slice(0, 100), '...');
|
||||
// [/docs:opinion-disposition]
|
||||
|
||||
|
||||
// [docs:opinion-in-reflect]
|
||||
const reflectAnswer = await client.reflect('my-bank', 'What language should I learn?');
|
||||
|
||||
console.log('Response:', reflectAnswer.text);
|
||||
|
||||
// See which facts influenced the response
|
||||
if (reflectAnswer.based_on) {
|
||||
console.log('\nBased on these facts:');
|
||||
for (const fact of reflectAnswer.based_on) {
|
||||
console.log(` - ${fact.text}`);
|
||||
}
|
||||
}
|
||||
// [/docs:opinion-in-reflect]
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Cleanup (not shown in docs)
|
||||
// =============================================================================
|
||||
await fetch(`${HINDSIGHT_URL}/v1/default/banks/my-bank`, { method: 'DELETE' });
|
||||
await fetch(`${HINDSIGHT_URL}/v1/default/banks/open-minded`, { method: 'DELETE' });
|
||||
await fetch(`${HINDSIGHT_URL}/v1/default/banks/conservative`, { method: 'DELETE' });
|
||||
|
||||
console.log('opinions.mjs: All examples passed');
|
||||
@@ -52,11 +52,13 @@ for result in results.results:
|
||||
# Create two memory banks with different dispositions
|
||||
client.create_bank(
|
||||
bank_id="open-minded",
|
||||
name="Open Minded",
|
||||
disposition={"skepticism": 2, "literalism": 2, "empathy": 4}
|
||||
)
|
||||
|
||||
client.create_bank(
|
||||
bank_id="conservative",
|
||||
name="Conservative",
|
||||
disposition={"skepticism": 5, "literalism": 5, "empathy": 2}
|
||||
)
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ const contextResponse = await client.reflect('my-bank', 'What do you think about
|
||||
// [docs:reflect-disposition]
|
||||
// Create a bank with specific disposition
|
||||
await client.createBank('cautious-advisor', {
|
||||
name: 'Cautious Advisor',
|
||||
background: 'I am a risk-aware financial advisor',
|
||||
disposition: {
|
||||
skepticism: 5,
|
||||
|
||||
@@ -53,6 +53,7 @@ response = client.reflect(
|
||||
# Create a bank with specific disposition
|
||||
client.create_bank(
|
||||
bank_id="cautious-advisor",
|
||||
name="Cautious Advisor",
|
||||
background="I am a risk-aware financial advisor",
|
||||
disposition={
|
||||
"skepticism": 5, # Very skeptical of claims
|
||||
|
||||
@@ -1268,14 +1268,28 @@
|
||||
"title": "Bank Id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Name"
|
||||
},
|
||||
"disposition": {
|
||||
"$ref": "#/components/schemas/DispositionTraits"
|
||||
},
|
||||
"background": {
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Background"
|
||||
},
|
||||
"created_at": {
|
||||
@@ -1304,9 +1318,7 @@
|
||||
"type": "object",
|
||||
"required": [
|
||||
"bank_id",
|
||||
"name",
|
||||
"disposition",
|
||||
"background"
|
||||
"disposition"
|
||||
],
|
||||
"title": "BankListItem",
|
||||
"description": "Bank list item with profile summary."
|
||||
@@ -1566,9 +1578,9 @@
|
||||
"title": "DeleteResponse",
|
||||
"description": "Response model for delete operations.",
|
||||
"example": {
|
||||
"success": true,
|
||||
"deleted_count": 10,
|
||||
"message": "Deleted successfully",
|
||||
"deleted_count": 10
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"DispositionTraits": {
|
||||
|
||||
@@ -1268,14 +1268,28 @@
|
||||
"title": "Bank Id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Name"
|
||||
},
|
||||
"disposition": {
|
||||
"$ref": "#/components/schemas/DispositionTraits"
|
||||
},
|
||||
"background": {
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Background"
|
||||
},
|
||||
"created_at": {
|
||||
@@ -1304,9 +1318,7 @@
|
||||
"type": "object",
|
||||
"required": [
|
||||
"bank_id",
|
||||
"name",
|
||||
"disposition",
|
||||
"background"
|
||||
"disposition"
|
||||
],
|
||||
"title": "BankListItem",
|
||||
"description": "Bank list item with profile summary."
|
||||
@@ -1566,9 +1578,9 @@
|
||||
"title": "DeleteResponse",
|
||||
"description": "Response model for delete operations.",
|
||||
"example": {
|
||||
"success": true,
|
||||
"deleted_count": 10,
|
||||
"message": "Deleted successfully",
|
||||
"deleted_count": 10
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"DispositionTraits": {
|
||||
|
||||
+19
-7
@@ -1268,14 +1268,28 @@
|
||||
"title": "Bank Id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Name"
|
||||
},
|
||||
"disposition": {
|
||||
"$ref": "#/components/schemas/DispositionTraits"
|
||||
},
|
||||
"background": {
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Background"
|
||||
},
|
||||
"created_at": {
|
||||
@@ -1304,9 +1318,7 @@
|
||||
"type": "object",
|
||||
"required": [
|
||||
"bank_id",
|
||||
"name",
|
||||
"disposition",
|
||||
"background"
|
||||
"disposition"
|
||||
],
|
||||
"title": "BankListItem",
|
||||
"description": "Bank list item with profile summary."
|
||||
@@ -1566,9 +1578,9 @@
|
||||
"title": "DeleteResponse",
|
||||
"description": "Response model for delete operations.",
|
||||
"example": {
|
||||
"success": true,
|
||||
"deleted_count": 10,
|
||||
"message": "Deleted successfully",
|
||||
"deleted_count": 10
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"DispositionTraits": {
|
||||
|
||||
Reference in New Issue
Block a user