Compare commits

...
Author SHA1 Message Date
Nicolò Boschi d8f2e3a6db fix 2025-12-10 16:00:31 +01:00
Nicolò Boschi ae5da7bcaa fix: make sure openai provider works 2025-12-10 15:52:21 +01:00
Nicolò Boschi 30eed1fbed fix: make sure openai provider works 2025-12-10 15:52:17 +01:00
94 changed files with 4293 additions and 8396 deletions
+1 -2
View File
@@ -40,9 +40,8 @@ WORKDIR /app/api
# Sync dependencies (will create lock file if needed)
RUN uv sync
# Copy source code and alembic migrations
# Copy source code (alembic migrations are inside hindsight_api/)
COPY hindsight-api/hindsight_api ./hindsight_api
COPY hindsight-api/alembic ./alembic
# =============================================================================
# Stage: SDK Builder (needed for Control Plane)
+1 -1
View File
@@ -26,7 +26,7 @@ PIDS=()
# Start API if enabled
if [ "$ENABLE_API" = "true" ]; then
cd /app/api
python -m hindsight_api.web.server 2>&1 | sed -u 's/^/[api] /' &
hindsight-api 2>&1 | sed -u 's/^/[api] /' &
API_PID=$!
PIDS+=($API_PID)
+3
View File
@@ -19,9 +19,12 @@ from .engine.search.tracer import SearchTracer
from .engine.embeddings import Embeddings, LocalSTEmbeddings, RemoteTEIEmbeddings
from .engine.cross_encoder import CrossEncoderModel, LocalSTCrossEncoder, RemoteTEICrossEncoder
from .engine.llm_wrapper import LLMConfig
from .config import HindsightConfig, get_config
__all__ = [
"MemoryEngine",
"HindsightConfig",
"get_config",
"SearchTrace",
"SearchTracer",
"QueryInfo",
+41 -64
View File
@@ -729,9 +729,11 @@ def create_app(memory: MemoryEngine, initialize_memory: bool = True) -> FastAPI:
await memory.close()
logging.info("Memory system closed")
from hindsight_api import __version__
app = FastAPI(
title="Hindsight HTTP API",
version="1.0.0",
version=__version__,
description="HTTP API for Hindsight",
contact={
"name": "Memory System",
@@ -857,16 +859,12 @@ def _register_routes(app: FastAPI):
"/v1/default/banks/{bank_id}/memories/recall",
response_model=RecallResponse,
summary="Recall memory",
description="""
Recall memory using semantic similarity and spreading activation.
The type parameter is optional and must be one of:
- 'world': General knowledge about people, places, events, and things that happen
- 'experience': Memories about experience, conversations, actions taken, and tasks performed
- 'opinion': The bank's formed beliefs, perspectives, and viewpoints
Set include_entities=true to get entity observations alongside recall results.
""",
description="Recall memory using semantic similarity and spreading activation.\n\n"
"The type parameter is optional and must be one of:\n"
"- `world`: General knowledge about people, places, events, and things that happen\n"
"- `experience`: Memories about experience, conversations, actions taken, and tasks performed\n"
"- `opinion`: The bank's formed beliefs, perspectives, and viewpoints\n\n"
"Set `include_entities=true` to get entity observations alongside recall results.",
operation_id="recall_memories",
tags=["Memory"]
)
@@ -975,17 +973,14 @@ def _register_routes(app: FastAPI):
"/v1/default/banks/{bank_id}/reflect",
response_model=ReflectResponse,
summary="Reflect and generate answer",
description="""
Reflect and formulate an answer using bank identity, world facts, and opinions.
This endpoint:
1. Retrieves experience (conversations and events)
2. Retrieves world facts relevant to the query
3. Retrieves existing opinions (bank's perspectives)
4. Uses LLM to formulate a contextual answer
5. Extracts and stores any new opinions formed
6. Returns plain text answer, the facts used, and new opinions
""",
description="Reflect and formulate an answer using bank identity, world facts, and opinions.\n\n"
"This endpoint:\n"
"1. Retrieves experience (conversations and events)\n"
"2. Retrieves world facts relevant to the query\n"
"3. Retrieves existing opinions (bank's perspectives)\n"
"4. Uses LLM to formulate a contextual answer\n"
"5. Extracts and stores any new opinions formed\n"
"6. Returns plain text answer, the facts used, and new opinions",
operation_id="reflect",
tags=["Memory"]
)
@@ -1401,16 +1396,12 @@ def _register_routes(app: FastAPI):
@app.delete(
"/v1/default/banks/{bank_id}/documents/{document_id}",
summary="Delete a document",
description="""
Delete a document and all its associated memory units and links.
This will cascade delete:
- The document itself
- All memory units extracted from this document
- All links (temporal, semantic, entity) associated with those memory units
This operation cannot be undone.
""",
description="Delete a document and all its associated memory units and links.\n\n"
"This will cascade delete:\n"
"- The document itself\n"
"- All memory units extracted from this document\n"
"- All links (temporal, semantic, entity) associated with those memory units\n\n"
"This operation cannot be undone.",
operation_id="delete_document",
tags=["Documents"]
)
@@ -1709,38 +1700,24 @@ This operation cannot be undone.
"/v1/default/banks/{bank_id}/memories",
response_model=RetainResponse,
summary="Retain memories",
description="""
Retain memory items with automatic fact extraction.
This is the main endpoint for storing memories. It supports both synchronous and asynchronous processing
via the async parameter.
Features:
- Efficient batch processing
- Automatic fact extraction from natural language
- Entity recognition and linking
- Document tracking with automatic upsert (when document_id is provided on items)
- Temporal and semantic linking
- Optional asynchronous processing
The system automatically:
1. Extracts semantic facts from the content
2. Generates embeddings
3. Deduplicates similar facts
4. Creates temporal, semantic, and entity links
5. Tracks document metadata
When async=true:
- Returns immediately after queuing the task
- Processing happens in the background
- Use the operations endpoint to monitor progress
When async=false (default):
- Waits for processing to complete
- Returns after all memories are stored
Note: If a memory item has a document_id that already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). Items with the same document_id are grouped together for efficient processing.
""",
description="Retain memory items with automatic fact extraction.\n\n"
"This is the main endpoint for storing memories. It supports both synchronous and asynchronous processing via the `async` parameter.\n\n"
"**Features:**\n"
"- Efficient batch processing\n"
"- Automatic fact extraction from natural language\n"
"- Entity recognition and linking\n"
"- Document tracking with automatic upsert (when document_id is provided)\n"
"- Temporal and semantic linking\n"
"- Optional asynchronous processing\n\n"
"**The system automatically:**\n"
"1. Extracts semantic facts from the content\n"
"2. Generates embeddings\n"
"3. Deduplicates similar facts\n"
"4. Creates temporal, semantic, and entity links\n"
"5. Tracks document metadata\n\n"
"**When `async=true`:** Returns immediately after queuing. Use the operations endpoint to monitor progress.\n\n"
"**When `async=false` (default):** Waits for processing to complete.\n\n"
"**Note:** If a memory item has a `document_id` that already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior).",
operation_id="retain_memories",
tags=["Memory"]
)
-127
View File
@@ -1,127 +0,0 @@
"""
Command-line interface for Hindsight API.
Run the server with:
hindsight-api
Stop with Ctrl+C.
"""
import argparse
import asyncio
import atexit
import os
import signal
import sys
from typing import Optional
import uvicorn
from . import MemoryEngine
from .api import create_app
# Disable tokenizers parallelism to avoid warnings
os.environ["TOKENIZERS_PARALLELISM"] = "false"
# Global reference for cleanup
_memory: Optional[MemoryEngine] = None
def _cleanup():
"""Synchronous cleanup function to stop resources on exit."""
global _memory
if _memory is not None and _memory._pg0 is not None:
try:
loop = asyncio.new_event_loop()
loop.run_until_complete(_memory._pg0.stop())
loop.close()
print("\npg0 stopped.")
except Exception as e:
print(f"\nError stopping pg0: {e}")
def _signal_handler(signum, frame):
"""Handle SIGINT/SIGTERM to ensure cleanup."""
print(f"\nReceived signal {signum}, shutting down...")
_cleanup()
sys.exit(0)
def main():
"""Main entry point for the CLI."""
global _memory
parser = argparse.ArgumentParser(
prog="hindsight-api",
description="Hindsight API Server",
)
parser.add_argument(
"--host", default="0.0.0.0",
help="Host to bind to (default: 0.0.0.0)"
)
parser.add_argument(
"--port", type=int, default=8888,
help="Port to bind to (default: 8888)"
)
parser.add_argument(
"--log-level", default="info",
choices=["critical", "error", "warning", "info", "debug", "trace"],
help="Log level (default: info)"
)
parser.add_argument(
"--access-log", action="store_true",
help="Enable access log"
)
args = parser.parse_args()
# Register cleanup handlers
atexit.register(_cleanup)
signal.signal(signal.SIGINT, _signal_handler)
signal.signal(signal.SIGTERM, _signal_handler)
# Get configuration from environment variables
db_url = os.getenv("HINDSIGHT_API_DATABASE_URL", "pg0")
llm_provider = os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq")
llm_api_key = os.getenv("HINDSIGHT_API_LLM_API_KEY", "")
llm_model = os.getenv("HINDSIGHT_API_LLM_MODEL", "openai/gpt-oss-20b")
llm_base_url = os.getenv("HINDSIGHT_API_LLM_BASE_URL") or None
# Create MemoryEngine
_memory = MemoryEngine(
db_url=db_url,
memory_llm_provider=llm_provider,
memory_llm_api_key=llm_api_key,
memory_llm_model=llm_model,
memory_llm_base_url=llm_base_url,
)
# Create FastAPI app
app = create_app(
memory=_memory,
http_api_enabled=True,
mcp_api_enabled=True,
mcp_mount_path="/mcp",
initialize_memory=True,
)
# Prepare uvicorn config
uvicorn_config = {
"app": app,
"host": args.host,
"port": args.port,
"log_level": args.log_level,
"access_log": args.access_log,
}
print(f"\nStarting Hindsight API...")
print(f" URL: http://{args.host}:{args.port}")
print(f" Database: {db_url}")
print(f" LLM Provider: {llm_provider}")
print()
uvicorn.run(**uvicorn_config)
if __name__ == "__main__":
main()
+154
View File
@@ -0,0 +1,154 @@
"""
Centralized configuration for Hindsight API.
All environment variables and their defaults are defined here.
"""
import os
from dataclasses import dataclass
from typing import Optional
import logging
logger = logging.getLogger(__name__)
# Environment variable names
ENV_DATABASE_URL = "HINDSIGHT_API_DATABASE_URL"
ENV_LLM_PROVIDER = "HINDSIGHT_API_LLM_PROVIDER"
ENV_LLM_API_KEY = "HINDSIGHT_API_LLM_API_KEY"
ENV_LLM_MODEL = "HINDSIGHT_API_LLM_MODEL"
ENV_LLM_BASE_URL = "HINDSIGHT_API_LLM_BASE_URL"
ENV_EMBEDDINGS_PROVIDER = "HINDSIGHT_API_EMBEDDINGS_PROVIDER"
ENV_EMBEDDINGS_LOCAL_MODEL = "HINDSIGHT_API_EMBEDDINGS_LOCAL_MODEL"
ENV_EMBEDDINGS_TEI_URL = "HINDSIGHT_API_EMBEDDINGS_TEI_URL"
ENV_RERANKER_PROVIDER = "HINDSIGHT_API_RERANKER_PROVIDER"
ENV_RERANKER_LOCAL_MODEL = "HINDSIGHT_API_RERANKER_LOCAL_MODEL"
ENV_RERANKER_TEI_URL = "HINDSIGHT_API_RERANKER_TEI_URL"
ENV_HOST = "HINDSIGHT_API_HOST"
ENV_PORT = "HINDSIGHT_API_PORT"
ENV_LOG_LEVEL = "HINDSIGHT_API_LOG_LEVEL"
ENV_MCP_ENABLED = "HINDSIGHT_API_MCP_ENABLED"
# Default values
DEFAULT_DATABASE_URL = "pg0"
DEFAULT_LLM_PROVIDER = "groq"
DEFAULT_LLM_MODEL = "openai/gpt-oss-20b"
DEFAULT_EMBEDDINGS_PROVIDER = "local"
DEFAULT_EMBEDDINGS_LOCAL_MODEL = "BAAI/bge-small-en-v1.5"
DEFAULT_RERANKER_PROVIDER = "local"
DEFAULT_RERANKER_LOCAL_MODEL = "cross-encoder/ms-marco-MiniLM-L-6-v2"
DEFAULT_HOST = "0.0.0.0"
DEFAULT_PORT = 8888
DEFAULT_LOG_LEVEL = "info"
DEFAULT_MCP_ENABLED = True
# Required embedding dimension for database schema
EMBEDDING_DIMENSION = 384
@dataclass
class HindsightConfig:
"""Configuration container for Hindsight API."""
# Database
database_url: str
# LLM
llm_provider: str
llm_api_key: Optional[str]
llm_model: str
llm_base_url: Optional[str]
# Embeddings
embeddings_provider: str
embeddings_local_model: str
embeddings_tei_url: Optional[str]
# Reranker
reranker_provider: str
reranker_local_model: str
reranker_tei_url: Optional[str]
# Server
host: str
port: int
log_level: str
mcp_enabled: bool
@classmethod
def from_env(cls) -> "HindsightConfig":
"""Create configuration from environment variables."""
return cls(
# Database
database_url=os.getenv(ENV_DATABASE_URL, DEFAULT_DATABASE_URL),
# LLM
llm_provider=os.getenv(ENV_LLM_PROVIDER, DEFAULT_LLM_PROVIDER),
llm_api_key=os.getenv(ENV_LLM_API_KEY),
llm_model=os.getenv(ENV_LLM_MODEL, DEFAULT_LLM_MODEL),
llm_base_url=os.getenv(ENV_LLM_BASE_URL) or None,
# Embeddings
embeddings_provider=os.getenv(ENV_EMBEDDINGS_PROVIDER, DEFAULT_EMBEDDINGS_PROVIDER),
embeddings_local_model=os.getenv(ENV_EMBEDDINGS_LOCAL_MODEL, DEFAULT_EMBEDDINGS_LOCAL_MODEL),
embeddings_tei_url=os.getenv(ENV_EMBEDDINGS_TEI_URL),
# Reranker
reranker_provider=os.getenv(ENV_RERANKER_PROVIDER, DEFAULT_RERANKER_PROVIDER),
reranker_local_model=os.getenv(ENV_RERANKER_LOCAL_MODEL, DEFAULT_RERANKER_LOCAL_MODEL),
reranker_tei_url=os.getenv(ENV_RERANKER_TEI_URL),
# Server
host=os.getenv(ENV_HOST, DEFAULT_HOST),
port=int(os.getenv(ENV_PORT, DEFAULT_PORT)),
log_level=os.getenv(ENV_LOG_LEVEL, DEFAULT_LOG_LEVEL),
mcp_enabled=os.getenv(ENV_MCP_ENABLED, str(DEFAULT_MCP_ENABLED)).lower() == "true",
)
def get_llm_base_url(self) -> str:
"""Get the LLM base URL, with provider-specific defaults."""
if self.llm_base_url:
return self.llm_base_url
provider = self.llm_provider.lower()
if provider == "groq":
return "https://api.groq.com/openai/v1"
elif provider == "ollama":
return "http://localhost:11434/v1"
else:
return ""
def get_python_log_level(self) -> int:
"""Get the Python logging level from the configured log level string."""
log_level_map = {
"critical": logging.CRITICAL,
"error": logging.ERROR,
"warning": logging.WARNING,
"info": logging.INFO,
"debug": logging.DEBUG,
"trace": logging.DEBUG, # Python doesn't have TRACE, use DEBUG
}
return log_level_map.get(self.log_level.lower(), logging.INFO)
def configure_logging(self) -> None:
"""Configure Python logging based on the log level."""
logging.basicConfig(
level=self.get_python_log_level(),
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s"
)
def log_config(self) -> None:
"""Log the current configuration (without sensitive values)."""
logger.info(f"Database: {self.database_url}")
logger.info(f"LLM: provider={self.llm_provider}, model={self.llm_model}")
logger.info(f"Embeddings: provider={self.embeddings_provider}")
logger.info(f"Reranker: provider={self.reranker_provider}")
def get_config() -> HindsightConfig:
"""Get the current configuration from environment variables."""
return HindsightConfig.from_env()
@@ -3,14 +3,7 @@ Cross-encoder abstraction for reranking.
Provides an interface for reranking with different backends.
Configuration via environment variables:
- HINDSIGHT_API_RERANKER_PROVIDER: "local" (default) or "tei"
For local provider:
- HINDSIGHT_API_RERANKER_LOCAL_MODEL: Model name (default: cross-encoder/ms-marco-MiniLM-L-6-v2)
For TEI provider:
- HINDSIGHT_API_RERANKER_TEI_URL: TEI server URL (required)
Configuration via environment variables - see hindsight_api.config for all env var names.
"""
from abc import ABC, abstractmethod
from typing import List, Tuple, Optional
@@ -19,10 +12,15 @@ import os
import httpx
logger = logging.getLogger(__name__)
from ..config import (
ENV_RERANKER_PROVIDER,
ENV_RERANKER_LOCAL_MODEL,
ENV_RERANKER_TEI_URL,
DEFAULT_RERANKER_PROVIDER,
DEFAULT_RERANKER_LOCAL_MODEL,
)
# Default model for local cross-encoder
DEFAULT_RERANKER_MODEL = "cross-encoder/ms-marco-MiniLM-L-6-v2"
logger = logging.getLogger(__name__)
class CrossEncoderModel(ABC):
@@ -82,7 +80,7 @@ class LocalSTCrossEncoder(CrossEncoderModel):
model_name: Name of the CrossEncoder model to use.
Default: cross-encoder/ms-marco-MiniLM-L-6-v2
"""
self.model_name = model_name or DEFAULT_RERANKER_MODEL
self.model_name = model_name or DEFAULT_RERANKER_LOCAL_MODEL
self._model = None
@property
@@ -284,30 +282,23 @@ def create_cross_encoder_from_env() -> CrossEncoderModel:
"""
Create a CrossEncoderModel instance based on environment variables.
Environment variables:
- HINDSIGHT_API_RERANKER_PROVIDER: "local" (default) or "tei"
For local provider:
- HINDSIGHT_API_RERANKER_LOCAL_MODEL: Model name (default: cross-encoder/ms-marco-MiniLM-L-6-v2)
For TEI provider:
- HINDSIGHT_API_RERANKER_TEI_URL: TEI server URL (required)
See hindsight_api.config for environment variable names and defaults.
Returns:
Configured CrossEncoderModel instance
"""
provider = os.environ.get("HINDSIGHT_API_RERANKER_PROVIDER", "local").lower()
provider = os.environ.get(ENV_RERANKER_PROVIDER, DEFAULT_RERANKER_PROVIDER).lower()
if provider == "tei":
url = os.environ.get("HINDSIGHT_API_RERANKER_TEI_URL")
url = os.environ.get(ENV_RERANKER_TEI_URL)
if not url:
raise ValueError(
"HINDSIGHT_API_RERANKER_TEI_URL is required when HINDSIGHT_API_RERANKER_PROVIDER is 'tei'"
f"{ENV_RERANKER_TEI_URL} is required when {ENV_RERANKER_PROVIDER} is 'tei'"
)
return RemoteTEICrossEncoder(base_url=url)
elif provider == "local":
model = os.environ.get("HINDSIGHT_API_RERANKER_LOCAL_MODEL")
model_name = model or DEFAULT_RERANKER_MODEL
model = os.environ.get(ENV_RERANKER_LOCAL_MODEL)
model_name = model or DEFAULT_RERANKER_LOCAL_MODEL
return LocalSTCrossEncoder(model_name=model_name)
else:
raise ValueError(
@@ -6,14 +6,7 @@ Provides an interface for generating embeddings with different backends.
IMPORTANT: All embeddings must produce 384-dimensional vectors to match
the database schema (pgvector column defined as vector(384)).
Configuration via environment variables:
- HINDSIGHT_API_EMBEDDINGS_PROVIDER: "local" (default) or "tei"
For local provider:
- HINDSIGHT_API_EMBEDDINGS_LOCAL_MODEL: Model name (default: BAAI/bge-small-en-v1.5)
For TEI provider:
- HINDSIGHT_API_EMBEDDINGS_TEI_URL: TEI server URL (required)
Configuration via environment variables - see hindsight_api.config for all env var names.
"""
from abc import ABC, abstractmethod
from typing import List, Optional
@@ -22,14 +15,17 @@ import os
import httpx
from ..config import (
ENV_EMBEDDINGS_PROVIDER,
ENV_EMBEDDINGS_LOCAL_MODEL,
ENV_EMBEDDINGS_TEI_URL,
DEFAULT_EMBEDDINGS_PROVIDER,
DEFAULT_EMBEDDINGS_LOCAL_MODEL,
EMBEDDING_DIMENSION,
)
logger = logging.getLogger(__name__)
# Fixed embedding dimension required by database schema
EMBEDDING_DIMENSION = 384
# Default model for local embeddings
DEFAULT_EMBEDDINGS_MODEL = "BAAI/bge-small-en-v1.5"
class Embeddings(ABC):
"""
@@ -88,7 +84,7 @@ class LocalSTEmbeddings(Embeddings):
Must produce 384-dimensional embeddings.
Default: BAAI/bge-small-en-v1.5
"""
self.model_name = model_name or DEFAULT_EMBEDDINGS_MODEL
self.model_name = model_name or DEFAULT_EMBEDDINGS_LOCAL_MODEL
self._model = None
@property
@@ -272,30 +268,23 @@ def create_embeddings_from_env() -> Embeddings:
"""
Create an Embeddings instance based on environment variables.
Environment variables:
- HINDSIGHT_API_EMBEDDINGS_PROVIDER: "local" (default) or "tei"
For local provider:
- HINDSIGHT_API_EMBEDDINGS_LOCAL_MODEL: Model name (default: BAAI/bge-small-en-v1.5)
For TEI provider:
- HINDSIGHT_API_EMBEDDINGS_TEI_URL: TEI server URL (required)
See hindsight_api.config for environment variable names and defaults.
Returns:
Configured Embeddings instance
"""
provider = os.environ.get("HINDSIGHT_API_EMBEDDINGS_PROVIDER", "local").lower()
provider = os.environ.get(ENV_EMBEDDINGS_PROVIDER, DEFAULT_EMBEDDINGS_PROVIDER).lower()
if provider == "tei":
url = os.environ.get("HINDSIGHT_API_EMBEDDINGS_TEI_URL")
url = os.environ.get(ENV_EMBEDDINGS_TEI_URL)
if not url:
raise ValueError(
"HINDSIGHT_API_EMBEDDINGS_TEI_URL is required when HINDSIGHT_API_EMBEDDINGS_PROVIDER is 'tei'"
f"{ENV_EMBEDDINGS_TEI_URL} is required when {ENV_EMBEDDINGS_PROVIDER} is 'tei'"
)
return RemoteTEIEmbeddings(base_url=url)
elif provider == "local":
model = os.environ.get("HINDSIGHT_API_EMBEDDINGS_LOCAL_MODEL")
model_name = model or DEFAULT_EMBEDDINGS_MODEL
model = os.environ.get(ENV_EMBEDDINGS_LOCAL_MODEL)
model_name = model or DEFAULT_EMBEDDINGS_LOCAL_MODEL
return LocalSTEmbeddings(model_name=model_name)
else:
raise ValueError(
+65 -275
View File
@@ -6,9 +6,6 @@ import time
import asyncio
from typing import Optional, Any, Dict, List
from openai import AsyncOpenAI, RateLimitError, APIError, APIStatusError, APIConnectionError, LengthFinishReasonError
from google import genai
from google.genai import types as genai_types
from google.genai import errors as genai_errors
import logging
# Seed applied to every Groq request for deterministic behavior.
@@ -34,8 +31,12 @@ class OutputTooLongError(Exception):
pass
class LLMConfig:
"""Configuration for an LLM provider."""
class LLMProvider:
"""
Unified LLM provider using OpenAI-compatible API.
Supports OpenAI, Groq, and Ollama (any OpenAI-compatible endpoint).
"""
def __init__(
self,
@@ -43,16 +44,17 @@ class LLMConfig:
api_key: str,
base_url: str,
model: str,
reasoning_effort: str = "low",
reasoning_effort: str = "low",
):
"""
Initialize LLM configuration.
Initialize LLM provider.
Args:
provider: Provider name ("openai", "groq", "ollama"). Required.
api_key: API key. Required.
base_url: Base URL. Required.
model: Model name. Required.
provider: Provider name ("openai", "groq", "ollama").
api_key: API key.
base_url: Base URL for the API.
model: Model name.
reasoning_effort: Reasoning effort level for supported providers.
"""
self.provider = provider.lower()
self.api_key = api_key
@@ -61,9 +63,10 @@ class LLMConfig:
self.reasoning_effort = reasoning_effort
# Validate provider
if self.provider not in ["openai", "groq", "ollama", "gemini"]:
valid_providers = ["openai", "groq", "ollama"]
if self.provider not in valid_providers:
raise ValueError(
f"Invalid LLM provider: {self.provider}. Must be 'openai', 'groq', 'ollama', or 'gemini'."
f"Invalid LLM provider: {self.provider}. Must be one of: {', '.join(valid_providers)}"
)
# Set default base URLs
@@ -74,25 +77,14 @@ class LLMConfig:
self.base_url = "http://localhost:11434/v1"
# Validate API key (not needed for ollama)
if self.provider not in ["ollama"] and not self.api_key:
raise ValueError(
f"API key not found for {self.provider}"
)
if self.provider != "ollama" and not self.api_key:
raise ValueError(f"API key not found for {self.provider}")
# Create client (private - use .call() method instead)
# Disable automatic retries - we handle retries in the call() method
if self.provider == "gemini":
self._gemini_client = genai.Client(api_key=self.api_key)
self._client = None # Not used for Gemini
elif self.provider == "ollama":
# Create OpenAI-compatible client for all providers
if self.provider == "ollama":
self._client = AsyncOpenAI(api_key="ollama", base_url=self.base_url, max_retries=0)
self._gemini_client = None
elif self.base_url:
self._client = AsyncOpenAI(api_key=self.api_key, base_url=self.base_url, max_retries=0)
self._gemini_client = None
else:
self._client = AsyncOpenAI(api_key=self.api_key, max_retries=0)
self._gemini_client = None
self._client = AsyncOpenAI(api_key=self.api_key, base_url=self.base_url, max_retries=0)
logger.info(
f"Initialized LLM: provider={self.provider}, model={self.model}, base_url={self.base_url}"
@@ -102,101 +94,92 @@ class LLMConfig:
self,
messages: List[Dict[str, str]],
response_format: Optional[Any] = None,
max_completion_tokens: Optional[int] = None,
temperature: Optional[float] = None,
scope: str = "memory",
max_retries: int = 10,
initial_backoff: float = 1.0,
max_backoff: float = 60.0,
skip_validation: bool = False,
**kwargs
) -> Any:
"""
Make an LLM API call with consistent configuration and retry logic.
Make an LLM API call with retry logic.
Args:
messages: List of message dicts with 'role' and 'content'
response_format: Optional Pydantic model for structured output
scope: Scope identifier (e.g., 'memory', 'judge') for future tracking
max_retries: Maximum number of retry attempts (default: 5)
initial_backoff: Initial backoff time in seconds (default: 1.0)
max_backoff: Maximum backoff time in seconds (default: 60.0)
**kwargs: Additional parameters to pass to the API (temperature, max_tokens, etc.)
messages: List of message dicts with 'role' and 'content'.
response_format: Optional Pydantic model for structured output.
max_completion_tokens: Maximum tokens in response.
temperature: Sampling temperature (0.0-2.0).
scope: Scope identifier for tracking.
max_retries: Maximum retry attempts.
initial_backoff: Initial backoff time in seconds.
max_backoff: Maximum backoff time in seconds.
skip_validation: Return raw JSON without Pydantic validation.
Returns:
Parsed response if response_format is provided, otherwise the text content
Parsed response if response_format is provided, otherwise text content.
Raises:
Exception: Re-raises any API errors after all retries are exhausted
OutputTooLongError: If output exceeds token limits.
Exception: Re-raises API errors after retries exhausted.
"""
# Use global semaphore to limit concurrent requests
async with _global_llm_semaphore:
start_time = time.time()
import json
# Handle Gemini provider separately
if self.provider == "gemini":
return await self._call_gemini(messages, response_format, max_retries, initial_backoff, max_backoff, skip_validation, start_time, **kwargs)
call_params = {
"model": self.model,
"messages": messages,
**kwargs
}
if max_completion_tokens is not None:
call_params["max_completion_tokens"] = max_completion_tokens
if temperature is not None:
call_params["temperature"] = temperature
# Provider-specific parameters
if self.provider == "groq":
call_params["seed"] = DEFAULT_LLM_SEED
if self.provider == "groq":
call_params["extra_body"] = {
"service_tier": "auto",
"reasoning_effort": self.reasoning_effort,
"include_reasoning": False, # Disable hidden reasoning tokens
"include_reasoning": False,
}
last_exception = None
for attempt in range(max_retries + 1):
try:
# Use the appropriate response format
if response_format is not None:
# Use JSON mode instead of strict parse for flexibility with optional fields
# This allows the LLM to omit optional fields without validation errors
# Add schema to the system message
# Add schema to system message for JSON mode
if hasattr(response_format, 'model_json_schema'):
schema = response_format.model_json_schema()
schema_msg = f"\n\nYou must respond with valid JSON matching this schema:\n{json.dumps(schema, indent=2)}"
# Add schema to the system message if present, otherwise prepend as user message
if call_params['messages'] and call_params['messages'][0].get('role') == 'system':
call_params['messages'][0]['content'] += schema_msg
else:
# No system message, add schema instruction to first user message
if call_params['messages']:
call_params['messages'][0]['content'] = schema_msg + "\n\n" + call_params['messages'][0]['content']
elif call_params['messages']:
call_params['messages'][0]['content'] = schema_msg + "\n\n" + call_params['messages'][0]['content']
call_params['response_format'] = {"type": "json_object"}
response = await self._client.chat.completions.create(**call_params)
# Parse the JSON response
content = response.choices[0].message.content
json_data = json.loads(content)
# Return raw JSON if skip_validation is True, otherwise validate with Pydantic
if skip_validation:
result = json_data
else:
result = response_format.model_validate(json_data)
else:
# Standard completion and return text content
response = await self._client.chat.completions.create(**call_params)
result = response.choices[0].message.content
# Log call details only if it takes more than 5 seconds
# Log slow calls
duration = time.time() - start_time
usage = response.usage
if duration > 10.0:
ratio = max(1, usage.completion_tokens) / usage.prompt_tokens
# Check for cached tokens (OpenAI/Groq may include this)
cached_tokens = 0
if hasattr(usage, 'prompt_tokens_details') and usage.prompt_tokens_details:
cached_tokens = getattr(usage.prompt_tokens_details, 'cached_tokens', 0) or 0
@@ -210,14 +193,12 @@ class LLMConfig:
return result
except LengthFinishReasonError as e:
# Output exceeded token limits - raise bridge exception for caller to handle
logger.warning(f"LLM output exceeded token limits: {str(e)}")
raise OutputTooLongError(
f"LLM output exceeded token limits. Input may need to be split into smaller chunks."
) from e
except APIConnectionError as e:
# Handle connection errors (server disconnected, network issues) with retry
last_exception = e
if attempt < max_retries:
logger.warning(f"Connection error, retrying... (attempt {attempt + 1}/{max_retries + 1})")
@@ -229,19 +210,18 @@ class LLMConfig:
raise
except APIStatusError as e:
# Fast fail on 4xx client errors (except 429 rate limit and 498 which is treated as server error)
if 400 <= e.status_code < 500 and e.status_code not in (429, 498):
logger.error(f"Client error (HTTP {e.status_code}), not retrying: {str(e)}")
raise
last_exception = e
if attempt < max_retries:
# Calculate exponential backoff with jitter
backoff = min(initial_backoff * (2 ** attempt), max_backoff)
# Add jitter (±20%)
jitter = backoff * 0.2 * (2 * (time.time() % 1) - 1)
sleep_time = backoff + jitter
# Only log if it's a non-retryable error or final attempt
# Silent retry for common transient errors like capacity exceeded
await asyncio.sleep(sleep_time)
else:
# Log only on final failed attempt
logger.error(f"API error after {max_retries + 1} attempts: {str(e)}")
raise
@@ -249,184 +229,18 @@ class LLMConfig:
logger.error(f"Unexpected error during LLM call: {type(e).__name__}: {str(e)}")
raise
# This should never be reached, but just in case
if last_exception:
raise last_exception
raise RuntimeError(f"LLM call failed after all retries with no exception captured")
async def _call_gemini(
self,
messages: List[Dict[str, str]],
response_format: Optional[Any],
max_retries: int,
initial_backoff: float,
max_backoff: float,
skip_validation: bool,
start_time: float,
**kwargs
) -> Any:
"""Handle Gemini-specific API calls using google-genai SDK."""
import json
# Convert OpenAI-style messages to Gemini format
# Gemini uses 'user' and 'model' roles, and system instructions are separate
system_instruction = None
gemini_contents = []
for msg in messages:
role = msg.get('role', 'user')
content = msg.get('content', '')
if role == 'system':
# Accumulate system messages as system instruction
if system_instruction:
system_instruction += "\n\n" + content
else:
system_instruction = content
elif role == 'assistant':
gemini_contents.append(genai_types.Content(
role="model",
parts=[genai_types.Part(text=content)]
))
else: # user or any other role
gemini_contents.append(genai_types.Content(
role="user",
parts=[genai_types.Part(text=content)]
))
# Add JSON schema instruction if response_format is provided
if response_format is not None and hasattr(response_format, 'model_json_schema'):
schema = response_format.model_json_schema()
schema_msg = f"\n\nYou must respond with valid JSON matching this schema:\n{json.dumps(schema, indent=2)}"
if system_instruction:
system_instruction += schema_msg
else:
system_instruction = schema_msg
# Build generation config
config_kwargs = {}
if system_instruction:
config_kwargs['system_instruction'] = system_instruction
if 'temperature' in kwargs:
config_kwargs['temperature'] = kwargs['temperature']
if 'max_tokens' in kwargs:
config_kwargs['max_output_tokens'] = kwargs['max_tokens']
if response_format is not None:
config_kwargs['response_mime_type'] = 'application/json'
# Pass the Pydantic model directly as response_schema for structured output
config_kwargs['response_schema'] = response_format
generation_config = genai_types.GenerateContentConfig(**config_kwargs) if config_kwargs else None
last_exception = None
for attempt in range(max_retries + 1):
try:
response = await self._gemini_client.aio.models.generate_content(
model=self.model,
contents=gemini_contents,
config=generation_config,
)
content = response.text
# Handle empty/None response (can happen with content filtering or timeouts)
if content is None:
# Check if there's a block reason
block_reason = None
if hasattr(response, 'candidates') and response.candidates:
candidate = response.candidates[0]
if hasattr(candidate, 'finish_reason'):
block_reason = candidate.finish_reason
if attempt < max_retries:
logger.warning(f"Gemini returned empty response (reason: {block_reason}), retrying... (attempt {attempt + 1}/{max_retries + 1})")
backoff = min(initial_backoff * (2 ** attempt), max_backoff)
await asyncio.sleep(backoff)
continue
else:
raise RuntimeError(f"Gemini returned empty response after {max_retries + 1} attempts (reason: {block_reason})")
if response_format is not None:
# Parse the JSON response
json_data = json.loads(content)
# Return raw JSON if skip_validation is True, otherwise validate with Pydantic
if skip_validation:
result = json_data
else:
result = response_format.model_validate(json_data)
else:
result = content
# Log call details only if it takes more than 10 seconds
duration = time.time() - start_time
if duration > 10.0 and hasattr(response, 'usage_metadata') and response.usage_metadata:
usage = response.usage_metadata
# Check for cached tokens (Gemini uses cached_content_token_count)
cached_tokens = getattr(usage, 'cached_content_token_count', 0) or 0
cache_info = f", cached_tokens={cached_tokens}" if cached_tokens > 0 else ""
logger.info(
f"slow llm call: model={self.provider}/{self.model}, "
f"input_tokens={usage.prompt_token_count}, output_tokens={usage.candidates_token_count}{cache_info}, "
f"time={duration:.3f}s"
)
return result
except json.JSONDecodeError as e:
# Handle truncated JSON responses (often from MAX_TOKENS) with retry
last_exception = e
if attempt < max_retries:
logger.warning(f"Gemini returned invalid JSON (truncated response?), retrying... (attempt {attempt + 1}/{max_retries + 1})")
backoff = min(initial_backoff * (2 ** attempt), max_backoff)
await asyncio.sleep(backoff)
continue
else:
logger.error(f"Gemini returned invalid JSON after {max_retries + 1} attempts: {str(e)}")
raise
except genai_errors.APIError as e:
# Handle rate limits and server errors with retry
if e.code in (429, 503, 500):
last_exception = e
if attempt < max_retries:
backoff = min(initial_backoff * (2 ** attempt), max_backoff)
jitter = backoff * 0.2 * (2 * (time.time() % 1) - 1)
sleep_time = backoff + jitter
await asyncio.sleep(sleep_time)
else:
logger.error(f"Gemini API error after {max_retries + 1} attempts: {str(e)}")
raise
else:
logger.error(f"Gemini API error: {type(e).__name__}: {str(e)}")
raise
except Exception as e:
logger.error(f"Unexpected error during Gemini call: {type(e).__name__}: {str(e)}")
raise
if last_exception:
raise last_exception
raise RuntimeError(f"Gemini call failed after all retries with no exception captured")
@classmethod
def for_memory(cls) -> "LLMConfig":
"""Create configuration for memory operations from environment variables."""
def for_memory(cls) -> "LLMProvider":
"""Create provider for memory operations from environment variables."""
provider = os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq")
api_key = os.getenv("HINDSIGHT_API_LLM_API_KEY")
base_url = os.getenv("HINDSIGHT_API_LLM_BASE_URL")
base_url = os.getenv("HINDSIGHT_API_LLM_BASE_URL", "")
model = os.getenv("HINDSIGHT_API_LLM_MODEL", "openai/gpt-oss-120b")
# Set default base URL if not provided
if not base_url:
if provider == "groq":
base_url = "https://api.groq.com/openai/v1"
elif provider == "ollama":
base_url = "http://localhost:11434/v1"
else:
base_url = ""
return cls(
provider=provider,
api_key=api_key,
@@ -436,27 +250,13 @@ class LLMConfig:
)
@classmethod
def for_answer_generation(cls) -> "LLMConfig":
"""
Create configuration for answer generation operations from environment variables.
Falls back to memory LLM config if answer-specific config not set.
"""
# Check if answer-specific config exists, otherwise fall back to memory config
def for_answer_generation(cls) -> "LLMProvider":
"""Create provider for answer generation. Falls back to memory config if not set."""
provider = os.getenv("HINDSIGHT_API_ANSWER_LLM_PROVIDER", os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq"))
api_key = os.getenv("HINDSIGHT_API_ANSWER_LLM_API_KEY", os.getenv("HINDSIGHT_API_LLM_API_KEY"))
base_url = os.getenv("HINDSIGHT_API_ANSWER_LLM_BASE_URL", os.getenv("HINDSIGHT_API_LLM_BASE_URL"))
base_url = os.getenv("HINDSIGHT_API_ANSWER_LLM_BASE_URL", os.getenv("HINDSIGHT_API_LLM_BASE_URL", ""))
model = os.getenv("HINDSIGHT_API_ANSWER_LLM_MODEL", os.getenv("HINDSIGHT_API_LLM_MODEL", "openai/gpt-oss-120b"))
# Set default base URL if not provided
if not base_url:
if provider == "groq":
base_url = "https://api.groq.com/openai/v1"
elif provider == "ollama":
base_url = "http://localhost:11434/v1"
else:
base_url = ""
return cls(
provider=provider,
api_key=api_key,
@@ -466,27 +266,13 @@ class LLMConfig:
)
@classmethod
def for_judge(cls) -> "LLMConfig":
"""
Create configuration for judge/evaluator operations from environment variables.
Falls back to memory LLM config if judge-specific config not set.
"""
# Check if judge-specific config exists, otherwise fall back to memory config
def for_judge(cls) -> "LLMProvider":
"""Create provider for judge/evaluator operations. Falls back to memory config if not set."""
provider = os.getenv("HINDSIGHT_API_JUDGE_LLM_PROVIDER", os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq"))
api_key = os.getenv("HINDSIGHT_API_JUDGE_LLM_API_KEY", os.getenv("HINDSIGHT_API_LLM_API_KEY"))
base_url = os.getenv("HINDSIGHT_API_JUDGE_LLM_BASE_URL", os.getenv("HINDSIGHT_API_LLM_BASE_URL"))
base_url = os.getenv("HINDSIGHT_API_JUDGE_LLM_BASE_URL", os.getenv("HINDSIGHT_API_LLM_BASE_URL", ""))
model = os.getenv("HINDSIGHT_API_JUDGE_LLM_MODEL", os.getenv("HINDSIGHT_API_LLM_MODEL", "openai/gpt-oss-120b"))
# Set default base URL if not provided
if not base_url:
if provider == "groq":
base_url = "https://api.groq.com/openai/v1"
elif provider == "ollama":
base_url = "http://localhost:11434/v1"
else:
base_url = ""
return cls(
provider=provider,
api_key=api_key,
@@ -494,3 +280,7 @@ class LLMConfig:
model=model,
reasoning_effort="high"
)
# Backwards compatibility alias
LLMConfig = LLMProvider
@@ -11,7 +11,7 @@ This implements a sophisticated memory architecture that combines:
import json
import os
from datetime import datetime, timedelta, timezone
from typing import Any, Dict, List, Optional, Tuple, Union, TypedDict
from typing import Any, Dict, List, Optional, Tuple, Union, TypedDict, TYPE_CHECKING
import asyncpg
import asyncio
from .embeddings import Embeddings, create_embeddings_from_env
@@ -22,6 +22,9 @@ import uuid
import logging
from pydantic import BaseModel, Field
if TYPE_CHECKING:
from ..config import HindsightConfig
class RetainContentDict(TypedDict, total=False):
"""Type definition for content items in retain_batch_async.
@@ -99,10 +102,10 @@ class MemoryEngine:
def __init__(
self,
db_url: str,
memory_llm_provider: str,
memory_llm_api_key: str,
memory_llm_model: str,
db_url: Optional[str] = None,
memory_llm_provider: Optional[str] = None,
memory_llm_api_key: Optional[str] = None,
memory_llm_model: Optional[str] = None,
memory_llm_base_url: Optional[str] = None,
embeddings: Optional[Embeddings] = None,
cross_encoder: Optional[CrossEncoderModel] = None,
@@ -115,26 +118,34 @@ class MemoryEngine:
"""
Initialize the temporal + semantic memory system.
All parameters are optional and will be read from environment variables if not provided.
See hindsight_api.config for environment variable names and defaults.
Args:
db_url: PostgreSQL connection URL (postgresql://user:pass@host:port/dbname). Required.
db_url: PostgreSQL connection URL. Defaults to HINDSIGHT_API_DATABASE_URL env var or "pg0".
Also supports pg0 URLs: "pg0" or "pg0://instance-name" or "pg0://instance-name:port"
memory_llm_provider: LLM provider for memory operations: "openai", "groq", or "ollama". Required.
memory_llm_api_key: API key for the LLM provider. Required.
memory_llm_model: Model name to use for all memory operations (put/think/opinions). Required.
memory_llm_base_url: Base URL for the LLM API. Optional. Defaults based on provider:
- groq: https://api.groq.com/openai/v1
- ollama: http://localhost:11434/v1
embeddings: Embeddings implementation to use. If not provided, uses LocalSTEmbeddings
cross_encoder: Cross-encoder model for reranking. If not provided, uses default when cross-encoder reranker is selected
query_analyzer: Query analyzer implementation to use. If not provided, uses TransformerQueryAnalyzer
memory_llm_provider: LLM provider. Defaults to HINDSIGHT_API_LLM_PROVIDER env var or "groq".
memory_llm_api_key: API key for the LLM provider. Defaults to HINDSIGHT_API_LLM_API_KEY env var.
memory_llm_model: Model name. Defaults to HINDSIGHT_API_LLM_MODEL env var.
memory_llm_base_url: Base URL for the LLM API. Defaults based on provider.
embeddings: Embeddings implementation. If not provided, created from env vars.
cross_encoder: Cross-encoder model. If not provided, created from env vars.
query_analyzer: Query analyzer implementation. If not provided, uses DateparserQueryAnalyzer.
pool_min_size: Minimum number of connections in the pool (default: 5)
pool_max_size: Maximum number of connections in the pool (default: 100)
Increase for parallel think/search operations (e.g., 200-300 for 100+ parallel thinks)
task_backend: Custom task backend for async task execution. If not provided, uses AsyncIOQueueBackend
task_backend: Custom task backend. If not provided, uses AsyncIOQueueBackend.
run_migrations: Whether to run database migrations during initialize(). Default: True
"""
if not db_url:
raise ValueError("Database url is required")
# Load config from environment for any missing parameters
from ..config import get_config
config = get_config()
# Apply defaults from config
db_url = db_url or config.database_url
memory_llm_provider = memory_llm_provider or config.llm_provider
memory_llm_api_key = memory_llm_api_key or config.llm_api_key
memory_llm_model = memory_llm_model or config.llm_model
memory_llm_base_url = memory_llm_base_url or config.get_llm_base_url() or None
# Track pg0 instance (if used)
self._pg0: Optional[EmbeddedPostgres] = None
self._pg0_instance_name: Optional[str] = None
@@ -2701,7 +2712,7 @@ Guidelines:
],
scope="memory_think",
temperature=0.9,
max_tokens=1000
max_completion_tokens=1000
)
llm_time = time.time() - llm_start
@@ -273,7 +273,7 @@ Merged background:"""
response_format=BackgroundMergeResponse,
scope="bank_background",
temperature=0.3,
max_tokens=8192
max_completion_tokens=8192
)
logger.info(f"Successfully got structured response: background={parsed.background[:100]}")
@@ -291,7 +291,7 @@ Merged background:"""
messages=messages,
scope="bank_background",
temperature=0.3,
max_tokens=8192
max_completion_tokens=8192
)
logger.info(f"LLM response for background merge (first 500 chars): {content[:500]}")
@@ -579,7 +579,7 @@ Text:
response_format=FactExtractionResponse,
scope="memory_extract_facts",
temperature=0.1,
max_tokens=65000,
max_completion_tokens=65000,
skip_validation=True, # Get raw JSON, we'll validate leniently
)
+201
View File
@@ -0,0 +1,201 @@
"""
Command-line interface for Hindsight API.
Run the server with:
hindsight-api
Stop with Ctrl+C.
"""
import argparse
import asyncio
import atexit
import os
import signal
import sys
import warnings
from typing import Optional
import uvicorn
from . import MemoryEngine
from .api import create_app
from .config import get_config, HindsightConfig
# Filter deprecation warnings from third-party libraries
warnings.filterwarnings("ignore", message="websockets.legacy is deprecated")
warnings.filterwarnings("ignore", message="websockets.server.WebSocketServerProtocol is deprecated")
# Disable tokenizers parallelism to avoid warnings
os.environ["TOKENIZERS_PARALLELISM"] = "false"
# Global reference for cleanup
_memory: Optional[MemoryEngine] = None
def _cleanup():
"""Synchronous cleanup function to stop resources on exit."""
global _memory
if _memory is not None and _memory._pg0 is not None:
try:
loop = asyncio.new_event_loop()
loop.run_until_complete(_memory._pg0.stop())
loop.close()
print("\npg0 stopped.")
except Exception as e:
print(f"\nError stopping pg0: {e}")
def _signal_handler(signum, frame):
"""Handle SIGINT/SIGTERM to ensure cleanup."""
print(f"\nReceived signal {signum}, shutting down...")
_cleanup()
sys.exit(0)
def main():
"""Main entry point for the CLI."""
global _memory
# Load configuration from environment (for CLI args defaults)
config = get_config()
parser = argparse.ArgumentParser(
prog="hindsight-api",
description="Hindsight API Server",
)
# Server options
parser.add_argument(
"--host", default=config.host,
help=f"Host to bind to (default: {config.host}, env: HINDSIGHT_API_HOST)"
)
parser.add_argument(
"--port", type=int, default=config.port,
help=f"Port to bind to (default: {config.port}, env: HINDSIGHT_API_PORT)"
)
parser.add_argument(
"--log-level", default=config.log_level,
choices=["critical", "error", "warning", "info", "debug", "trace"],
help=f"Log level (default: {config.log_level}, env: HINDSIGHT_API_LOG_LEVEL)"
)
# Development options
parser.add_argument(
"--reload", action="store_true",
help="Enable auto-reload on code changes (development only)"
)
parser.add_argument(
"--workers", type=int, default=1,
help="Number of worker processes (default: 1)"
)
# Access log options
parser.add_argument(
"--access-log", action="store_true",
help="Enable access log"
)
parser.add_argument(
"--no-access-log", dest="access_log", action="store_false",
help="Disable access log (default)"
)
parser.set_defaults(access_log=False)
# Proxy options
parser.add_argument(
"--proxy-headers", action="store_true",
help="Enable X-Forwarded-Proto, X-Forwarded-For headers"
)
parser.add_argument(
"--forwarded-allow-ips", default=None,
help="Comma separated list of IPs to trust with proxy headers"
)
# SSL options
parser.add_argument(
"--ssl-keyfile", default=None,
help="SSL key file"
)
parser.add_argument(
"--ssl-certfile", default=None,
help="SSL certificate file"
)
args = parser.parse_args()
# Configure Python logging based on log level
# Update config with CLI override if provided
if args.log_level != config.log_level:
config = HindsightConfig(
database_url=config.database_url,
llm_provider=config.llm_provider,
llm_api_key=config.llm_api_key,
llm_model=config.llm_model,
llm_base_url=config.llm_base_url,
embeddings_provider=config.embeddings_provider,
embeddings_local_model=config.embeddings_local_model,
embeddings_tei_url=config.embeddings_tei_url,
reranker_provider=config.reranker_provider,
reranker_local_model=config.reranker_local_model,
reranker_tei_url=config.reranker_tei_url,
host=args.host,
port=args.port,
log_level=args.log_level,
mcp_enabled=config.mcp_enabled,
)
config.configure_logging()
# Register cleanup handlers
atexit.register(_cleanup)
signal.signal(signal.SIGINT, _signal_handler)
signal.signal(signal.SIGTERM, _signal_handler)
# Create MemoryEngine (reads configuration from environment)
_memory = MemoryEngine()
# Create FastAPI app
app = create_app(
memory=_memory,
http_api_enabled=True,
mcp_api_enabled=config.mcp_enabled,
mcp_mount_path="/mcp",
initialize_memory=True,
)
# Prepare uvicorn config
uvicorn_config = {
"app": app,
"host": args.host,
"port": args.port,
"log_level": args.log_level,
"access_log": args.access_log,
"proxy_headers": args.proxy_headers,
"ws": "wsproto", # Use wsproto instead of websockets to avoid deprecation warnings
}
# Add optional parameters if provided
if args.reload:
uvicorn_config["reload"] = True
if args.workers > 1:
uvicorn_config["workers"] = args.workers
if args.forwarded_allow_ips:
uvicorn_config["forwarded_allow_ips"] = args.forwarded_allow_ips
if args.ssl_keyfile:
uvicorn_config["ssl_keyfile"] = args.ssl_keyfile
if args.ssl_certfile:
uvicorn_config["ssl_certfile"] = args.ssl_certfile
print(f"\nStarting Hindsight API...")
print(f" URL: http://{args.host}:{args.port}")
print(f" Database: {config.database_url}")
print(f" LLM: {config.llm_provider} / {config.llm_model}")
print(f" Embeddings: {config.embeddings_provider}")
print(f" Reranker: {config.reranker_provider}")
if config.mcp_enabled:
print(f" MCP: enabled at /mcp")
print()
uvicorn.run(**uvicorn_config)
if __name__ == "__main__":
main()
+7 -7
View File
@@ -88,11 +88,11 @@ def run_migrations(database_url: str, script_location: Optional[str] = None) ->
try:
# Determine script location
if script_location is None:
# Default: use the alembic directory in the hindsight_api package
# This file is in: hindsight-api/hindsight_api/migrations.py
# Default location is: hindsight-api/alembic
package_root = Path(__file__).parent.parent
script_location = str(package_root / "alembic")
# Default: use the alembic directory inside the hindsight_api package
# This file is in: hindsight_api/migrations.py
# Alembic is in: hindsight_api/alembic/
package_dir = Path(__file__).parent
script_location = str(package_dir / "alembic")
script_path = Path(script_location)
if not script_path.exists():
@@ -162,8 +162,8 @@ def check_migration_status(database_url: Optional[str] = None, script_location:
# Get head revision from migration scripts
if script_location is None:
package_root = Path(__file__).parent.parent
script_location = str(package_root / "alembic")
package_dir = Path(__file__).parent
script_location = str(package_dir / "alembic")
script_path = Path(script_location)
if not script_path.exists():
+43
View File
@@ -0,0 +1,43 @@
"""
FastAPI server for Hindsight API.
This module provides the ASGI app for uvicorn import string usage:
uvicorn hindsight_api.server:app
For CLI usage, use the hindsight-api command instead.
"""
import os
import warnings
# Filter deprecation warnings from third-party libraries
warnings.filterwarnings("ignore", message="websockets.legacy is deprecated")
warnings.filterwarnings("ignore", message="websockets.server.WebSocketServerProtocol is deprecated")
from hindsight_api import MemoryEngine
from hindsight_api.api import create_app
from hindsight_api.config import get_config
# Disable tokenizers parallelism to avoid warnings
os.environ["TOKENIZERS_PARALLELISM"] = "false"
# Load configuration and configure logging
config = get_config()
config.configure_logging()
# Create app at module level (required for uvicorn import string)
# MemoryEngine reads configuration from environment variables automatically
_memory = MemoryEngine()
# Create unified app with both HTTP and optionally MCP
app = create_app(
memory=_memory,
http_api_enabled=True,
mcp_api_enabled=config.mcp_enabled,
mcp_mount_path="/mcp"
)
if __name__ == "__main__":
# When run directly, delegate to the CLI
from hindsight_api.main import main
main()
@@ -1,12 +0,0 @@
"""
Web interface for memory system.
Provides FastAPI app and visualization interface.
"""
from hindsight_api.api import create_app
# Note: Don't import app from .server here to avoid circular import warnings
# when running with `python -m hindsight_api.web.server`
# If you need the app, import it directly: from hindsight_api.web.server import app
__all__ = ["create_app"]
-109
View File
@@ -1,109 +0,0 @@
"""
FastAPI server for memory graph visualization and API.
Provides REST API endpoints for memory operations and serves
the interactive visualization interface.
"""
import warnings
# Filter deprecation warnings from third-party libraries
warnings.filterwarnings("ignore", message="websockets.legacy is deprecated")
warnings.filterwarnings("ignore", message="websockets.server.WebSocketServerProtocol is deprecated")
import logging
import os
import argparse
from hindsight_api import MemoryEngine
from hindsight_api.api import create_app
# Disable tokenizers parallelism to avoid warnings
os.environ["TOKENIZERS_PARALLELISM"] = "false"
# Create app at module level (required for uvicorn import string)
_memory = MemoryEngine(
db_url=os.getenv("HINDSIGHT_API_DATABASE_URL", "pg0"),
memory_llm_provider=os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq"),
memory_llm_api_key=os.getenv("HINDSIGHT_API_LLM_API_KEY"),
memory_llm_model=os.getenv("HINDSIGHT_API_LLM_MODEL", "openai/gpt-oss-120b"),
memory_llm_base_url=os.getenv("HINDSIGHT_API_LLM_BASE_URL") or None,
)
# Check if MCP should be enabled
mcp_enabled = os.getenv("HINDSIGHT_API_MCP_ENABLED", "true").lower() == "true"
# Create unified app with both HTTP and optionally MCP
app = create_app(
memory=_memory,
http_api_enabled=True,
mcp_api_enabled=mcp_enabled,
mcp_mount_path="/mcp"
)
if __name__ == "__main__":
import uvicorn
# Get log level from environment variable (default: info)
env_log_level = os.environ.get("HINDSIGHT_API_LOG_LEVEL", "info").lower()
if env_log_level not in ["critical", "error", "warning", "info", "debug", "trace"]:
env_log_level = "info"
# Parse CLI arguments
parser = argparse.ArgumentParser(description="Hindsight API Server")
parser.add_argument("--host", default="0.0.0.0", help="Host to bind to (default: 0.0.0.0)")
parser.add_argument("--port", type=int, default=8888, help="Port to bind to (default: 8888)")
parser.add_argument("--reload", action="store_true", help="Enable auto-reload on code changes")
parser.add_argument("--workers", type=int, default=1, help="Number of worker processes (default: 1)")
parser.add_argument("--log-level", default=env_log_level, choices=["critical", "error", "warning", "info", "debug", "trace"],
help=f"Log level (default: {env_log_level}, from HINDSIGHT_API_LOG_LEVEL)")
parser.add_argument("--access-log", action="store_true", help="Enable access log")
parser.add_argument("--no-access-log", dest="access_log", action="store_false", help="Disable access log")
parser.add_argument("--proxy-headers", action="store_true", help="Enable X-Forwarded-Proto, X-Forwarded-For headers")
parser.add_argument("--forwarded-allow-ips", default=None, help="Comma separated list of IPs to trust with proxy headers")
parser.add_argument("--ssl-keyfile", default=None, help="SSL key file")
parser.add_argument("--ssl-certfile", default=None, help="SSL certificate file")
parser.set_defaults(access_log=False)
args = parser.parse_args()
# Configure Python logging based on log level
log_level_map = {
"critical": logging.CRITICAL,
"error": logging.ERROR,
"warning": logging.WARNING,
"info": logging.INFO,
"debug": logging.DEBUG,
"trace": logging.DEBUG, # Python doesn't have TRACE, use DEBUG
}
logging.basicConfig(
level=log_level_map.get(args.log_level, logging.INFO),
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s"
)
logging.info(f"Starting Hindsight API on {args.host}:{args.port}")
app_ref = "hindsight_api.web.server:app"
# Prepare uvicorn config
uvicorn_config = {
"app": app_ref,
"host": args.host,
"port": args.port,
"reload": args.reload,
"workers": args.workers,
"log_level": args.log_level,
"access_log": args.access_log,
"proxy_headers": args.proxy_headers,
"ws": "wsproto", # Use wsproto instead of websockets to avoid deprecation warnings
}
# Add optional parameters if provided
if args.forwarded_allow_ips:
uvicorn_config["forwarded_allow_ips"] = args.forwarded_allow_ips
if args.ssl_keyfile:
uvicorn_config["ssl_keyfile"] = args.ssl_keyfile
if args.ssl_certfile:
uvicorn_config["ssl_certfile"] = args.ssl_certfile
uvicorn.run(**uvicorn_config)
+15 -1
View File
@@ -48,11 +48,25 @@ test = [
]
[project.scripts]
hindsight-api = "hindsight_api.cli:main"
hindsight-api = "hindsight_api.main:main"
[tool.hatch.build.targets.wheel]
packages = ["hindsight_api"]
[tool.hatch.build.targets.wheel.sources]
"hindsight_api" = "hindsight_api"
[tool.hatch.build.targets.sdist]
include = [
"hindsight_api/**/*",
]
[tool.hatch.build]
include = [
"hindsight_api/**/*.py",
"hindsight_api/alembic/**/*",
]
[tool.pytest.ini_options]
log_cli = true
log_cli_level = "INFO"
@@ -1,71 +0,0 @@
---
id: add-bank-background
title: "Add/merge memory bank background"
description: "Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits."
sidebar_label: "Add/merge memory bank background"
hide_title: true
hide_table_of_contents: true
api: eJzVV0tv2zgQ/isETwmg+pHuXgT0kLYBaiB9IEn3EhgFLY4kNnyoJGVba+i/L4aUbfqRdBHsZX2xLA6H33wz83G8oZ5VjuaP9D3TT47OM8rBFVY0XhhNc3rNOdGwIgtWPFXWtJoToUtjFUMDYixRYCsgK+FrAmvhvNDViNzefiZCe5BSVKC97IgFZ+QSHCmMLqUovMuIRj9S/A2OeENKYZ0nDVhndEaY5sQEFEzKDg8F6wgXrjFOhLO9ZcK7Ec2oacAGPDNOc8o4/7Fg+unHHjPNaMMsU+DBYrQbqpkCmtNgJ3BdYLQN8zXNqIVfrbDAae5tCxl1RQ2K0XxDfdfgNuet0BXNqBde4gtkj8w47ft53A7Ovze8wz3H3gqjPWiPS6xppCgC9PFPh4RvksMai4F5AQ5/JdueQ/FhMDlO4pfnE+gNYZzv8kj7jLYNZx5+JFQnZy6MkcB0cuj3YE4+JubH589KEkKPWTyTRFJao4ivIaLgKdoLDiVrpc+Dj8vgPLyIfPZ9tsVmFj+h8Af5e9zRNt8jvub8/c7/XUzWCebhPVGGgySlsciT0NUYEQpdPUMoliOsmWrwpCRpdEZWzJGFsZoITR5gzRw9z3WMqsfALLjGaBcL4Goywa9DmPdtUYBzZSvJ3WBMX11iScO8WOs7qz6jR2XCdPe1DB126No9QeNFIZxKXKNCVGBpRhVbC9Uqmv+ZUSV0fJ7uz7zfbz9O1CezIoN3JsnSYZkEFSIX03fb54z8+W5ndIm4pfBgmXwtoNv99nOABu+ywwZDr7ax4A8672L6rpSwFgsJiG7YEbCBQiHqXgXsZth7DpVqixoBFUY7wcESUCYqLAkVs/aIioNnRQ0cUUUk4EVxSX/XaS7NkUz52caT9GAiFw9BAk4AfzxVCV+zwKFsQRdAagwJlLECHGEWsEsV8HB17DgHftSSO3LfHhbB2+ygSN/2fbajX7dS0n7+OwaS/pmf65ekQ4/FJi4kapPISxSJozDSXj0nLiMyI0wRRpwp/QrZAV0JDWDjXT2dkA6YdcSUBNYNWIGc4iFHHf3v+Yqa9cfV1alM/cWk4LHub6w19vUahdUpJD4JD8qdGkhTHKzuFelQ0JL0brurn+8TzKxlXaJ6tyYCxP5UrnpJID+DcyzepdHkedNABnnA1d8VF8YVjx7skhLb0xvZfT6Mj5G+c4dtTT49PHw7cRhzq8DXBguuMeHKDPNSTsfL6Xi4lMc4UbnxZhis+vHBEIbJvdtPRzf/wUWJk1tpAsdb/EJzJ6raE4yEXH+bnYrhsBA6bWc/FCUrQlEOE+JnFJiO3HfOg4oXRwHYw3uT6wb1klyNJgjUSprT2vvG5ePxarUasbA8MrYaD3vd+Hb24ebL/c2bq9FkVHsl0fESrIvwpqPJaIKvkGbFdHoW5+M4casIDIkmByQfhJoy+7+Y5YeqxMto3EgmQsMFUjdDuT3S5TSZArMwxGON5Ptp/lCJa6zW/JFuNgvm4LuVfY+vf7VgO5o/zjO6ZFawBZbP4wYFEJ85zUsmHbzA6MXd0KCX5Dno2z7U2IVLJlv8RTP6BF3y/yMoTw2Mgw0Q4uowz78J+rDffSKXKGVxx3VRQONftJ0nbfzt6/0DsjX8U8Hbh+bUshVqD1tFpDFzQUvDuw2VTFctKlxOo0/8/APsnf3O
sidebar_class_name: "post api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Add/merge memory bank background"}
>
</Heading>
<MethodEndpoint
method={"post"}
path={"/v1/default/banks/{bank_id}/background"}
context={"endpoint"}
>
</MethodEndpoint>
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={{"required":true,"content":{"application/json":{"schema":{"properties":{"content":{"type":"string","title":"Content","description":"New background information to add or merge"},"update_disposition":{"type":"boolean","title":"Update Disposition","description":"If true, infer disposition traits from the merged background (default: true)","default":true}},"type":"object","required":["content"],"title":"AddBackgroundRequest","description":"Request model for adding/merging background information.","example":{"content":"I was born in Texas","update_disposition":true}}}}}}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"background":{"type":"string","title":"Background"},"disposition":{"anyOf":[{"properties":{"skepticism":{"type":"integer","maximum":5,"minimum":1,"title":"Skepticism","description":"How skeptical vs trusting (1=trusting, 5=skeptical)"},"literalism":{"type":"integer","maximum":5,"minimum":1,"title":"Literalism","description":"How literally to interpret information (1=flexible, 5=literal)"},"empathy":{"type":"integer","maximum":5,"minimum":1,"title":"Empathy","description":"How much to consider emotional context (1=detached, 5=empathetic)"}},"type":"object","required":["skepticism","literalism","empathy"],"title":"DispositionTraits","description":"Disposition traits that influence how memories are formed and interpreted.","example":{"empathy":3,"literalism":3,"skepticism":3}},{"type":"null"}]}},"type":"object","required":["background"],"title":"BackgroundResponse","description":"Response model for background update.","example":{"background":"I was born in Texas. I am a software engineer with 10 years of experience.","disposition":{"empathy":3,"literalism":3,"skepticism":3}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: cancel-operation
title: "Cancel a pending async operation"
description: "Cancel a pending async operation by removing it from the queue"
sidebar_label: "Cancel a pending async operation"
hide_title: true
hide_table_of_contents: true
api: eJy9VEtv2zAM/isCTxugxWmwk29dG2AB2rVYs12CoFBkxlYrS64kpzMM/fdBsmMnzdph2LCTZT4+kh8fLTiWW0hXcFOhYU5oZWFNIUPLjajCP6RwwRRHSRipUGVC5YTZRnGi9y5k0xCDpd4FnXBka3RJXIHkqcYagcJgucggBR7h7gchUKiYYSU6NCGXFhQrEVLYMPV4LzKgIEIaFXMFUDD4VAuDGaTO1EjB8gJLBmkLrqmCm3VGqBwoOOFkEHxi6pEsMvCeDthD9H8RYCCvi7IOGLbSyqINbrPpNHyOSb2rOUdrt7UkX3tjoMC1cqhcMGdVJQWPsMmDDT7tmIr33lP4OJudAn9nUmRdNnNjtPkDVKhM4MWJLu8MHRMyvITD0p4aSM2PtEw1N9vYwWOmAu+9RCiHORrwa0/3MmYMaw7ovNJdguAplDZ/i/lrtJblCAPY66aRDLIMWj/G1psH5O6o66tYVxe6t1uPMCO9Hbuvl3HZ0ferYHuTz8vl7Qlg19sSXaHDumQo0WFcEldACsnuLMlwy2rpkrAhNmn7RfHJMNU2aQ8n3McR3+rIzz62UJkVeeFIyIKc3y7g5eLvFWSrDRns+4FiPA5Uv0/XWGrTkLvGOiwDKVJwDDM9mpxXjBdIZpMpUKiNhBQK5yqbJsnz8/OERfVEmzzpfW1ytbiYf7mbf5hNppPClTIA79DYLr2zyXQyDaJKW1cydRDrdyfrZantuCN/f+76bjv84ZJKMhEHORbc9k1cwe4sphDbCDSeOgsU0vHmjb0M8qN7taZQaOsCTttumMVvRnofxE81mgbS1ZrCjhnBNqHVqxYyYcM7g3TLpMU3qn/3tV+E9+S1UvbzrsK075iswx9QeMTm4GqHpf+PYY8IitelQJahieV3JuecY+UOnE+OYTjdw+Jdzq/myzl4/xMJp2+z
sidebar_class_name: "delete api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Cancel a pending async operation"}
>
</Heading>
<MethodEndpoint
method={"delete"}
path={"/v1/default/banks/{bank_id}/operations/{operation_id}"}
context={"endpoint"}
>
</MethodEndpoint>
Cancel a pending async operation by removing it from the queue
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"operation_id","in":"path","required":true,"schema":{"type":"string","title":"Operation Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: clear-bank-memories
title: "Clear memory bank memories"
description: "Delete memory units for a memory bank. Optionally filter by type (world, experience, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (disposition and background) will be preserved."
sidebar_label: "Clear memory bank memories"
hide_title: true
hide_table_of_contents: true
api: eJzlVU1v2zgQ/SvEnBJAKznGnnTLNgY2QLotGu9egqCgyZHFhiJZcmRHMPTfF6QkW4abdrfY2/oig5zP9x5nDkB8G6B8gvfYWN/BcwYSg/DKkbIGSrhDjYSsSdesNYoCq6xnfDracPOSsw/JnmvdsUppQs82HaPOIbvaW69lxvDVoVdoBGbMOmWUNdeMLJNDAmt0x4JDoSolkmfI2bpWganAOJMYyLeC1A6Zdeh5TMeo5sQEN8YS2yBrjbQGoxumspjztlIa2ZVUwdmgkhM3km24eNl62xp5zfZK6+jtPAb0O5Q5ZHDMcS+hBKGR+88x5OfUtcIAGTjueYOEPgJ4AMMbhBKSlZKQgYr4OU41ZODxa6s8SijJt5hBEDU2HMoDxFahhEBemS1kQIp0PPgtNnAvoe+zY+xkOwb+2qLvziJXXIez0Nx0H6pU23mSGHE8Ma3W0F+wPtHJKi5o4HGk9Xt0zqpfx/D9fxQ21ucxOGsChtjYcrGIn/Pgj60QGELVavZpNIYMhDWEhhIczmklEqvFlxB9DjOwnI+ckxoyhCHYjKCNtRq5mfU4JowMTUZ28wUFnbHydIz1fHIdXtWszPNWpgvWWIk6vbfpmUy6DFGl+MobFwPOCo766uMvg1+Xy0uY/uJayeH5rLy3/ucxkkhc6fhPETbh0kBbcXb7D/SoDOEWPfTPJ1C597yb4f5ghwKjvpqw/d4jeo8h8G1S4mDytmkCgw26/QGhsa8h9Wg3Y/YE74Du223cDfB9K9lk8vt6/fEi4MBtg1TbOJsGYaRxRDWUUOxuCokVbzUVcRaF4jCOpL6YDS9lKpvgmFIpI4Pa1sRiUnb78f5CldNF0uPRftQPF0k/46Aatgl77AJhEzHQSmBU+snk1nFRI1vmC8ig9RpKqIlcKItiv9/nPF3n1m+L0TcUD/fvVn88rn5Z5ou8pkbHwDv0YSjvJl/ki3jkbKCGm1mud3F+zxcWmyFx1uTh9Bj+r6tvFCPhKxVOc5XeWSLoMGrsCXY3CbikMsjSzotQlqfldwT4OYPaBopeh8OGB/zT676Px8MGi+NAqsA3erbD3uTk5xfTt7p6we60VXdct9EkrZsd9yqW9C/Lu/o0jolr9lbOaRqYbp5zqmUCMM2/GrlEn0oYbm+FQEczv4txHWs/joa71cNqvYK+/xsQCGzg
sidebar_class_name: "delete api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Clear memory bank memories"}
>
</Heading>
<MethodEndpoint
method={"delete"}
path={"/v1/default/banks/{bank_id}/memories"}
context={"endpoint"}
>
</MethodEndpoint>
Delete memory units for a memory bank. Optionally filter by type (world, experience, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (disposition and background) will be preserved.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional fact type filter (world, experience, opinion)","title":"Type"},"description":"Optional fact type filter (world, experience, opinion)"}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"DeleteResponse","description":"Response model for delete operations.","example":{"success":true}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: create-or-update-bank
title: "Create or update memory bank"
description: "Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults."
sidebar_label: "Create or update memory bank"
hide_title: true
hide_table_of_contents: true
api: eJztV01v2zgQ/SvEnBpA8Ve2FwE9JGmABki7QZLuJTACWhpJbChSJSk7huD/vhhStqQ4zmaDBXYXqC+WyRnyzdObR7MBx3ML8T2ccfVoYR5BijYxonJCK4jh3CB3yDhTuGI8R+WYNqyuUhrFJ2GdUHk7sRKuYKmwlbaC0hlXKVvw5DE3ulbpiJ3WTh9nQkrLSmEtZWYCZWrbVMx4LZ0dQQS6QsNpkcsUYkg8igdtHsLODwuuHiGCihteokNDJTSgeIkQA00+iBQiEFRCxV0BERj8WQuDKcTO1BiBTQosOcQNuHVFadYZoXKIwAknaYAoYZcpbDbzkI7Wnel0TTnPV0u0cqgcTfGqkiLx4Mc/LLHY9DarDJXmBFr6FRA3wNX698zXMASziXYjqpYSCMkW3jfK3UTQY3y41HAr+4iVE4mwZa9moRzmaCCCkj+Jsi4h/hhBKVR4nna73XbpzzXyRa9YuzqXbGmZM3XQxYfpp+1zxD5+2gUdEW4pHBou3wvoqkt/CVC7ulwzpxmtaiqDjgmVaVP6l0PoMolPYiGR0LUZHhuWpJr1u4BdtLkvoSrrpCBAiVZWpGgYlpqmuWReQU+OUKXoeFJgSqgCEnQiOYLNJtrC0YsfmLiBrO/7r3hAb1dPTz6fO9ncGS6c3QPci2DOhzBXcM+hrFElyAoqCUttBFrGDTIiF1Pf+DvOMaWGxideVtKLfUfuyVAEJ9FApCebffVvIugM5b2Nc9at8BKj27BgfWQCN6H39whqx1mpU5RUO/NGJVQ+9j7lrZGRHT1joF8DXDJeMt6mLpFZnbkVkYkqFwrRBHecTtgaubFMZwyfKjSCXgHs9f+b2Y22fnkqRYKwoQ/pyVZa2eAZs8mEvoZV39ZJgtZmtWQ3bTC82wC3Xv0WG452dnko9IAl/jLCX0b4PzfCZ7Z3uFdetbY+R92/JN9Vw6YZ7Dcf9uK10ZmQ2Ov9564YJnq2SHuxKuS9wQr/lgMyoZh13Li6sh53ayhQWzTT2ck/7pC/zWb7pvgHlyIN3XRhjDbvd0TSvJD0JByWdj9A6mQw+4YjcNuz/gBtx7gxfN2TzpUOAKnrS5u/prKvaC3PvdOGkMOhngx2R7N/JUiqK2zdxvV019Eb2D1cxudA32sH+5e7u+u9BcO7LdEVmsRT1c7fL1wBMYyX03F7ORmTvuy4aWW2gQjohd50t4OL//gxT7eiTPt3tuVDqNSKvHCMmGGn15f7lt1O+G7exbci54nr7jLwlWxwzW7X1mEZjrcEySe6kNOKXJ3NRhOIoDYSYiicq2w8Hq9WqxH30yNt8nGba8dXl+cX324vjmejyahwpaSFl2hsgDcdTUYTGqq0dSVXvb3aC2x3aS0DvvYGOSiz6Xr2X7v4tqKlE3BcSS58P3qOmlaO97CceuQ+qbU8sr54633zCAptHYU2zYJb/G7kZkPDP2s0a4jv5xEsuRF8QQK4b0hc9JxCnHFp8RVePty0LXvEDqHddqaivlxyWdMviOAR173bufeiAnmKxkMIs+dho2PvGF32noGSuYWM0yTByr0aO+819vX3O6KsvcbTEQUxGL4iM+KrAFT7ur25+rEGJFd5TZYXQ1iSPn8Cfqb3jQ==
sidebar_class_name: "put api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Create or update memory bank"}
>
</Heading>
<MethodEndpoint
method={"put"}
path={"/v1/default/banks/{bank_id}"}
context={"endpoint"}
>
</MethodEndpoint>
Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={{"required":true,"content":{"application/json":{"schema":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"disposition":{"anyOf":[{"properties":{"skepticism":{"type":"integer","maximum":5,"minimum":1,"title":"Skepticism","description":"How skeptical vs trusting (1=trusting, 5=skeptical)"},"literalism":{"type":"integer","maximum":5,"minimum":1,"title":"Literalism","description":"How literally to interpret information (1=flexible, 5=literal)"},"empathy":{"type":"integer","maximum":5,"minimum":1,"title":"Empathy","description":"How much to consider emotional context (1=detached, 5=empathetic)"}},"type":"object","required":["skepticism","literalism","empathy"],"title":"DispositionTraits","description":"Disposition traits that influence how memories are formed and interpreted.","example":{"empathy":3,"literalism":3,"skepticism":3}},{"type":"null"}]},"background":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Background"}},"type":"object","title":"CreateBankRequest","description":"Request model for creating/updating a bank.","example":{"background":"I am a creative software engineer with 10 years of experience","disposition":{"empathy":3,"literalism":3,"skepticism":3},"name":"Alice"}}}}}}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"bank_id":{"type":"string","title":"Bank Id"},"name":{"type":"string","title":"Name"},"disposition":{"properties":{"skepticism":{"type":"integer","maximum":5,"minimum":1,"title":"Skepticism","description":"How skeptical vs trusting (1=trusting, 5=skeptical)"},"literalism":{"type":"integer","maximum":5,"minimum":1,"title":"Literalism","description":"How literally to interpret information (1=flexible, 5=literal)"},"empathy":{"type":"integer","maximum":5,"minimum":1,"title":"Empathy","description":"How much to consider emotional context (1=detached, 5=empathetic)"}},"type":"object","required":["skepticism","literalism","empathy"],"title":"DispositionTraits","description":"Disposition traits that influence how memories are formed and interpreted.","example":{"empathy":3,"literalism":3,"skepticism":3}},"background":{"type":"string","title":"Background"}},"type":"object","required":["bank_id","name","disposition","background"],"title":"BankProfileResponse","description":"Response model for bank profile.","example":{"background":"I am a software engineer with 10 years of experience in startups","bank_id":"user123","disposition":{"empathy":3,"literalism":3,"skepticism":3},"name":"Alice"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,78 +0,0 @@
---
id: delete-document
title: "Delete a document"
description: "Delete a document and all its associated memory units and links."
sidebar_label: "Delete a document"
hide_title: true
hide_table_of_contents: true
api: eJztVU2P2zgM/SsCTy2gxpmgJ99mdwJ0gOm26KS9ZIKCkZlYHVlyJTppYPi/LyTb+Wh2Ciyw6GlPtinykXp8pFtg3AbIl3DnVFOR5QArCQUF5XXN2lnI4Y4MMQkUxeAj0BYCjRGag8AQnNLIVIiKKucPorHJbgthtH0Okyf7ZBelDmKvjREKg8KCRJFQ8yf7RixKOmFrDmQ20XxrzCUk/WCPKmbaeFcJjphj3BiQUopXTFXtPBopAlVoWSspyLLmw+vziveaS8GlC3SR6Vixq8ljpEEotNaxWJNobOEsTUDC8fS+gBz6C30dCwIJNXqsiMlHhluwWBHksEb7/FUXIEFHdmvkEiR4+t5oTwXk7BuSEFRJFULeAh/qGBbYa7sFCazZRMMfaJ/FfQFdJ4/YY/L/An9URJ9jFSFC7WygEKNm02l8XCrlsVGKQtg0RnwanEGCcpYjIXkLWNdGq8RZ9i3EmPZUSdd1nYS3s9k18Bc0uugbMffe+X+BCrWPfWLd110QozbxTTNV4drBOHVxivbwYZP6d0lUZH2waMu0JQ/dqpOjDb3HwxmbD64vEDoJVdj+ivj3FAJuCY5gL7smMsQinnan3G79jRRfNH2Z7tWnHvxWJ5gTvT27L1/jrqfvn5KNLu8Wi49XgH1vK+LSnWYljQiXkEO2u8kK2mBjOIvzEbJ2GJMuGzUdsvZM3l3S98YldsbM2hZBb0sWsQZx+/Eeft5l44HYOC+O/oOcUCU5DbP0vl8Ij4fAVEVKjFYUFX1yua1RlSRmkylIaLyBHErmOuRZtt/vJ5iOJ85vsyE2ZA/3f87/epy/mU2mk5IrE4F35ENf3s1kOplGU+0CV2jPcl1t4Z/v1p5G4v+V/dLKHkTL9IOz2qBO85g61w5aXMLuJlGb1Agy7esAEvLT4j5KMprPd+5KQukCR5S2XWOgz950XTR/b8gfIF+uJOzQa1xHxS5bKHSI7wXkGzSBftHTV5+GaX4tXrrIOLQ2juwOTRO/QMIzHc5+PHFz/ca05/ykDVkSFuTT7XuPW6Wo5rPYq4Uefz/H5XE3f5gv5tB1fwPJKQVj
sidebar_class_name: "delete api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Delete a document"}
>
</Heading>
<MethodEndpoint
method={"delete"}
path={"/v1/default/banks/{bank_id}/documents/{document_id}"}
context={"endpoint"}
>
</MethodEndpoint>
Delete a document and all its associated memory units and links.
This will cascade delete:
- The document itself
- All memory units extracted from this document
- All links (temporal, semantic, entity) associated with those memory units
This operation cannot be undone.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: get-agent-stats
title: "Get statistics for memory bank"
description: "Get statistics about nodes and links for a specific agent"
sidebar_label: "Get statistics for memory bank"
hide_title: true
hide_table_of_contents: true
api: eJylVE1v2zAM/SsCTxugxWmwk2/dVnQB2q1Yu12CoGBsxlZjS65IpwsM//dBspP0Yy0w7BSHn4+PT+xAsGBIF/AJ7YZhqSEnzrxpxDgLKZyTKBYUw2IyVrhyrSjrcmKFNleVsRtWa+cVKm4oM2uTKSzICmhwDXkMdeY5pFCQ3EbPbajHoKFBjzUJ+QCgA4s1QQortJtbk4MGEwA0KCVo8HTfGk85pOJb0sBZSTVC2oHsmpDG4o0tQIMYqYIhDKTmOfT9MqRz4ywTh4zZdBp+ng563WYZMa/bSv0Yg0FD5qyEYdIOsGkqk8V5kjsOOd0RRd/3vYaPs9nLwr+wMnlMU2feO/8PVaHxgUMxA+6cBE0VvoxQzS8DKpc98aLdfV9Hbp+S1OuDxVihgjz0y17vbeg97h4xeeEGgNBrqLl4i/RLYsaC4FDs9dBIhroJ3v7Y263uKJMnC1/EuYbWY9zyWOZI78Du62N8Gej7W7N9yNebm6sXBYfd1iSlG3UctSslpJBsT5Kc1thWkgThctKN+u2TvcyNXbtIxL6JsTmbohQV2qnTqzk8f3V7R3xZh/hROZhF5YzP5ZJq53fqesdCdZi+MhkF8R5DThvMSlKzyRQ0tL6CFEqRhtMkeXh4mGB0T5wvkjGXk4v557Nv12cfZpPppJS6CoW35HmAdzKZTqbB1DiWGu2jXs/uRcBfDwgDL88H7Y5P4b8uzbhPod+SNBWaKNU4aTduagHbk9g97gp0PDNhO+nx3gwLW2ooHUtI6boVMv30Vd8H831LfgfpYqlhi97gKqxz0UFuOHznkK6xYnpjxnc/RlW/V6+h3ovXBulusWrDP9Cwod2j4xifa0mYk48QBu9pllEjj/JeXJdwCw9KPj+7gb7/Ax/bCsc=
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get statistics for memory bank"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/stats"}
context={"endpoint"}
>
</MethodEndpoint>
Get statistics about nodes and links for a specific agent
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: get-bank-profile
title: "Get memory bank profile"
description: "Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists."
sidebar_label: "Get memory bank profile"
hide_title: true
hide_table_of_contents: true
api: eJy9Vk1v2zgQ/SvEnBpA9Ve2FwE9ZDdBGyDtFk12L4FR0NJYYsMPlRzZMQz998VQsiXVSVrksLlEFmc4bx7fPGoPJIsA6T38Ke1DgGUCOYbMq4qUs5DCBySRq1C5oPiNIC8VBSFtLlYyeyi8q20u1s4LKQwa53diJe3DRFzU5N5mHiVhELJAS2KrqBQ5rmWtKQi1FtaRwEcVKEwgAVehl1zkOocUCqRvvNO3yru10ggJVNJLg4SeAe/BSoOQQgxSOSSgGHAlqYQEPP6olcccUvI1JhCyEo2EdA+0qzgtkFe2gARIkeYXTIC4zqFplpweKmcDBs5YzGb8b0zMbZ1lGMK61uJrFwwJZM4SWuJwWVVaZbGh6ffAOfsBispzu6TaCocefgde0jX+fOhnXm8SGJzbacnwgBWpTAUz2EpZwgI9JGDkozK1gfRdAkbZ9nne17jt03+WzEe3Fd3uUotNEOTrQMoW4s38/eE5Ee/eH4POGK1WhF7q1wK66dOfAtTtrneCnOBdfeWRhLJr5008JEa31vioVhoZXZcRsaFhWe1eBeyqy30KlamzkgFlzgaVoxdoHC9LLaKSHolR5UgyKzFnVC0SJJWdQdMkBzhu9R0zGun+fnjEI3r7fpY9zMteLHdxxk8AX57aAJUycqhrtBmKkltiE1A88x7ZFwzm0S2OnGPOw46P0lQ6yvhI7vlYBOfJSKTn3G7vOS/PyjHqVxz17hGnajw0o3rL8Sx+aW1pMPtjtg4LwrgcdXRIriU6O/uJg2FfcC2kEVIEt6Yts4i2UBbRtwY6n4kdSh+EWwt8rNCryL2yIpD0VFch4u4MBeqAfr44hxM7+G3aD4YDF1plCA3/JfDHYnFqiv9KrfJ2mq68d/71jsiaV5qfFKEJpwHaZaNVaXd/r+O9MFZFk5zMbLPsRSG9l7uBdG5cC5Cn3oTiJZV9whBkEZ22DXk+NJIh7nj1V4LkvtrSXdxAdz29LbvPt3HZ0vdUsUPIx7u7LycbtmdrkErXXcLx3qUSUphu5tPu9p6yvsJ038msmfaXNDtqpOJQRtk8qKIkwQXFxZfrUyfsFuKQHOM77cgsaqeT4Kf2E+N2FwhNe2tkyOPXh1xUbJZiMZlBArXXkEJJVIV0Ot1utxMZlyfOF9MuN0xvrv+6+nx79XYxmU1KMpo33qAPLbz5ZDaZ8avKBTLSDmrx19Hgq0f0NIw63PdT8H9+UHUnz9fItNJSRVFHRvbdmd7DZh7Bxi0632D/SHtfPPS0TKB0gThpv1/JgP943TT8+keNfgfp/TKBjfRKrvjg7/dsOPycQ7qWOuALpLz52k3AmXgO90HolmW+kbrmX5DAA+4GH4FxtEuUOfoIoV29yDKsaJB34kT8zXdU/YerO2ia/wA/btIS
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get memory bank profile"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/profile"}
context={"endpoint"}
>
</MethodEndpoint>
Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"bank_id":{"type":"string","title":"Bank Id"},"name":{"type":"string","title":"Name"},"disposition":{"properties":{"skepticism":{"type":"integer","maximum":5,"minimum":1,"title":"Skepticism","description":"How skeptical vs trusting (1=trusting, 5=skeptical)"},"literalism":{"type":"integer","maximum":5,"minimum":1,"title":"Literalism","description":"How literally to interpret information (1=flexible, 5=literal)"},"empathy":{"type":"integer","maximum":5,"minimum":1,"title":"Empathy","description":"How much to consider emotional context (1=detached, 5=empathetic)"}},"type":"object","required":["skepticism","literalism","empathy"],"title":"DispositionTraits","description":"Disposition traits that influence how memories are formed and interpreted.","example":{"empathy":3,"literalism":3,"skepticism":3}},"background":{"type":"string","title":"Background"}},"type":"object","required":["bank_id","name","disposition","background"],"title":"BankProfileResponse","description":"Response model for bank profile.","example":{"background":"I am a software engineer with 10 years of experience in startups","bank_id":"user123","disposition":{"empathy":3,"literalism":3,"skepticism":3},"name":"Alice"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: get-chunk
title: "Get chunk details"
description: "Get a specific chunk by its ID"
sidebar_label: "Get chunk details"
hide_title: true
hide_table_of_contents: true
api: eJydVU2P20YM/SsDnhpAK8lOetFtm11sDSRtkHV7qGEYY4myJpE0ypDyriHovxcz+rC07q6D+mJp+Dh8JB+pBlgeCKIN3Om4LrBkgq0HCVJsVMVKlxDBA7KQgiqMVapiEWd1+V3sT0IxidUdeKArNNKCVwlEcEDeOQx4UEkjC2Q0NkYDpSwQInDWnUrAA2UDVJIz8MDgj1oZTCBiU6MHFGdYSIga4FNl/YiNKg/gASvO7cFHR2WVQNturT9VuiQk67IMQ/s3z+SxjmMkSutcfO3B4EGsS8aSLVxWVa5il0vwjaxPM6FRGZspqy7CmMVPEfQg6St8xWVoRO+1l1eD/CbHGD2nMsHniYcqGQ9oLnk53OjG+MzXk1lblPUxKBmTnXzbp0OJW4a29QaY3n/DmGct30xVMS3VuQTz9GasZ3S2LyhPWj2Xw2AQhU4wF6k24oDcCxzLpNKqZB88wGdZVPbC5twPqAnNYvn+TGtyuCMkUrrcLXbhC95ROK83rDNFQpHgDEWqDA0EdOqOhlr4vj9PM4JluPxwEy5uFr+uF2H0PozC8J8X1YtgZAKt/XnwYbm8nIy/Za4Sp3txb4w2/38sEmSpcvukGAu6BOQ6nlllefozdethLqLWuxBwuz1rSBojTxOlfdIdQavNgg5vifIzEskDwnjZ61BXDLG21mv6tXl1oXvcRIfn8nbVfT2Nu658/xVsgPy+Xn+5uLDrbYGc6X4Ju/XLGUQQHBdBgqmscw6ctihoBs22bgmn2hVhCKDKhNQhY2FDidsvq4vRGQxuaEZ8rxoZO9X02/4zFtqcxOOJGAubea5itON4htxWMs5QLH07LLXJIYKMuaIoCJ6ennzpzL42h6D3peDT6uP9H4/3N0s/9DMucnvxEQ119BZ+6If2qNLEhSwnsR7GCe+USi9za87Kv/7p63tkRzmocqmc/FwGTV/9DRwXLoSr/7AMbNRo3BtbDzJNbMFNs5eEf5m8be3xjxrNCaLN1oOjNErubYM2DSSK7HMCUSpzwjdS+OVrr9F34jW+gxRLK8SjzGv7Bh58x9P0a+2mL0OZoHEcOvNtHGPFE8eLZWG/zaMwH+7X0Lb/AoXB258=
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get chunk details"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/chunks/{chunk_id}"}
context={"endpoint"}
>
</MethodEndpoint>
Get a specific chunk by its ID
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"chunk_id","in":"path","required":true,"schema":{"type":"string","title":"Chunk Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"chunk_id":{"type":"string","title":"Chunk Id"},"document_id":{"type":"string","title":"Document Id"},"bank_id":{"type":"string","title":"Bank Id"},"chunk_index":{"type":"integer","title":"Chunk Index"},"chunk_text":{"type":"string","title":"Chunk Text"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["chunk_id","document_id","bank_id","chunk_index","chunk_text","created_at"],"title":"ChunkResponse","description":"Response model for get chunk endpoint.","example":{"bank_id":"user123","chunk_id":"user123_session_1_0","chunk_index":0,"chunk_text":"This is the first chunk of the document...","created_at":"2024-01-15T10:30:00Z","document_id":"session_1"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: get-document
title: "Get document details"
description: "Get a specific document including its original text"
sidebar_label: "Get document details"
hide_title: true
hide_table_of_contents: true
api: eJy9Vk1v2zgQ/SvEnHYBRZLd9qJbNs2mAdpt0Th7WMMwaGkssaFIlaScGoL+ezGUZMlx4g2Kxfoii3zz9eYNqQYczy0kS3iv07pE5SysAsjQpkZUTmgFCdygY5zZClOxFSnLeiQTKpV1JlTOhLNMG5ELxSVz+MNBALpCw8nDbQYJ5OjWgyEEUHHDS3RoKHYDipcICWy4eliLDAIQFLfiroAADH6vhcEMEmdqDMCmBZYckgbcviIz64xQOQTghJO08AdXD+w2g7YNDr6H4P+F/4GrLsaKXNhKK4uWrOZxTI9jDu/qNEVrt7VkX3swBJBq5YiQpAFeVVKknrDomyWbZpJJZYhOJ7oIIjuXHSUVHLh8DU0BDM1b++adsfk8dHlBwPZQwrrgtvB1qP3nrW/qsQtqRb+iaimBaBucXnU+2AfyQT4NcofZmp9N5apDsUufR11lr7C571C9TYmlNvt1rYRbp7pWU1OhHOZoJrafPJrdK+HYlUe3bTDA9eYbpu5ITUvwUhtFfUzyE+qOqj4q57k8V6dinMjqWHrDBit1hpJttWE5unGMUWWVFsqFEAD+4GVFbptRQFBbNLP5m6cZJ8A3ab8+aRjM4/nbi3h2MXu3mMXJmziJ439o5MiVRWuFVuvZs1Uls3cnUoQ/aynHZGmRFWgwDMNjml4I3NIvgLfz+elQ/s2lyPzIsWtjtPn1iczQcSH9bDos7SlA6vRo9xVjMiiwXY0y48bw/USTH3WXoFezzc9J/xNay3OEg7OXoZ4MtqDdf5M41dWF7nETZY70duy+XMb7jr7ngg2QD4vFlxOHXW9LdIXuLxl/tzgSZ7SbRRlueS1dRFq2UdNLuo0GOdmomdwLrb8YttpTM4QVKrMiLxyjBNjll9uT+Ro2/GQd8L2WeOq11F9C/RFyt7cOS+JDihRpZkfIZcXTAtk8jEneRkIChXOVTaLo8fEx5H471CaPelsbfby9uv7r7vpiHsZh4UpJjndobJfeLIzDmJYqbV3J1STWzfQY6CRsn5bXjCPxix8CfUfpLaokF16svrKm79USdjMf13erPzMpk2Q8PA8to+XpZb4KoNDWkZem2XCL90a2LS1/r9HsIVmuAthxI/iGOrpsIBOW/meQbLm0eKbg3772Uv+dvVTIoGhFet5xWdMbBPCA+8kXDY31/xh2yo8/PgrkGRpffYe4TFOs3MT25LSjC/owWTfXC2jbn+gTcts=
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get document details"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/documents/{document_id}"}
context={"endpoint"}
>
</MethodEndpoint>
Get a specific document including its original text
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"id":{"type":"string","title":"Id"},"bank_id":{"type":"string","title":"Bank Id"},"original_text":{"type":"string","title":"Original Text"},"content_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Hash"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"memory_unit_count":{"type":"integer","title":"Memory Unit Count"}},"type":"object","required":["id","bank_id","original_text","content_hash","created_at","updated_at","memory_unit_count"],"title":"DocumentResponse","description":"Response model for get document endpoint.","example":{"bank_id":"user123","content_hash":"abc123","created_at":"2024-01-15T10:30:00Z","id":"session_1","memory_unit_count":15,"original_text":"Full document text here...","updated_at":"2024-01-15T10:30:00Z"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: get-entity
title: "Get entity details"
description: "Get detailed information about an entity including observations (mental model)."
sidebar_label: "Get entity details"
hide_title: true
hide_table_of_contents: true
api: eJy9Vl1v2zYU/SvEfWoB2ZIcJ930lmVelqFpgsbbwwzDoKVrm41EqiTl1BD034tLSbEsz+7QffjFNnl57tc5lyzB8rWBaAYTaYUVaGDuQYIm1iK3QkmI4BYtS9BykWLChFwpnXHaYnypCsu4ZEhnd0zIOC0SIddMLQ3qrbMy7E2G0vKUZSrB9O0QPFA5ard5l0AEa7SLGgE8yLnmGVrUFFQJkmcIESy5fF6IBDwQFFHO7QY80Pi5EBoTiKwu0AMTbzDjEJVgdzkdM1YLuQYPrLApLfzE5TO7S6CqvFfs2vW/gT6py+Dw5wRgciUNGjozCgL6OqzsUxHHaMyqSNnHxhg8iJW0KC2Z8zxPRexK5X8ydKbsxJFrKqRrWlSCSM7FRkF5EHOppIh5uqiTP21/01qyD2RZeUBdFEouYlXUwTVHhbS4Rt05e19bshtnWXmwEtrYhUF0CXC5e1i57h46p540K7JIU6AatpC/EAJ7IoTKg5T/Q7j3vIOWoeUJt/wQjCeJoCx4+tgpc02FBlYtP2Fszzq6b7ErD7qicA2zmJnjPlr8Ys91Zkr7+35gsuD2e+tw32Kwa0ui6GXWFcGsDmzep/vDPqsOhw95fi27E6E/N4awd8y15rtOsg/dmn0rQCfhHsX7vO214Sidn92gO5lJu1EPM7ZSuh1+9YRkKJNcCWlpzOEXnuWpk1lfePCb2kg4VAaMgtF4EISD8HIaBtFFEAXBnzSUaEiGowscX169G+APPy4H4Si5GPDx5dVgPLq6Csfhu3EQBHCgjAZuNAjCaTiOghaup+Pwss/MWdnj1qnAaqa6VNiL0s+GcctulVqnCNW8oo8H49HoePD9wVOR1GSYaK3090+9uuxn5JSq+GD3b8iknWjV/DQx36s6QKdEsz4n2Hs0hq9xz/IzNwgVg01p91tkp7xq141dh8r78tbVPZ1GTfe/dNaa/DqdPh4B1r3N0G5Uc4W7u9tuIAJ/G/oJrniRWp8ubuOXzf1d+di8Mvzy9dqt3L27Uq4urU8hEyPWG8vIO7t+vDtSYrvhNPhq3xCJx45IjdbuMVN6x552xmLm7g8RI6l7b3Kd83iDbDQkERU6hQg21uYm8v2Xl5chd9tDpdd+c9b47+9uJh+eJoPRMBhubJYS8Ba1qcMLh8EwoKVcGZtx2fFF76mDoWH6yZV7NfwHr6+m0aReP0+5cBx2OZdNC2ewDV1MrongufcXRRntH2JtJ2l1/4Sae7BRxhJEWS65wd91WlW0/LlAvYNoNvdgy7XgS2r0rIREGPqdQLTiqcEzlXjzsaH/W3Yqi5blkji+5WlB/8CDZ9x1XpEk9f/R7b46bqBskCeoXe71/nUcY247J4/mH13Zr1q7nUyhqr4CIl/3/g==
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get entity details"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/entities/{entity_id}"}
context={"endpoint"}
>
</MethodEndpoint>
Get detailed information about an entity including observations (mental model).
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"entity_id","in":"path","required":true,"schema":{"type":"string","title":"Entity Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"id":{"type":"string","title":"Id"},"canonical_name":{"type":"string","title":"Canonical Name"},"mention_count":{"type":"integer","title":"Mention Count"},"first_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Seen"},"last_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Seen"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"observations":{"items":{"properties":{"text":{"type":"string","title":"Text"},"mentioned_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mentioned At"}},"type":"object","required":["text"],"title":"EntityObservationResponse","description":"An observation about an entity."},"type":"array","title":"Observations"}},"type":"object","required":["id","canonical_name","mention_count","observations"],"title":"EntityDetailResponse","description":"Response model for entity detail endpoint.","example":{"canonical_name":"John","first_seen":"2024-01-15T10:30:00Z","id":"123e4567-e89b-12d3-a456-426614174000","last_seen":"2024-02-01T14:00:00Z","mention_count":15,"observations":[{"mentioned_at":"2024-01-15T10:30:00Z","text":"John works at Google"}]}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: get-graph
title: "Get memory graph data"
description: "Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items."
sidebar_label: "Get memory graph data"
hide_title: true
hide_table_of_contents: true
api: eJzNVm1r4zgQ/itiPrXg2k62C4e/ZW9DL9BtS5q9gwulKPbE1kaWvJKSNGv834+Rncbuyx4cd3D9kiLPyzPPzDNSDY7nFpIlfMFSmwM8BJChTY2onNAKEpijMwJ3yHLDq4Jl3HG21obthN1yKX5wsguY9vZcygNbC+nQYMZWB+YOFbKzvTYyi/CpQiNQpRjpSiih1XnIrkUpHGbMaTaK45iV2jpmMEXlmHBY2hAC0BUan2eWQQI5ukcPBgKouOElOjRUQw2KlwgJrLjaPIoMAhBUQsUd2Rr8vhUGM0ic2WIANi2w5JDUQCghAeuMUDkE4ISTdPCJqw2bZdA0wXNsb9sF/r5FcxhEXnNpB6G5OtyuPbZhEorYnaitlNA8nNIu6LyhE4O20sqipVDjOKafYXvut2mK1q63ks07Ywgg1cqhch5AVUmRevaib5Z86h68yhC3TrQZlM7afzzz3jvLRNvYu55ly18HX6++YeqgeT7gxvBDj8UbH7UJALP8Pwg/9VHpO19JfDR6/+/nWFBoNqfQZKQdl49bJZztTY9QDnM0fS+yY1+9XdO8zNYfm2VH/ZGjQTHDhL05uSIRfOaO9zr/UrztB1bqDKXXbU/GqLJKC+VIYvjEy4qi1sc2LWtYG11CAiMPARIYw3MRFkuunEghgD2KvHCQxOEvNLPdEC1rEFnnLPkKJSQwkSJFttdmYxl37ErrXOIppl8TXhnec9zz/KRXbE87oRCbTqMDn4dh+5d1K4EnBwn8oc2GCbXWRA935DWOx5cX8ehi9JGN4uRDTAQoJ9rR6GCe3U3n97c350GHk53dzq8mN7M/J4vZ7c057QBCyVfpaPzh8mMYEo1dyrcL9Sj7szNu6C+Ay/H4tbJ/51JkXrdsaow2/1zWGTou5EAUQwOp06Fk/n5pHae9eXhfNde6BUiaKW3+s037Ba3lOZ4k+L6pJ4N1O/LnoqK62tSdXU88J3pbdt8v43NL31vJjia/LRZ3rwK2vS3RFbq7tvyF5QpIINqNogzXfCtdRLeVjeru0mqi493mR5aIOCYRKrMkNUbp2ORu9krvxw9e6c/23eTw1E9Od4+19z27P1iHJVVPI0s75GQyqXhaIBuHpI+tIR0WzlU2iaL9fh9y/znUJo86Xxtdz36d3txPL8ZhHBaulBR4h8a28EZhHMZ0VGnrSq56ua7QsbKFdNpQL+urTwr4X7xLunEg0UeV5MJPuieq7hq9hN3IV+FbDYF/mtBKT05vlLbfDwEU2jpyqesVt/jVyKah4/aVQWrMhKUld3pnbPBwepLsuNwSHL9ndtwIsn3b711Wz+adfM7Ze/UdVaIO/ZxHLMey/F4okGdoPIT26yRNsXI9v1drjLA/S+ZquoCm+QsJVZbu
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get memory graph data"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/graph"}
context={"endpoint"}
>
</MethodEndpoint>
Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"nodes":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Nodes"},"edges":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Edges"},"table_rows":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Table Rows"},"total_units":{"type":"integer","title":"Total Units"}},"type":"object","required":["nodes","edges","table_rows","total_units"],"title":"GraphDataResponse","description":"Response model for graph data endpoint.","example":{"edges":[{"from":"1","to":"2","type":"semantic","weight":0.8}],"nodes":[{"id":"1","label":"Alice works at Google","type":"world"},{"id":"2","label":"Bob went hiking","type":"world"}],"table_rows":[{"context":"Work info","date":"2024-01-15 10:30","entities":"Alice (PERSON), Google (ORGANIZATION)","id":"abc12345...","text":"Alice works at Google"}],"total_units":2}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,63 +0,0 @@
---
id: health-endpoint-health-get
title: "Health check endpoint"
description: "Checks the health of the API and database connection"
sidebar_label: "Health check endpoint"
hide_title: true
hide_table_of_contents: true
api: eJydUk1v2zAM/SsCz5rt5ehbUQRLgLUoluxkBIUqM5ZaW9IkOplh+L8PtN31Y7f5Iovi43vk4wikmgRlBXfeWfLRugZOEmpMOtpA1jso4dagfkmCDAqDqiUj/Hm+3TzshXK1qBWpJ5VQaO8c6hkmwQeMiv/3NZSwIB/R1cFbR4/rvUECCRFT8C5hgnKETVHw8VHDodcaUzr3rfixJoME7R2hI05XIbRWz3z5c2LMCEkb7BSU48SfhA7JeBazsAZFBkrIFykgwbqzZxxZahFK2FlXJ9sYErvj8YHbhc+zeX0QZx/F3/xVmtKzNKc6rnaHnY+DOAyJsINJQms1ch9vKTdBaYNikxUgoY8tz40opDLPr9drpubnzMcmX7Ep/76/3d4ftl82WZEZ6loufMGYFnlfsyIrOBR8ok65d1y7xUrN5opXWz73N76N+H/XgIbAdIS/KQ+tso7lzL2NqwPVuhy8ecYn4sg4cqWfsZ0mDv/qMQ5QVicJFxWtemJ/qtMkGVpjhLIa4QUHnqHWGLiRi2p7Zv5nM6bTu1X4tj3CNP0BgNwIYQ==
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Health check endpoint"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/health"}
context={"endpoint"}
>
</MethodEndpoint>
Checks the health of the API and database connection
<ParamsDetails
parameters={undefined}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}
>
</StatusCodes>
@@ -1,57 +0,0 @@
---
id: hindsight-http-api
title: "Hindsight HTTP API"
description: "HTTP API for Hindsight"
sidebar_label: Introduction
sidebar_position: 0
hide_title: true
custom_edit_url: null
---
import ApiLogo from "@theme/ApiLogo";
import Heading from "@theme/Heading";
import SchemaTabs from "@theme/SchemaTabs";
import TabItem from "@theme/TabItem";
import Export from "@theme/ApiExplorer/Export";
<span
className={"theme-doc-version-badge badge badge--secondary"}
children={"Version: 1.0.0"}
>
</span>
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Hindsight HTTP API"}
>
</Heading>
HTTP API for Hindsight
<div
style={{"display":"flex","flexDirection":"column","marginBottom":"var(--ifm-paragraph-margin-bottom)"}}
>
<h3
style={{"marginBottom":"0.25rem"}}
>
Contact
</h3><span>
Memory System:
</span>
</div><div
style={{"marginBottom":"var(--ifm-paragraph-margin-bottom)"}}
>
<h3
style={{"marginBottom":"0.25rem"}}
>
License
</h3><a
href={"https://www.apache.org/licenses/LICENSE-2.0.html"}
>
Apache 2.0
</a>
</div>
@@ -1,63 +0,0 @@
---
id: list-banks
title: "List all memory banks"
description: "Get a list of all agents with their profiles"
sidebar_label: "List all memory banks"
hide_title: true
hide_table_of_contents: true
api: eJylVttu4kgQ/ZVWPe1IDhiY7IOlecjORhOk7Oxow7wsQlFjF7gnffF0lyEI+d9X1TYYSLRz4wWruy6nqk4dew8k1wGyOfwh7VOARQIFhtyripSzkMEHJCGFVoGEWwmptZBrtBTEVlEpqETlReXdSmkMkICr0Et2nRaQAbs9LmPgBDyGytmAAbI9jNOU/85zPdR5jiGsai3+6YwhgdxZQktsLqtKqzzGH34J7LOHkJdoJD9VnrOTajO0abM9KEITXr9/VAU/0q5CyCCQV3YNCZAizQfcEjEtoEnASoP/Z/qR75sEChUqF1Rb0GXK8IQVqVwFcxJKWcI1ekjAyGdlagPZdQJG2fZ51Od46N0vp3TntqKLLrXYBEG+DqTsWvw2end4TsT1u6PRG0arFaGX+mcB3ffurwHqouudICc4qq88klB25byJQ2R0K43PaqmR0XUeERuaSlK5+ylgt53va6hMnZcMKHc2qAK9QOP4WmoRmfZMjKpAknmJBaNqkSCp/A00TXKA45ZfMKdI7K+18ljwFoXTGenT/hzqWfQw/+zJMvNSUXgB+MRCUDQRVMrYQ12jzVGUXBIa5xUGIT0Kbi4WQtqi7zkWA0bwLE2lI42PzZ2ck2CSnJF0wuUuZf609q6239iVo1WTQO5REhaPsl1bu/t7Bdn80rtJjie21hqak968byOIG+J4dVX8YrzPbYQY7xszPChDt/XnS33Wj8W5VtyrQFPCl9sQhSRqKItRK52daIpQGyP9bgA9Kum93F3oUPgu2OE1SCdaeg7rcCGMK1AzcyJIlg0W+hjwgjidqs73Z7SAqZBGSBHcirZMQrRrZTHu6lFnoQ7oR+MJnNMDxun47VU6uhpdz0ZpNkmzNP0XXijpdzP2oNVwo1XONZ9yp0/2+2z0Nhu3yZpFE38JGKTSMdY1cns5JWQw3IyGBa5krWl4eJuxisV96Jp9p2wR1LokcTebfRI3n6Yv1ae7iI0+2ndvOJlHanfY/+KN3omHXWA6RaXOkUfYm9xULFBiPEi5Rq8hg5KoCtlwuN1uBzJeD5xfDzvfMLyfvr/9+HB7NR6kg5KM5sAb9KGFNxqkg5SPKhfISHuSi1kUKWFaXIcmnNW379/UP/rV0NGaxXdYaals3Hmuad/NYA6bUUwYp9DRKrK9dIH4fr9fyoCfvW4aPv5ao99BNl8ksJFeySVPab5oEihRFugjh59wx53Mc6w45kbqOu7f5WcGC8mRGh9uZ9A0/wF6hSQV
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"List all memory banks"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks"}
context={"endpoint"}
>
</MethodEndpoint>
Get a list of all agents with their profiles
<ParamsDetails
parameters={undefined}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"banks":{"items":{"properties":{"bank_id":{"type":"string","title":"Bank Id"},"name":{"type":"string","title":"Name"},"disposition":{"properties":{"skepticism":{"type":"integer","maximum":5,"minimum":1,"title":"Skepticism","description":"How skeptical vs trusting (1=trusting, 5=skeptical)"},"literalism":{"type":"integer","maximum":5,"minimum":1,"title":"Literalism","description":"How literally to interpret information (1=flexible, 5=literal)"},"empathy":{"type":"integer","maximum":5,"minimum":1,"title":"Empathy","description":"How much to consider emotional context (1=detached, 5=empathetic)"}},"type":"object","required":["skepticism","literalism","empathy"],"title":"DispositionTraits","description":"Disposition traits that influence how memories are formed and interpreted.","example":{"empathy":3,"literalism":3,"skepticism":3}},"background":{"type":"string","title":"Background"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["bank_id","name","disposition","background"],"title":"BankListItem","description":"Bank list item with profile summary."},"type":"array","title":"Banks"}},"type":"object","required":["banks"],"title":"BankListResponse","description":"Response model for listing all banks.","example":{"banks":[{"background":"I am a software engineer","bank_id":"user123","created_at":"2024-01-15T10:30:00Z","disposition":{"empathy":3,"literalism":3,"skepticism":3},"name":"Alice","updated_at":"2024-01-16T14:20:00Z"}]}}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: list-documents
title: "List documents"
description: "List documents with pagination and optional search. Documents are the source content from which memory units are extracted."
sidebar_label: "List documents"
hide_title: true
hide_table_of_contents: true
api: eJzFVk1v4zYQ/SvEnFpAsSRvctEt7QatgWw33bg9NDAMWhpb3FCkQo6SGIb++4IUJUubOGmLAvXFNvk4bz7eDHkA4jsL2R181HlToSILqwgKtLkRNQmtIINrYYkV/T57ElSymu+E4g7AuCqY9lgumUVu8nLGBnOMG2RUIrO6MTmyXCtCRWxrdMWeSpGXrMJKmz1rlAhwfCbDc8JiBhHoGo0nWhSQgRSW1oMvEEHNDa+Q0LgoDqB4hZDBhqv7tSggAuEiqDmVEIHBh0YYLCAj02AENi+x4pAdgPa1O2bJCLWDCEiQdAs/cXXPFgW0bTTYfuitPjRo9hOzWy7txC5X+89b79iUwZkLK6qREtrVkfP3CZsUlaB/wBisCkW4QwOullveSIIsTZIjybU3OybS263F/4ZpxPO5s9q6AA3aWiuL1p2eJ4n7mirttslztHbbSPYlgCGCIBmfz7qWIvdyiL9ad+Yw8qg2TiwkOgZBWE1/8KIQnU5vRshOCyEavfmKOUE7LHBj+H6kiIU35vY1cflqHnro0iPaKNTwLWgoR9RX4S3skNLvnR5X6y5E3fsZDUIKDKsxuaWhX0d5n9am32CVLlCyrTZMTgcDqqLWQpHrWnzmVe2sD+m/OwxdmUFj0aTzD8firktuS5fuTR7WDXLCYs0JMpgn8/OzJD1LL5Zpkn1IsiT5yynVmbJordBqnUIE3SRZu0myznXjNJNeRED4TGuJakclZBfn8ySCpi7eMe8UGwrnO6evTDKU/iJp3SeC8/n8pZb/5FIU3YS8Mkabfy/kAokLOVHyFCB1PtX5+1Onl1W7Oi31a9056HRZ2d1bc/ITWst3eOyb01CfDLZ0u+9J2MXVUQfcSLTH9HbZPR3Gxy59r5H1kF+Xy5sXBrvaVkildjrb+eHob5IM4sc0DuMudqq28SGIu43Ht5NQW+2T0RMJVVixK4k5SnZ5s3jRZ/2G77ABH9TDc6+eMLI/dRfn7d4SVt2gydH17hFyWfO8RDafJRBBYyRkUBLVNovjp6enGffbM212cThr4+vFz1e/3V6dzWfJrKTKT7BHNLZzL50ls8Qt1dpSxdWIa/pO+D6ww1H+//OLIqjATYW4llx4gfvcHEJ97+AxHV1okZ9cLqLs+LAoxg+mUltyxw6HDbf4h5Ft65a7W9Q1YiEs38jRPXqP+/CWeOSycf749jyB64f338EOF/kRvHJ/jHDo1705WakfvoR+/JGdylzfdmo/5uy96RPmB02JvEDjXeh2L/Mc67GvL+ai833owV+ultC23wAYB51G
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"List documents"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/documents"}
context={"endpoint"}
>
</MethodEndpoint>
List documents with pagination and optional search. Documents are the source content from which memory units are extracted.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"items":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["items","total","limit","offset"],"title":"ListDocumentsResponse","description":"Response model for list documents endpoint.","example":{"items":[{"bank_id":"user123","content_hash":"abc123","created_at":"2024-01-15T10:30:00Z","id":"session_1","memory_unit_count":15,"text_length":5420,"updated_at":"2024-01-15T10:30:00Z"}],"limit":100,"offset":0,"total":50}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: list-entities
title: "List entities"
description: "List all entities (people, organizations, etc.) known by the bank, ordered by mention count."
sidebar_label: "List entities"
hide_title: true
hide_table_of_contents: true
api: eJzNVttu4zYQ/RVinnYB2bqsk231lqZpm8LZBhu3Dw2CgJbGFjcUqSWpJKqhfy+GkmLZibPbLQo0Lw7E4ZnbOcPZgONrC+k1nCknnEALNwHkaDMjKie0ghTmwjrGpWTYm7A3FepKYsC0WXMl/uJkaQOGLpu+ZXdKPyi2bJgrkC25uiO7HA3m9LEkFK1YpmvlphCArtB4gPMcUpDCutvBEQRQccNLdGgoyA0oXiKkQKi3IocABEVYcVdAAAY/18JgDqkzNQZgswJLDukGXFPRNeuMUGsIwAkn6cMPXN2x8xzaNnjClqIUbkD+XKNpdqBXXNqXsIVyuEYD+9W74I+irEum6nKJhunVtoxOM4OuNspfWvFaOkjjKNrGN/extN+E2d5Q2LbSyqKlQJMoop9dqKs6y9DaVS3Zx94YAsi0cqgcmfOqkiLzDQo/WbqzGSVfGWqf71W6AeGw3P1n7zx/rRnUhwAyrrQSGZe3XT8O258OluwDWbYB9Ny69dx6sTfD3Yuehafesg1gJYx1txbRJ8hV89vKE27XOdGk/6JqKX2NB8ifCIFdEUIbgOT/Em7OR2glOp5zx3fBeJ4LyoLLy1GZO+73sHr5CTP3qqOLAbtt96+NeX8NXm977dmv+QjXD5SGhse5w/KZLrpjRnpnRBf2IFzBbF2W3DQ0F/CRl5X0DNjnBPyqCxLNuGmQRMlsEsWT+GgRR+m7KI2iP0nGNFXi5B3Ojo7fT/C775eTOMnfTfjs6HgyS46P41n8fhZFEew0rYdLJlG8iGdpNMDtUSw+GlWNG8ObMaG9Cr5YVm/1YuFGitwt3nDASp2jZCttugnQ1xNVXmnRjddRGXtVXv/PC3rT0l8AsyR5Pq/+4FLkfhqxM2O0+fZhlaPjQr4yraTOdk6/QsXDoGlvDrNirrsAva7t+rUJd4HW8rUfbZ3JYVNfDLag0y8RjvLqXPd2I+5ty9tV93AaP3ble8nZYPLLYnH5DLDrbYmu0ESkNTr/yrsCUgjv47B/CEN64m246V/6NhztBEKttK/F4Eeo3Ip14Rh5ZCeX588EMxx4qTzZ9+ThmSdPL4ULLLVp2FVjaWzRKBcZkgi3JicVzwpkyZQ4XhsJKRTOVTYNw4eHhyn3x1Nt1mF/14bz89OzD1dnk2QaTQtXSgK+R2O78OJpNI3oU6WtK7ka+Zp3gn5KfievzZb8//Wa1jfZ4aMLK8mF56/PfdO37xru49EmE/gtjUJOt+sajrbMQltHtzabJbf4u5FtS5+7lYtklgvLl3K0dB3M/SuXrBdzuMNmtPXdc1mTjX8i77kRFME/jObNx15tb9khp4OoVDP2OQQz1MuPkQJ5jsaH0J2eZBlW41ifTT2K/UlhP58toG3/BkhS/u4=
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"List entities"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/entities"}
context={"endpoint"}
>
</MethodEndpoint>
List all entities (people, organizations, etc.) known by the bank, ordered by mention count.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum number of entities to return","default":100,"title":"Limit"},"description":"Maximum number of entities to return"}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"items":{"items":{"properties":{"id":{"type":"string","title":"Id"},"canonical_name":{"type":"string","title":"Canonical Name"},"mention_count":{"type":"integer","title":"Mention Count"},"first_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Seen"},"last_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Seen"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["id","canonical_name","mention_count"],"title":"EntityListItem","description":"Entity list item with summary.","example":{"canonical_name":"John","first_seen":"2024-01-15T10:30:00Z","id":"123e4567-e89b-12d3-a456-426614174000","last_seen":"2024-02-01T14:00:00Z","mention_count":15}},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"EntityListResponse","description":"Response model for entity list endpoint.","example":{"items":[{"canonical_name":"John","first_seen":"2024-01-15T10:30:00Z","id":"123e4567-e89b-12d3-a456-426614174000","last_seen":"2024-02-01T14:00:00Z","mention_count":15}]}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: list-memories
title: "List memory units"
description: "List memory units with pagination and optional full-text search. Supports filtering by type. Results are sorted by most recent first (mentioned_at DESC, then created_at DESC)."
sidebar_label: "List memory units"
hide_title: true
hide_table_of_contents: true
api: eJzVVsFu4zYQ/RWCpwSQLdl10lY3d9dIDWSTNPa2wAZGQEtjmxuKVMhRHMPQvxdDSba8jtNt0R6aSxLyad5w5r0htxzF0vH4gX+CzNgNnwU8BZdYmaM0msf8Wjpkmd9khZbo2FriiuViKbUgDBM6ZcbDhWKLQqkOwisyB8Imqy6bFHluLDq2kArBSr1k8w3DTQ5ddg+uUOiYsMCcsQgp7WXGIbOQgEa2kNYhO8tAEwGkjwLZx9HkQ8BwBZolFgTuV8+7POAmB+szG6c85ko6fPT5S3A84LmwIgMES6feci0y4DGfC/30KFMecEmHzgWueMAtPBfSQspjtAUE3CUryASPt5zS5zF3SOfhAUeJihZ+EfqJjVNelsEutsfWgZ8LsJuDyAuh3EFooTe3C5/bIQlFrFd0oRQvZ3vaKa23OZ//Y8LfDtiUzCT+DcY6qtQIS7CcJLcQhUIe96JoT3Ltw7aJzGLh4N9havHcVlFLOqAFlxvtwNHX/SiiX4eGmBRJAs4tCkXy9WAe8MRoBI2+nnmuZOIVGH519M22lVFuSZ8oKwaJkB3+IdJUVl66ayEr/dWnMfOvkCAvdwvCWrFpqXDsg9G+QaHerMNOOR5RBnUP34PW7QiaLryH3ZX026Tb3XqoT93kGeyEVDPM2uQOqxH1mYZQq/KH3Wk2WGZSUGxhLFNHEwx0mhupkaYFvIosJ4pdDx62VTdfkcf8D2OfWGL0C1jnW0qMAimlftQfdKJep3cx7UXxD1EcRV8ooEZZNY0PlUyAnd2N7ie3N+cBuzJmqYCd3d5fDW/GX4bT8e3NOamZBtXFRQQ/DaKoA/2f551BLx10xI+9y85gcHl5cTEYRFEUUamqvKrQa2OfHBPYRDaaxiIbjhmCyPiu+GtjVeoNXLfZ+6zpY7QTSu8iKukn4IN+/1j6vwsl02roj6w19p/rPgUUUh0I/xCgTHJoi78eUo0Ky9lpZ1ybKkGSceaW743yT+CcWMLeZqehvhisGcLvKp7OVVHXuJbG9+Wtqnv6GB+r8r1F1kB+nU7vjgJWvc0AV4Ykt/Sz1F92MQ9femE9HUO6Dl24rW/FMmzuz5C85MfvwviCNGRSp04uV8iIlg3vxkfGbDa8JXf4WkEi8Qqqp3zlczbZOISsmk0JkNn3kGEukhWwfpcsUVjFY75CzF0chuv1uiv8dtfYZVh/68Lr8YfRzWTU6Xej7gozP/TI1VV6vW7UjWgpNw4zoVtcRy+gb8+23bvgf/hcqgVESYS5EtJ7w5d0W0vjgb/0Wldn4F9LVIV4/2xqvbC8RmYBXxmH9PF2OxcOPltVlrRc3drk5FQ6MVete/sJNvv30otQBSXmLX4C+vyduOZe+R7s7o2xB8/oHysJ/XbiJ+Vwdl97/5ydKnVjcb1pczbZNBX2Q20FIgXrU6h2h0kCeTvXoxlMue/8fjWa8rL8E3jOBNI=
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"List memory units"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/memories/list"}
context={"endpoint"}
>
</MethodEndpoint>
List memory units with pagination and optional full-text search. Supports filtering by type. Results are sorted by most recent first (mentioned_at DESC, then created_at DESC).
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"items":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["items","total","limit","offset"],"title":"ListMemoryUnitsResponse","description":"Response model for list memory units endpoint.","example":{"items":[{"context":"Work conversation","date":"2024-01-15T10:30:00Z","entities":"Alice (PERSON), Google (ORGANIZATION)","id":"550e8400-e29b-41d4-a716-446655440000","text":"Alice works at Google on the AI team","type":"world"}],"limit":100,"offset":0,"total":150}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: list-operations
title: "List async operations"
description: "Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations"
sidebar_label: "List async operations"
hide_title: true
hide_table_of_contents: true
api: eJzFVE1P3DAQ/SvWnEBKN8uqp9xoiygSFAS0l9UKDc4kMTh2sCdLV1H+e2Un+8UWpJ56SuyZNx/Pb6YDxtJDNofrhhyyssbDIoGcvHSqCWfI4JxYoNDKs7CFQK0F+pWRwm4w4qghkytTCjS5KFBpyo9FYZ1A4RuSqlBSYEmGE6GM1G30JeesEzV5jyX56D5AdyJDApvDRQ4ZhDIe9uwNOqyJyYVGOjBYE2TwiOb5QeWQgAo9NMgVJODopVWOcsjYtZSAlxXVCFkHvGoCzLNTpoQEWLEOF1/QPIuLHPp+EeC+scaTD4jZdBo++1zdtVKS90Wrxe3oDAlIa5gMB3dsGq1kLD598gHTbavo+75P4PNsdhj4F2qVR5g4C7z9Q1RoXCCM1VB3ToxKhz/FVPtDB23lnhXN6rqI3O6T1CebG2WYSnLQL/pkfYfO4WqHyUs7FAh9ArUvPyL9atAEbIK97xrJEPfB2m9z28cnkrz34PPY15B69Ftsw2zpHdh9v41vA31/S7Z2+X5/f3MQcHjbmriyQcclcdQuV5BBujxJcyqw1ZwG4fq0G/Xbp3taV6awkY11JmVyr8qKRcgpTm8u4O30rg1xvjb+o3xQRvmMM3NFtXUrcbfyTHWgQCtJQcFbl9MGZUViNplCAq3TkEHF3PgsTV9fXycYzRPrynTE+vTy4uvZj7uzT7PJdFJxrUPgJTk/lHcymU6m4aqxnms0O7kuw8Z5u2re9tdtx+B/L6pRDky/OW00qqj0yFE3PvQcliexgfjUkMQtFaDZdl3ZvU1cWc8B13WP6Omn030frl9acivI5osElugUPgY1zDvIlQ//OWQFak8fcHV0O07GsXiv9PUAmCD/Jeo2nCCBZ1rtLNg48hVhTi6WMFhPpaSGd3AHGyrs0800nJ/dQ9//AWouPmY=
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"List async operations"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/v1/default/banks/{bank_id}/operations"}
context={"endpoint"}
>
</MethodEndpoint>
Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,63 +0,0 @@
---
id: metrics-endpoint-metrics-get
title: "Prometheus metrics endpoint"
description: "Exports metrics in Prometheus format for scraping"
sidebar_label: "Prometheus metrics endpoint"
hide_title: true
hide_table_of_contents: true
api: eJydUsFu2zAM/RWDZ8/2ctStGII1wFoES3YygkKVGVurLWkindQw/O8DXXvNutt0EUDy8T3ycQTWNYEq4cE7yz5aV8MphQrJRBvYegcKtq/BR6akQ47WUGJdso++Q26wp+TsY6dZvoRM1EFapOADRi34XQUKFuQTuip46/hpDdTIkEJECt4REqgRNkUh398SDr0xSHTu2+T7UgwpGO8YHUu5DqG1ZmbMf5JgRiDTYKdBjZO8VFQ0XuS8sQbNDSjIFy2QgnVnL0C23CIouLeuIls3nNwfj/vkbr+Dj7tZE/P8f+oXbdrM2pzupNsDdj4OyWEgxg6mFFprUAZ5L7kL2jSYbLICUuhjCwoa5kAqz6/Xa6bndOZjnS9Yyr/tvmwfD9tPm6zIGu5aaXzBSG/yPmdFVkgoeOJOuxuuGwtXY1d7Pk45vm/6v46BhyCMjK+ch1ZbJ4rm8cbFhXI9Ebm+xhNLaByfNeGP2E6ThH/1GAdQ5SmFi45WP4tH5WlKoUFdYQRVjvCCg+zRGAwyxkW3vVD/cx7T6eYevm6PME2/AWkyDcA=
sidebar_class_name: "get api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Prometheus metrics endpoint"}
>
</Heading>
<MethodEndpoint
method={"get"}
path={"/metrics"}
context={"endpoint"}
>
</MethodEndpoint>
Exports metrics in Prometheus format for scraping
<ParamsDetails
parameters={undefined}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}
>
</StatusCodes>
@@ -1,78 +0,0 @@
---
id: recall-memories
title: "Recall memory"
description: "Recall memory using semantic similarity and spreading activation."
sidebar_label: "Recall memory"
hide_title: true
hide_table_of_contents: true
api: eJztWW1v2zgS/isDfkkLyO9J2go4HNI02Auw3XSb3C1w2cCgpbHNNUVqSSqJEfi/H4akbPk1aVocDovLhyaVhsN5fZ6h+MQcn1iW3rLPWGgzZ3cJy9FmRpROaMVS9hUzLiUU/jVUVqgJWCy4ciIDKwohuRFuDlzlYEuDPCcJnjlxz0lF+3f1uwIAuJkiuHmJUHLDC3RoQFjQfh8u/fqisg5GCFoh6HEa1rXg6EEbmR+l8BMqNFzCTOkHifkEgY905aBEXUpMoJQ8Q5sA3qNyNvE63VSoiQU35Q6mvCxRLdXiY4lGoMrwKAXvv0AbVa7eJZBpdY/GendIa+b/AMdnqOIm3M4slGjG2hSYL3fQpVBCq6PUez/ianZkIcjACKXAsU1omS2RAobR5nuBD6UWytk6eNfoQKhMVjkOUTnhBNq/OVMhOA0TdOAfzkGPLJoQeAtcajWxIkcwIYkGbSWdbbOE6RKNF7vMWcrC+2ERY8AStkwSFccTU7xAljLyYChyljBBtVFyN2UJM/hnJQzmLCWLEmazKRacpU+M8s1SZp0RasIS5oST9OAjVzO4zNlicReWo3UfdT6nNZvaMq0cKkeveFlKkXmzO39YKs+nxmalIacoMvS/Pys080M2/OoFFokX8Eu4ml+NvbvCYWG3F0dhljJuDKfFSwlVScnIm1r9jde62U0/C+tAj2HMM+e7wVICY3re5DjmlCB6Rg/EGJR2QNUhxgLzt2TBqMon6MMRxVnKCp+TTU9RVQW1ttQPLIkyUzGZsoaZH4O2TTvDY5B4j9JXbLSxY3AsMXOwrB/bJqMK/jh0eoaqGTWhHE7QNGL+mT/CTRBLVuYfdz+cUmgNz7CxfKS1RK4ay2+8RGPlmEuLiyQke+hEgdbxolxP5mYO9+fMlwTcLNVsRuXy+sp3L3eQc4cQVMIbbE/aCRz1u/1Bq3vSGnRv+oP0uJt2u0c+ZbFzQ86aCq/K0KkU4CDkwTPPRUTFnDsOb+qOB26whoEcRnOIgXhLDbtW/fWK9Uisy7wuZ03zP/NHUVQFBC3eix041EzYSbe7WHWRHv2BmWvsdeFXXwYPY3C2dt0dtF0AKNQW8u1K/0aSw+67FLY9DjsNtJR+58LykVzKemsskV7T5/VIxwhk00rN/vvpCdvCm/i74HPiW2cqlXFHANOw+33vQ/9Qss5Jx6tyFXf/rvQY/hD1LLPytKB/UVFKkq0c1eia1k/yt212yL8N13aJrrjqNhJOA03C5PQ1sNtWZOJzKHSOsoGwgCr33E81hI+8KKUHjhr2I443IKXZ6zsqrfmIkDapqZH9RjNRLnI4kyJDsHweh5+CZ1OhECRyo4Sa/J3tgFi2A+7YEsUDd0dqvWV+gvMO1WMVu1vQD8XQllrZYH+/291Gyesqy9DacSXhaxRmr54LYqnRn0uWX5cQ+aGxgaaWhDl8dIekbuj9smBex0Y0QZCO3Vj+A0aUi1rxIkYz+PQaW8/j8kXCdJZVxmA+tI6bVyu8ilrg2mtp6kWVf7fWC+XTWFBstcJ8yF9t6edaB5x5O3OdVaR3KF5t5qeoAi6jlY7TILCubjUlfFkr3331EEHrsCtxo5qgvsMHzw5hxj+Mm2F0peLZgZ3Uq1vQeS3URG4caoD6YQMyVy6w45NTfPf+Q7eFvf6oNTjOT1r89N371odurz84Pjmld6zRBQRYMxBqrNlGRplFSxQ/5KOs1x+wZn/eMo+kLGE/aT2RSB75Nb3+AGmXFr7/MGr1+vmgxY9PTlvH/dPT3nHv3XHXY+d6ORLAHre6vVbv5KbXTQcEsP9m6+VgdWUynxHJs9l2m+zTsdmk++RiNAJBUEwscAfBO9AK3BTh7BIc8mJ1AAlgv9iEomZ2AwY3h/7nCntFKC+r5XBW2Auf+7pnxxg9Hx5mhDC0xl7NuNJKZFwOw5F5/7LzWhJ+IUlKXXNo3s9PL+WeHw9uz3TyZhOHwFytvGqw93pHn6nmnB2nEK7iXN3eYrUGojdj9pyBq3RuJWoj+lteXDvucK/959RMygGFnMs40+nxbhdeULxLZt7cKNaaJWsaBy46Gy7THebqZYftOmm8rPp/5CAUsVjl+HjwOBNpw8t5eIgnk2e+C9RSm/H6bYpuisbjlDcByGB44HZ16IE8fEbzQzJIUQhntz8yvJjF1n3dZMRPBNxb5eMt82d9SikHGxjOK/rG0jkP6d65RagY+vZkE5jhPHxEWNLkcz7WRbWLp3f3Rf1i/ynH7uJsX30vouwVy4fK6kbCfSHffwO9teF6ikcWRoj+uUHvzgDmyI1tt8NZskk2YRYgCzc4YTklNOjlJSNCbxOlqJVfNjN8C48v7uKxLJyTbn/cIPXjJqX/nSnnrjHDqKoYLuPWe+VBm47YQ4uZVrllabfd6w8W8ah83O9vn47/xaXIA29eGKPN64/GOTou5IHJQ+ps7e0LJooa4Rd3+zn8Zx0M9EOLnRyik89oLZ9g82i9dyyjYEA4RD8DbORX2DrKNRBuFd4Q3f1ufArhO/RJ6R83N1+2FIbcFuimmmq51P5rkb9bSVnnvteJTNSh2xfbeYqXMItOfV3TCZjKEkYZ/rq6Trn4S38+Ii/G2pdAHV6hcismUwcUaDj7crnFSPULD95L+dgzPPM9E1E63IjC9dw6LCjv5Cax3ErkrOTZFKHfJtMrI1nKps6VNu10Hh4e2ty/bmsz6cS1tvPz5fnFL9cXrX672566QpJiul0M5vXa3XaXHlEVFFw19lq7iN3062nV8/+/sf1r3thGTCGu6pSSCw+XvuaeIljcsvteY3BN/HUtjYLp6t62ccUbUeMuYVOCnPSWPT2NuMV/GrlY0OPY6Ld3CbvnRtA3cw/29ffzOBofKMU3XyPKvoV9HtRgqqim77ms6H8sYTOcNy6cPX1MkedovAnh7XnYqOVBfrV6i/OIj8KKsyzD0h2UvWtg8Zer6xuKY7yapimWbss53afSv95SXS5P7P7ZE5NcTSqiqZQFnfTzH/FPUrU=
sidebar_class_name: "post api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Recall memory"}
>
</Heading>
<MethodEndpoint
method={"post"}
path={"/v1/default/banks/{bank_id}/memories/recall"}
context={"endpoint"}
>
</MethodEndpoint>
Recall memory using semantic similarity and spreading activation.
The type parameter is optional and must be one of:
- 'world': General knowledge about people, places, events, and things that happen
- 'experience': Memories about experience, conversations, actions taken, and tasks performed
- 'opinion': The bank's formed beliefs, perspectives, and viewpoints
Set include_entities=true to get entity observations alongside recall results.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={{"required":true,"content":{"application/json":{"schema":{"properties":{"query":{"type":"string","title":"Query"},"types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Types","description":"List of fact types to recall (defaults to all if not specified)"},"budget":{"default":"mid","type":"string","enum":["low","mid","high"],"title":"Budget","description":"Budget levels for recall/reflect operations."},"max_tokens":{"type":"integer","title":"Max Tokens","default":4096},"trace":{"type":"boolean","title":"Trace","default":false},"query_timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query Timestamp","description":"ISO format date string (e.g., '2023-05-30T23:40:00')"},"include":{"description":"Options for including additional data (entities are included by default)","properties":{"entities":{"anyOf":[{"properties":{"max_tokens":{"type":"integer","title":"Max Tokens","description":"Maximum tokens for entity observations","default":500}},"type":"object","title":"EntityIncludeOptions","description":"Options for including entity observations in recall results."},{"type":"null"}],"description":"Include entity observations. Set to null to disable entity inclusion.","default":{"max_tokens":500}},"chunks":{"anyOf":[{"properties":{"max_tokens":{"type":"integer","title":"Max Tokens","description":"Maximum tokens for chunks (chunks may be truncated)","default":8192}},"type":"object","title":"ChunkIncludeOptions","description":"Options for including chunks in recall results."},{"type":"null"}],"description":"Include raw chunks. Set to {} to enable, null to disable (default: disabled)."}},"type":"object","title":"IncludeOptions"}},"type":"object","required":["query"],"title":"RecallRequest","description":"Request model for recall endpoint.","example":{"budget":"mid","include":{"entities":{"max_tokens":500}},"max_tokens":4096,"query":"What did Alice say about machine learning?","query_timestamp":"2023-05-30T23:40:00","trace":true,"types":["world","experience"]}}}}}}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"results":{"items":{"properties":{"id":{"type":"string","title":"Id"},"text":{"type":"string","title":"Text"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"entities":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Entities"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"occurred_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Occurred Start"},"occurred_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Occurred End"},"mentioned_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mentioned At"},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id"},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata"},"chunk_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Chunk Id"}},"type":"object","required":["id","text"],"title":"RecallResult","description":"Single recall result item.","example":{"chunk_id":"456e7890-e12b-34d5-a678-901234567890","context":"work info","document_id":"session_abc123","entities":["Alice","Google"],"id":"123e4567-e89b-12d3-a456-426614174000","mentioned_at":"2024-01-15T10:30:00Z","metadata":{"source":"slack"},"occurred_end":"2024-01-15T10:30:00Z","occurred_start":"2024-01-15T10:30:00Z","text":"Alice works at Google on the AI team","type":"world"}},"type":"array","title":"Results"},"trace":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Trace"},"entities":{"anyOf":[{"additionalProperties":{"properties":{"entity_id":{"type":"string","title":"Entity Id"},"canonical_name":{"type":"string","title":"Canonical Name"},"observations":{"items":{"properties":{"text":{"type":"string","title":"Text"},"mentioned_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mentioned At"}},"type":"object","required":["text"],"title":"EntityObservationResponse","description":"An observation about an entity."},"type":"array","title":"Observations"}},"type":"object","required":["entity_id","canonical_name","observations"],"title":"EntityStateResponse","description":"Current mental model of an entity."},"type":"object"},{"type":"null"}],"title":"Entities","description":"Entity states for entities mentioned in results"},"chunks":{"anyOf":[{"additionalProperties":{"properties":{"id":{"type":"string","title":"Id"},"text":{"type":"string","title":"Text"},"chunk_index":{"type":"integer","title":"Chunk Index"},"truncated":{"type":"boolean","title":"Truncated","description":"Whether the chunk text was truncated due to token limits","default":false}},"type":"object","required":["id","text","chunk_index"],"title":"ChunkData","description":"Chunk data for a single chunk."},"type":"object"},{"type":"null"}],"title":"Chunks","description":"Chunks for facts, keyed by chunk_id"}},"type":"object","required":["results"],"title":"RecallResponse","description":"Response model for recall endpoints.","example":{"chunks":{"456e7890-e12b-34d5-a678-901234567890":{"chunk_index":0,"id":"456e7890-e12b-34d5-a678-901234567890","text":"Alice works at Google on the AI team. She's been there for 3 years..."}},"entities":{"Alice":{"canonical_name":"Alice","entity_id":"123e4567-e89b-12d3-a456-426614174001","observations":[{"mentioned_at":"2024-01-15T10:30:00Z","text":"Alice works at Google on the AI team"}]}},"results":[{"chunk_id":"456e7890-e12b-34d5-a678-901234567890","context":"work info","entities":["Alice","Google"],"id":"123e4567-e89b-12d3-a456-426614174000","occurred_end":"2024-01-15T10:30:00Z","occurred_start":"2024-01-15T10:30:00Z","text":"Alice works at Google on the AI team","type":"world"}],"trace":{"num_results":1,"query":"What did Alice say about machine learning?","time_seconds":0.123}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,79 +0,0 @@
---
id: reflect
title: "Reflect and generate answer"
description: "Reflect and formulate an answer using bank identity, world facts, and opinions."
sidebar_label: "Reflect and generate answer"
hide_title: true
hide_table_of_contents: true
api: eJztWE1vGzcQ/SsDXmoD69WHZafdS+GkLmogqVPbaYE6RkAtR1rGFLklubIFQf+9GJIrraTYCYweWqA+CBbJGc68efNIask8nzpW3LJ3ODN2we4yJtCVVtZeGs0KdoUThaUHrgVMjJ01insEroFr94AWGif1FMZc34MUqL30iwwejFUCJrz0LguWppZaGu3yj/qjBgC4qaQD1KI2Uvsijg1yuEJvJc7RAT7WaCXqEuGgNHqO1nEKyQV/OEft3WG0G3btOluDRYVzrj14A75C+KtBu4g2x9t7SecpjTZMOKCEvnNQo3U1ll7Osd1tlMMHhw7evn1HfjuYQGm0x0ffcJXQiRYnOZw/ehtCouCdNxbp3wVofNhsSq5QRJvTEF9jtYNacamBHCevWUgmptg4FBHiriuWMVOjDYBdCFYwG6vIMlZzy2fo0VLVl0zzGbKCUbqfpGAZk1T0mvuKZcziX420KFjhbYMZc2WFM86KJfOLmsyct1JPWca89IoGXhMPLgRbre6iOTr/2ogF2ex6C2hpT1O8rpUsQ7i9z454t+xsVltKxkt09C0U8bkYfgsLVhkbN2KKwb/ACW+UZwVT5oGW7piibmbUBHF2FoCo5LSidlinFr3t9kccBoVzVKGEYLHkSvUS5LAuhMspqMSRkLVeXE5CFbbjWWXrEd0oxVadKN4k8xVVqlSNwJhfN6TL2rd8griIuM2FkDTOFQjuORwI6fhYoYDxAhJAh0SQLbQDy7aD3VqwWoNpxp8jw9pQfybTixhkCmkPvS+HGql9MOYOxSejD0FqaOG06BrlA5b7KG07T3snd77iPjROEi7pIGwARudwjUEkliv6RE24ZEBu6XsCCg4SSkU7Ig5ztnoGgaSdOxh8yWLTG7eJ4Hd7bq5iO+1hmMZhZgSqxMCIVauvOVH8kc9qFdjS9kWi+5qRLIiyjNXghDRyW1ZQ8xotGA1nF4C+kqVjW+xrOUKJpe5kfxDawsDCNOArqe+Bj03jgVsvJ7KUXIHUHpWSU9L4H9mK/ggIVxvtIvmG/f4+u6+bskTnJo2Cq7SYvVhM2lZ8SktuUq+1VKS10uPM7buS4qU9TXqZfXMocf5lO93Q+D8qQqYsG2tRfHKe2xc7vExe4Dp46fpF/WJc117Ptfhq14WE9puORGyv486CpISzl6Qp8rtl7k6zbbqrQq58VXKLpB9l4xx5ywJx2GB4jKOT01dH+P0P46PBUBwf8dHJ6dFoeHo6GA1ejfr9PtuFhQ37w9FRf3A0OLkZ9IvjftHv/8n2i/LUuhTY2QU1fZvNJszNQRkuVV0IubV8sXXuk/WlDlCls/b27oWYd9p6V+niREfqIvZPCd26a2+Xa5hfkHeWrEcnpxvri7aKKEgYO6rjQHHn4QHxfuNqc5+NHI1OXqcTCGYLaLRA6zzXdAZmEKPj4C3Xjq6GnG6h4LGstFFmusjzvFXN0XC4L5S/cyVFCAjOrTX25Sop0HOpntE+Zcqt2W/oVlL/KVq2unuaVW9NDJAEYeamz6njO3SOT7ErkE8tDWBAlMKvEJTyilundR2ybuCN6D6dxk8RvuduCr/c3LzfcxhrO0NfGWJfbVy8wPuKFaw3H/RSq/Xo9u56y3SJX/U2t32q7NXmGn7+b78EkMuJCdVrkZFaODmtPBBGcPb+Yk8W2okQ8np9Sor0u1i/c+IrF64XzuOMtlOyRJKazZKzmpcVwjAnvW2sIuX2vnZFr/fw8JDzMJ0bO+0lW9d7e/Hm/Nfr86Nh3s8rP1PkmB6sMbxB3s/7NEQFnHHd2av7uJ6ipodCez/dzXK5ad7/3+T/0Td56n4y6wUPxIpAsWVq61s2H3TO0Cw8zMm02LzQ2+6+y1hFklDcsuWSjroPVq1WNJz67/YuY3NuJT1Vghi3zxZWTLhy+AzDDq6SCh7CU3G3YqdJ6uZcNfSNZeweF50fFIK8V8gF2hBCnH0TNzoKIryx3juT6LyIFmdlibV/du1dRyvfX17fEHrppwe6L9CvIJykjj5DpCY9yOi3CRpbMsX1tKFjpGDRJ/39DTabij8=
sidebar_class_name: "post api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Reflect and generate answer"}
>
</Heading>
<MethodEndpoint
method={"post"}
path={"/v1/default/banks/{bank_id}/reflect"}
context={"endpoint"}
>
</MethodEndpoint>
Reflect and formulate an answer using bank identity, world facts, and opinions.
This endpoint:
1. Retrieves experience (conversations and events)
2. Retrieves world facts relevant to the query
3. Retrieves existing opinions (bank's perspectives)
4. Uses LLM to formulate a contextual answer
5. Extracts and stores any new opinions formed
6. Returns plain text answer, the facts used, and new opinions
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={{"required":true,"content":{"application/json":{"schema":{"properties":{"query":{"type":"string","title":"Query"},"budget":{"default":"low","type":"string","enum":["low","mid","high"],"title":"Budget","description":"Budget levels for recall/reflect operations."},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"include":{"description":"Options for including additional data (disabled by default)","properties":{"facts":{"anyOf":[{"properties":{},"type":"object","title":"FactsIncludeOptions","description":"Options for including facts (based_on) in reflect results."},{"type":"null"}],"description":"Include facts that the answer is based on. Set to {} to enable, null to disable (default: disabled)."}},"type":"object","title":"ReflectIncludeOptions"}},"type":"object","required":["query"],"title":"ReflectRequest","description":"Request model for reflect endpoint.","example":{"budget":"low","context":"This is for a research paper on AI ethics","include":{"facts":{}},"query":"What do you think about artificial intelligence?"}}}}}}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"text":{"type":"string","title":"Text"},"based_on":{"items":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"text":{"type":"string","title":"Text"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"occurred_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Occurred Start"},"occurred_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Occurred End"}},"type":"object","required":["text"],"title":"ReflectFact","description":"A fact used in think response.","example":{"context":"healthcare discussion","id":"123e4567-e89b-12d3-a456-426614174000","occurred_end":"2024-01-15T10:30:00Z","occurred_start":"2024-01-15T10:30:00Z","text":"AI is used in healthcare","type":"world"}},"type":"array","title":"Based On","default":[]}},"type":"object","required":["text"],"title":"ReflectResponse","description":"Response model for think endpoint.","example":{"based_on":[{"id":"123","text":"AI is used in healthcare","type":"world"},{"id":"456","text":"I discussed AI applications last week","type":"experience"}],"text":"Based on my understanding, AI is a transformative technology..."}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,71 +0,0 @@
---
id: regenerate-entity-observations
title: "Regenerate entity observations"
description: "Regenerate observations for an entity based on all facts mentioning it."
sidebar_label: "Regenerate entity observations"
hide_title: true
hide_table_of_contents: true
api: eJy9Vt9z4jYQ/lc0+9TOGGwTkmv9lqZpm87lkkloH8owjLAX0EWWfJIgx3j8v3dWtmMDhetcb8oLIO1+2h/ft1IJjq8sJFO4VU44gRZmAWRoUyMKJ7SCBJ5whQoNd8j0wqLZctqwbKkN44ohOe7YglvMmFaMS8mWPHWW5bSllVArJtwQAtAFwQit7jJIwLzhzmuMeR8eAii44Tk6NBRgCYrnCAksuHqZiwwCEBRdwd0aAjD4aSMMZpA4s8EAbLrGnENSgtsV5GadEWoFATjhJC38xNULu8ugqoI37CaOb4B+W1fF488IwBZaWbTkM4oi+tqv8vMmTdHa5Uayp8YYAki1cqgcmfOikCL1xQk/WvIpe3EUhorrG5iUILJzsVFQAaRcaSVSLud18qftb1pL9oEsqwCazs5TvamDa1yFcrhC0/O9ry3ZjbesAlgKY93cIvoEuNo9LH139w+nnjQraiMlUA1byF8IgT0TQhWA5P8R7j3voeXoeMYd3wfjWSYoCy4fe2WuqdDA6sVHTN3Zg+5b7CqAPaZTwxzm9riPDj+7c52Z0H7XD8zm3H1tHe5bDHbtSBQHmfVFMK0Dmx3S/aHLqsfhfZ5fq/4UYXyhN64bI0PoDubG8F0v2Yd+zb4UoJfwAcUPeXvQhqN0fkbHhTyZSbvBcp2h9OOwmYWZd2SoskIL5UcffuZ5Ib3MDoUHv+u1gn1lwCgajQdRPIgvJ3GUXERJFP1FQ4kGZzy6wPHl1bsB/vDjYhCPsosBH19eDcajq6t4HL8bR1EEe8po4EaDKJ7E4yRq4Q50HF8eMnNaHnDrVGA1U30q7FWbF8u4Y79qvZII1ayiTwDj0eh48P3JpchqMtwao83XT7267GfkJHW6t/svZNJOtGp2mpjvdR2gV6JdnRPsPVrLV9ix/MwNQsVgE9r9Etkpr/roxq5H5a68dXVPp1HT/R8Pa01+m0wejwDr3ubo1prYWWjr/OXt1pBAuI3DDJd8I11IN7cNy+YCr0Jsnhxh+XbvVmH3KvB38FL7GrXnC5VZsVo7RpGw68e7I1W2G16Pb/YNqXjqSdXo7h5zbXbseWcd5v4uESmS0juT64Kna2SjIQlqYyQksHausEkYvr6+DrnfHmqzChtfG76/u7n98Hw7GA2j4drlkoC3aGwdXjyMhhEtUZlyrnpn9d5ZzRw5eA/tJVp2KvmGL7Sm8aTmsJBceE77vMumo1PYxj4W31MI/HuMoku6h1nbWFrtP6l6vZ0FsCaiJFMoS4rsDyOripY/bdDsIJnOAthyI/iCOj8tIROWfmeQLLm0eKYc3z012vienUqplYAiAWy53NA/COAFd70nJs2B//HYrlR+2qyRZ2h87vX+dZpi4XqeR8OR7vM3IT4+PE+gqv4GjhQJJQ==
sidebar_class_name: "post api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Regenerate entity observations"}
>
</Heading>
<MethodEndpoint
method={"post"}
path={"/v1/default/banks/{bank_id}/entities/{entity_id}/regenerate"}
context={"endpoint"}
>
</MethodEndpoint>
Regenerate observations for an entity based on all facts mentioning it.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}},{"name":"entity_id","in":"path","required":true,"schema":{"type":"string","title":"Entity Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"id":{"type":"string","title":"Id"},"canonical_name":{"type":"string","title":"Canonical Name"},"mention_count":{"type":"integer","title":"Mention Count"},"first_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Seen"},"last_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Seen"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"observations":{"items":{"properties":{"text":{"type":"string","title":"Text"},"mentioned_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mentioned At"}},"type":"object","required":["text"],"title":"EntityObservationResponse","description":"An observation about an entity."},"type":"array","title":"Observations"}},"type":"object","required":["id","canonical_name","mention_count","observations"],"title":"EntityDetailResponse","description":"Response model for entity detail endpoint.","example":{"canonical_name":"John","first_seen":"2024-01-15T10:30:00Z","id":"123e4567-e89b-12d3-a456-426614174000","last_seen":"2024-02-01T14:00:00Z","mention_count":15,"observations":[{"mentioned_at":"2024-01-15T10:30:00Z","text":"John works at Google"}]}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,100 +0,0 @@
---
id: retain-memories
title: "Retain memories"
description: "Retain memory items with automatic fact extraction."
sidebar_label: "Retain memories"
hide_title: true
hide_table_of_contents: true
api: eJztWFtv27gS/isDvpwGUHxr+yJgH9I0uydAuw1S9xQ42cAYi2OLG4lUSSquYfi/L4aUZMlu0kX3ceuXxLzM9ZtvxtwJj2sn0jvxnkpjt+I+EZJcZlXlldEiFbfkUWkowzYoT6WDjfI5YO1NiV5lsMLMA331FjO+NPpD/6EBAOa5cqAc+JygZCGkZWWU9rAyFpw3Vul1lKzIjeDag6uryljvYGl8Dm6rs9wabWoHqCVgf6GyJiPnlF5HbY8Kg6ZwCCq0WJIn21nzK6GvLbk0fj2Hq9VKZYq0hyX6LD8ReA4XT7kIK2tK0CwQCyhQr2tcUydYe+W3YCkza63Ceba+UPqhJ/ytyeqStbNQ3jgOa105sh5ebHLSIJvTCyU5pJU1j0qSBKNjTs5asXMqK8NWsUpHJWqWdaT7Q8guH3oqom0GCdzWeSoPdmFRbJsYTkdwFWPiDqpW4WsIEKcjM9qT9vHCbAS/kSaLnhxQuSQplV67uPlyBG9J1lWhsrDvVKkKtFFgPPJqBJeWwq5v/Ew6zUlwmWLw2eHm0usRzDnErgsilORRosfWz88c4hCLX7ytqYPILfnaageqLEkq9FRsAVeeLHypqeacsYse3UN746aLIeRYVcSXdTi1xOxhbU2tZXv2k6OwYyqOiDLaHSrEGyiNVt5YTsvaknPfMHaFhSN4IWmFdeHPOrs/o+IcxMutPd5AZsqqIE/H/kWfsCi6agS0FEqUZKv3d+MphesVYJ8NIEcHOMCnz9EDFpZQboG+KuddEh0t5CEHnCy2spFVa/6yUUUBSwJJbKaEJa2MJcg46eyDpg0YTQ5eNNWxpBwflbFnTB8dN7EyhyUNzGKPOAEVSfBmTT4nG2JEHREcojUSiejyci1FKmwgwkUbIJGIjmOYQHdCY0kiFUvUDwslRSIU82eFPheJsPSlVpakSBlgiXBZTiWKdCf8tuJrzjMbikR45QteeIP6Aa6l2O/v43Vy/o2RW75zLK0pMt7CKhaQMnr8p2MK3/WUVZad8mx/uhOBOQb/DPd7Yp+y8rI5suelkpzHsgpm6O2HVQjL8c2VsSV6kQqJns75ktgn3TFdF4Vgj1sF807qvvHzq39OwXOyLpvr+0S0DDAUhVKqyIw3g0Acq2gXzPJPyvyzOt+3ivaJ6KHxR13ousY1I2zYqjtW72rs+m0AuOdG3KvZkdif+NCH6F2X+YEjfJ+L7ETxR6XXBQ1YgdXGiuFKoq/IxDPAlLgoVMaXNEshCS6n/zjYGBuaITfNUO7v30FpJBWil37hCUsoiXzE1CCwollfaOPJLWaT2avFZLqYvhbDtGc5ak2FSAXptdJEDUCdqW0W0lFg9nCEbMHizifT8+nr+XSSvpykk8n/++FEa3HbK5DASiwkMHYPTEtjCkLdO3oRThwH93oFochbchr07GLL7eXQWkbMz6ErJLBBFSethvV5DmlbRRoPnQVtYUWkYeV7wIhM0YNFnA9vIz+dGN+sxwz2QNE1uiN0NEGKHrS0dHeKGkaJA/TwmzHrggbY4L0TTGRGP5J1gRcX09nLUGQHqW/MEjZcMbkK6NuS82RlyOR3BD0Hj0kDj/s9fziSrjLaRVKZTSb856iU6oyTvKoLuG0Oix/mdxeFPQu6RiEjtO1cf6cpNclZZKYeNAilPa3JHhcAXIZz/6AMPuexYQ8GJthgN7aSPKqM75JcG56k37N7XrXGfgPtXWaO4R43fhDvXQJE7chGcA3CPEsOOWVSaGD1ajY7RdL/sFAyRunKWmN/HEaSXSiemRMKkw12/0Zja3Gyv3+aOt+ZaGDo1279HC7fk3O4pkNrfvpoCAbMefd7AGG/ourmXA8Jh/DG6D7txtsYvm8pa4/8dz6/OREYc1uSzw1DojKBX8M8mYrx43TcMPeYYePGuwY9+3FvROXU3h5mx6t/AdPy3L0yAQFtdJWWTq1zDxxnuLi5PincdiOUbHe+cRazUDLNfB/nIPgYfhZz2jlMTAaHIxcVZjnBbDQRiagtjxi595VLx+PNZjPCsD0ydj1u7rrxu+vLq98/Xp3PRpNR7suCBbP30bzpaDKa8BKDoETd09V/n4k5H3jWD/3Pp5yfTzk/n3J+PuX8C59ymsbLfWtcFajCTBGYedd01DvxOO39GorDGNNpehgOO5K9T0TO7Ti9E7vdEh19ssV+z8tfarJbkd7dJ+IRrcIld6C7nZDK8f+y67hPsvSL22YCOYOnDG8HDc1N8xGLmr+JRDzQtvcAFXphTijJBhPibvNgcx4GoMPtk3mQu3a8cZFlVPlnz9735pSbDx/nHL7mqYonYX49ww0PV7iJlprgeBgWw9pOtMwrUhFl8ucvTySJXQ==
sidebar_class_name: "post api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Retain memories"}
>
</Heading>
<MethodEndpoint
method={"post"}
path={"/v1/default/banks/{bank_id}/memories"}
context={"endpoint"}
>
</MethodEndpoint>
Retain memory items with automatic fact extraction.
This is the main endpoint for storing memories. It supports both synchronous and asynchronous processing
via the async parameter.
Features:
- Efficient batch processing
- Automatic fact extraction from natural language
- Entity recognition and linking
- Document tracking with automatic upsert (when document_id is provided on items)
- Temporal and semantic linking
- Optional asynchronous processing
The system automatically:
1. Extracts semantic facts from the content
2. Generates embeddings
3. Deduplicates similar facts
4. Creates temporal, semantic, and entity links
5. Tracks document metadata
When async=true:
- Returns immediately after queuing the task
- Processing happens in the background
- Use the operations endpoint to monitor progress
When async=false (default):
- Waits for processing to complete
- Returns after all memories are stored
Note: If a memory item has a document_id that already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). Items with the same document_id are grouped together for efficient processing.
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={{"required":true,"content":{"application/json":{"schema":{"properties":{"items":{"items":{"properties":{"content":{"type":"string","title":"Content"},"timestamp":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata"},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id","description":"Optional document ID for this memory item."}},"type":"object","required":["content"],"title":"MemoryItem","description":"Single memory item for retain.","example":{"content":"Alice mentioned she's working on a new ML model","context":"team meeting","document_id":"meeting_notes_2024_01_15","metadata":{"channel":"engineering","source":"slack"},"timestamp":"2024-01-15T10:30:00Z"}},"type":"array","title":"Items"},"async":{"type":"boolean","title":"Async","description":"If true, process asynchronously in background. If false, wait for completion (default: false)","default":false}},"type":"object","required":["items"],"title":"RetainRequest","description":"Request model for retain endpoint.","example":{"async":false,"items":[{"content":"Alice works at Google","context":"work","document_id":"conversation_123"},{"content":"Bob went hiking yesterday","document_id":"conversation_123","timestamp":"2024-01-15T10:00:00Z"}]}}}}}}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","title":"Success"},"bank_id":{"type":"string","title":"Bank Id"},"items_count":{"type":"integer","title":"Items Count"},"async":{"type":"boolean","title":"Async","description":"Whether the operation was processed asynchronously"}},"type":"object","required":["success","bank_id","items_count","async"],"title":"RetainResponse","description":"Response model for retain endpoint.","example":{"async":false,"bank_id":"user123","items_count":2,"success":true}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,186 +0,0 @@
import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";
const sidebar: SidebarsConfig = {
apisidebar: [
{
type: "doc",
id: "api-reference/endpoints/hindsight-http-api",
},
{
type: "category",
label: "Monitoring",
items: [
{
type: "doc",
id: "api-reference/endpoints/health-endpoint-health-get",
label: "Health check endpoint",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/metrics-endpoint-metrics-get",
label: "Prometheus metrics endpoint",
className: "api-method get",
},
],
},
{
type: "category",
label: "Memory",
items: [
{
type: "doc",
id: "api-reference/endpoints/get-graph",
label: "Get memory graph data",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/list-memories",
label: "List memory units",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/recall-memories",
label: "Recall memory",
className: "api-method post",
},
{
type: "doc",
id: "api-reference/endpoints/reflect",
label: "Reflect and generate answer",
className: "api-method post",
},
{
type: "doc",
id: "api-reference/endpoints/retain-memories",
label: "Retain memories",
className: "api-method post",
},
{
type: "doc",
id: "api-reference/endpoints/clear-bank-memories",
label: "Clear memory bank memories",
className: "api-method delete",
},
],
},
{
type: "category",
label: "Banks",
items: [
{
type: "doc",
id: "api-reference/endpoints/list-banks",
label: "List all memory banks",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/get-agent-stats",
label: "Get statistics for memory bank",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/get-bank-profile",
label: "Get memory bank profile",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/update-bank-disposition",
label: "Update memory bank disposition",
className: "api-method put",
},
{
type: "doc",
id: "api-reference/endpoints/add-bank-background",
label: "Add/merge memory bank background",
className: "api-method post",
},
{
type: "doc",
id: "api-reference/endpoints/create-or-update-bank",
label: "Create or update memory bank",
className: "api-method put",
},
],
},
{
type: "category",
label: "Entities",
items: [
{
type: "doc",
id: "api-reference/endpoints/list-entities",
label: "List entities",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/get-entity",
label: "Get entity details",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/regenerate-entity-observations",
label: "Regenerate entity observations",
className: "api-method post",
},
],
},
{
type: "category",
label: "Documents",
items: [
{
type: "doc",
id: "api-reference/endpoints/list-documents",
label: "List documents",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/get-document",
label: "Get document details",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/delete-document",
label: "Delete a document",
className: "api-method delete",
},
{
type: "doc",
id: "api-reference/endpoints/get-chunk",
label: "Get chunk details",
className: "api-method get",
},
],
},
{
type: "category",
label: "Operations",
items: [
{
type: "doc",
id: "api-reference/endpoints/list-operations",
label: "List async operations",
className: "api-method get",
},
{
type: "doc",
id: "api-reference/endpoints/cancel-operation",
label: "Cancel a pending async operation",
className: "api-method delete",
},
],
},
],
};
export default sidebar.apisidebar;
@@ -1,71 +0,0 @@
---
id: update-bank-disposition
title: "Update memory bank disposition"
description: "Update bank's disposition traits (skepticism, literalism, empathy)"
sidebar_label: "Update memory bank disposition"
hide_title: true
hide_table_of_contents: true
api: eJztV8tu2zoQ/RViNjcBWL9yuxHQRdoEaIC0DfK4m8AoaGlssaFIlqTsGIb+vRhKjqQojyK4q6JeyeLM8MzwnCNpB0GsPCS38FHoOw9zDhn61EkbpNGQwI3NREC2EPruH88y6a3xktZYcEIGzw78HdogU+kLzpQM6ISK11hYEfLtIXAwFp2gpLMMEihjye9U8nunIHCwwokCAzpCtAMtCoQEYqDMgIMkRFQVODj8WUqHGSTBlcjBpzkWApIdhK2lNB+c1CvgEGRQdIM6ZGcZVNW8TkcfPppsSzmPq6VGB9SBloS1SqYR/viHp6HsOptZR80FiZ7+ddsZLLaD6qCUOuAKHXAoxL0sygKS9xwKqevraQv/qk1/fEifzYY11YVia8+CK32QesUOph/215y9//AQdAgVh/a03gTovE1/ClBTXW1ZMIyqOuswMKmXxhVxnIRuqfBeLhQSuiYjYmvY8yZgp03uU6iKMs0JUGq0lxk6hoWhZaFYPPP7QKgyDCLNMSNUNRIMMj2EquJ7OGbxA9PQI+Jt94h74237mbcwT1qyXEctDQCfDOUWchFnqErUKbKcWsLCOImeCYeMhosZEzprZ47ZiBDci8LSxrt2uEd9EhzxHkmPqtf67fK901ltGh30l7XaBg0291lhMlSEnUVzIOYOrWYEVQTk0FujfS2q2WQShdcre1WmKXq/LBW7bILhzZre28/vOAtvPOv50K+0XvG/TvHXKf4sp+CwEOndyplSv6KVh6jXZtQ++KOq+qLp7Tfva/HCmaVU2NH+Y9upFzq+Q3sxW+c9mkG3LzhjomCCebMMG5oi6pXUiI5tZMjZdMK2KJxnZsnw3qKTcfZSMx+EC6X1EXdjKFB6dNPZEQzs4LfHvjccOFYyxWiQFYd/Z7OhKf4nlMxqNZ06Z9zbHZE4LxVdyYCFHwYok/ZWhd5+W8ZXuj4rKj7QbDVvSSGcE9sOdc5NDZBUX/jVSyz7gt6LVXTaOuT50DgMdk2rrxGS+qq3buI6vGvHW0/3+TZO6vE9tdk+5PP19cWgYH22BYbcEHlsGeIrc8ghgfF6Os5wKUoVxsQvP941NKvGDauBAx3sZfvie9py/K38q+ilfGnifPfYpc68XOWBURfs+OJsaK/NQlTeQ3xDSJFGQja8/kKWtWVXWx+wqB9FKZKm25BjSw7MZqMJcCidggTyEKxPxuPNZjMScXlk3Grc5Prx+dmn069Xp+9mo8koD4Wiwmt0voY3HU1GE7pljQ+F0J29ms+hokYVTaNvSr1Gd63C/p8PqYYv9PAZWyVklEJsedcw4RbW0wgjcqFxG3KdpHXTPSHmHHLjAyXtdgvh8capqqLbP0t0W0hu5xzWwkmxoJO9jTSh6wySpVAeX2j34LLRzSF7DvdeHprEsRaqpH/A4Q63na++aAg5igxdhFCvfqo3ehdl22YPXIwcps44TlO04cXYeUddFzfXNLzm85CeE5CAExtyBLGpgZrYd3S4eG8HSuhVSb6TQF2Sfr8A8RRWiA==
sidebar_class_name: "put api-method"
info_path: docs/api-reference/endpoints/hindsight-http-api
custom_edit_url: null
---
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";
<Heading
as={"h1"}
className={"openapi__heading"}
children={"Update memory bank disposition"}
>
</Heading>
<MethodEndpoint
method={"put"}
path={"/v1/default/banks/{bank_id}/profile"}
context={"endpoint"}
>
</MethodEndpoint>
Update bank's disposition traits (skepticism, literalism, empathy)
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"bank_id","in":"path","required":true,"schema":{"type":"string","title":"Bank Id"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={{"required":true,"content":{"application/json":{"schema":{"properties":{"disposition":{"properties":{"skepticism":{"type":"integer","maximum":5,"minimum":1,"title":"Skepticism","description":"How skeptical vs trusting (1=trusting, 5=skeptical)"},"literalism":{"type":"integer","maximum":5,"minimum":1,"title":"Literalism","description":"How literally to interpret information (1=flexible, 5=literal)"},"empathy":{"type":"integer","maximum":5,"minimum":1,"title":"Empathy","description":"How much to consider emotional context (1=detached, 5=empathetic)"}},"type":"object","required":["skepticism","literalism","empathy"],"title":"DispositionTraits","description":"Disposition traits that influence how memories are formed and interpreted.","example":{"empathy":3,"literalism":3,"skepticism":3}}},"type":"object","required":["disposition"],"title":"UpdateDispositionRequest","description":"Request model for updating disposition traits."}}}}}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"bank_id":{"type":"string","title":"Bank Id"},"name":{"type":"string","title":"Name"},"disposition":{"properties":{"skepticism":{"type":"integer","maximum":5,"minimum":1,"title":"Skepticism","description":"How skeptical vs trusting (1=trusting, 5=skeptical)"},"literalism":{"type":"integer","maximum":5,"minimum":1,"title":"Literalism","description":"How literally to interpret information (1=flexible, 5=literal)"},"empathy":{"type":"integer","maximum":5,"minimum":1,"title":"Empathy","description":"How much to consider emotional context (1=detached, 5=empathetic)"}},"type":"object","required":["skepticism","literalism","empathy"],"title":"DispositionTraits","description":"Disposition traits that influence how memories are formed and interpreted.","example":{"empathy":3,"literalism":3,"skepticism":3}},"background":{"type":"string","title":"Background"}},"type":"object","required":["bank_id","name","disposition","background"],"title":"BankProfileResponse","description":"Response model for bank profile.","example":{"background":"I am a software engineer with 10 years of experience in startups","bank_id":"user123","disposition":{"empathy":3,"literalism":3,"skepticism":3},"name":"Alice"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"}}}}}}
>
</StatusCodes>
@@ -1,41 +0,0 @@
---
sidebar_position: 1
---
# API Reference
Complete reference for Hindsight's HTTP and MCP APIs.
## HTTP API
The HTTP API reference is automatically generated from our OpenAPI specification. Browse the endpoints in the sidebar to see request/response details, parameters, and examples.
**Base URL:** `http://localhost:8888`
| Category | Endpoints |
|----------|-----------|
| **Memory Operations** | Store, search, list, delete memories |
| **Reasoning** | Think and generate personality-aware responses |
| **Memory bank Management** | Create, update, list memory banks and profiles |
| **Documents** | Manage document groupings |
| **Visualization** | Get entity graph data |
## MCP API
The MCP (Model Context Protocol) API exposes Hindsight tools for AI assistants like Claude Desktop.
| Tool | Description |
|------|-------------|
| `hindsight_search` | Search memories |
| `hindsight_think` | Generate personality-aware response |
| `hindsight_store` | Store new memory |
| `hindsight_agents` | List available memory banks |
[MCP Tools Reference →](/api-reference/mcp)
## OpenAPI / Swagger
Interactive API documentation available when the server is running:
- **Swagger UI:** [http://localhost:8888/docs](http://localhost:8888/docs)
- **OpenAPI JSON:** [http://localhost:8888/openapi.json](http://localhost:8888/openapi.json)
-100
View File
@@ -1,100 +0,0 @@
---
sidebar_position: 3
---
# MCP API
Model Context Protocol (MCP) tools exposed by the Hindsight MCP server.
## Endpoint
```
/mcp/{bank_id}/sse
```
The `bank_id` is extracted from the URL path and used for all tool operations. The MCP server uses Server-Sent Events (SSE) transport.
## Available Tools
### retain
Store a new memory.
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string | yes | Memory content to store |
| `context` | string | no | Category for the memory (default: 'general') |
**Example:**
```json
{
"name": "retain",
"arguments": {
"content": "User prefers Python for data analysis",
"context": "preferences"
}
}
```
**Response:**
```
Memory stored successfully
```
---
### recall
Search memories.
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `query` | string | yes | Natural language search query |
| `max_results` | integer | no | Maximum results to return (default: 10) |
**Example:**
```json
{
"name": "recall",
"arguments": {
"query": "What does the user do for work?"
}
}
```
**Response:**
```json
{
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"text": "User works at Google as a software engineer",
"type": "world",
"context": "work",
"event_date": null
}
]
}
```
---
## Usage Guidelines
**When to use `retain`:**
- User shares personal facts, preferences, or interests
- Important events or milestones are mentioned
- Decisions, opinions, or goals are stated
**When to use `recall`:**
- Start of conversation to get user context
- Before making recommendations
- To provide continuity across conversations
@@ -258,6 +258,6 @@ await sdk.regenerateEntityObservations({
## Next Steps
- [**Memory Banks**](./memory-banks) — Configure bank personality
- [**Memory Banks**](./memory-banks) — Configure bank disposition
- [**Documents**](./documents) — Track document sources
- [**Operations**](./operations) — Monitor background tasks
@@ -206,9 +206,9 @@ hindsight recall my-bank "Tell me about Alice" -v
---
## Reflect: Reason with Personality
## Reflect: Reason with Disposition
Generate personality-aware responses that form opinions based on evidence.
Generate disposition-aware responses that form opinions based on evidence.
<Tabs>
<TabItem value="python" label="Python">
@@ -288,9 +288,9 @@ hindsight reflect my-bank "Analyze our tech stack" --budget high
</TabItem>
</Tabs>
**What happens:** Memories are recalled, bank personality is loaded, LLM reasons through evidence, new opinions are formed and stored.
**What happens:** Memories are recalled, bank disposition is loaded, LLM reasons through evidence, new opinions are formed and stored.
**See:** [Reflect Details](./reflect) for personality configuration.
**See:** [Reflect Details](./reflect) for disposition configuration.
---
@@ -303,7 +303,7 @@ hindsight reflect my-bank "Analyze our tech stack" --budget high
| **Output** | Memory IDs | Ranked facts | Reasoned response + opinions |
| **Uses LLM** | Yes (extraction) | No | Yes (generation) |
| **Forms opinions** | No | No | Yes |
| **Personality** | No | No | Yes |
| **Disposition** | No | No | Yes |
---
@@ -311,5 +311,5 @@ hindsight reflect my-bank "Analyze our tech stack" --budget high
- [**Retain**](./retain) — Advanced options for storing memories
- [**Recall**](./recall) — Tuning search quality and performance
- [**Reflect**](./reflect) — Configuring personality and opinions
- [**Memory Banks**](./memory-banks) — Managing memory bank personality
- [**Reflect**](./reflect) — Configuring disposition and opinions
- [**Memory Banks**](./memory-banks) — Managing memory bank disposition
+71 -117
View File
@@ -4,8 +4,8 @@ sidebar_position: 6
# Memory Bank
Configure memory bank personality, background, and behavior.
Memory banks have charateristics:
Configure memory bank disposition, background, and behavior.
Memory banks have characteristics:
- Banks are completely isolated from each other.
- You don't need to pre-create it, Hindsight will create it for you with default settings.
- Banks have a profile that influences how they form opinions from memories. (optional)
@@ -31,13 +31,10 @@ client.create_bank(
bank_id="my-bank",
name="Research Assistant",
background="I am a research assistant specializing in machine learning",
personality={
"openness": 0.8,
"conscientiousness": 0.7,
"extraversion": 0.5,
"agreeableness": 0.6,
"neuroticism": 0.3,
"bias_strength": 0.5
disposition={
"skepticism": 4, # Questions claims, wants evidence
"literalism": 3, # Balanced interpretation
"empathy": 3 # Balanced emotional consideration
}
)
```
@@ -53,13 +50,10 @@ 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',
personality: {
openness: 0.8,
conscientiousness: 0.7,
extraversion: 0.5,
agreeableness: 0.6,
neuroticism: 0.3,
bias_strength: 0.5
disposition: {
skepticism: 4,
literalism: 3,
empathy: 3
}
});
```
@@ -69,83 +63,58 @@ await client.createBank('my-bank', {
```bash
# Set background
hindsight agent background my-bank "I am a research assistant specializing in ML"
hindsight bank background my-bank "I am a research assistant specializing in ML"
# Set personality
hindsight agent personality my-bank \
--openness 0.8 \
--conscientiousness 0.7 \
--extraversion 0.5 \
--agreeableness 0.6 \
--neuroticism 0.3 \
--bias-strength 0.5
# Set disposition
hindsight bank disposition my-bank \
--skepticism 4 \
--literalism 3 \
--empathy 3
```
</TabItem>
</Tabs>
## Personality Traits (Big Five)
## Disposition Traits
Each trait is scored 0.0 to 1.0:
Each trait is scored 1 to 5:
| Trait | Low (0.0) | High (1.0) |
|-------|-----------|------------|
| **Openness** | Conventional, prefers proven methods | Curious, embraces new ideas |
| **Conscientiousness** | Flexible, spontaneous | Organized, systematic |
| **Extraversion** | Reserved, independent | Outgoing, collaborative |
| **Agreeableness** | Direct, analytical | Cooperative, diplomatic |
| **Neuroticism** | Calm, optimistic | Risk-aware, cautious |
| Trait | Low (1) | High (5) |
|-------|---------|----------|
| **Skepticism** | Trusting, accepts information at face value | Skeptical, questions and doubts claims |
| **Literalism** | Flexible interpretation, reads between the lines | Literal interpretation, takes things exactly as stated |
| **Empathy** | Detached, focuses on facts and logic | Empathetic, considers emotional context |
### How Traits Affect Behavior
**Openness** influences how the bank weighs new vs. established ideas:
**Skepticism** influences how the bank evaluates claims:
```python
# High openness bank
"Let's try this new framework—it looks promising!"
# High skepticism (5)
"What's the source for this? Have these results been replicated?"
# Low openness bank
"Let's stick with the proven solution we know works."
# Low skepticism (1)
"That sounds reasonable, let's proceed with that assumption."
```
**Conscientiousness** affects structure and thoroughness:
**Literalism** affects interpretation:
```python
# High conscientiousness bank
"Here's a detailed, step-by-step analysis..."
# High literalism (5)
"The requirement says 'users' - that means all users, no exceptions."
# Low conscientiousness bank
"Quick take: this should work, let's try it."
# Low literalism (1)
"When they say 'users', they probably mean active users in this context."
```
**Extraversion** shapes collaboration preferences:
**Empathy** shapes how emotional context is considered:
```python
# High extraversion bank
"We should get the team together to discuss this."
# High empathy (5)
"I understand this is frustrating. Let's find a solution that works for you."
# Low extraversion bank
"I'll analyze this independently and share my findings."
```
**Agreeableness** affects how disagreements are handled:
```python
# High agreeableness bank
"That's a valid point. Perhaps we can find a middle ground..."
# Low agreeableness bank
"Actually, the data doesn't support that conclusion."
```
**Neuroticism** influences risk assessment:
```python
# High neuroticism bank
"We should consider what could go wrong here..."
# Low neuroticism bank
"The risks seem manageable, let's proceed."
# Low empathy (1)
"Here are the facts: Option A has 20% better performance than Option B."
```
## Background
@@ -201,7 +170,7 @@ profile = api.get_bank_profile("my-bank")
print(f"Name: {profile.name}")
print(f"Background: {profile.background}")
print(f"Personality: {profile.personality}")
print(f"Disposition: {profile.disposition}")
```
</TabItem>
@@ -212,14 +181,14 @@ const profile = await client.getBankProfile('my-bank');
console.log(`Name: ${profile.name}`);
console.log(`Background: ${profile.background}`);
console.log(`Personality:`, profile.personality);
console.log(`Disposition:`, profile.disposition);
```
</TabItem>
<TabItem value="cli" label="CLI">
```bash
hindsight agent profile my-bank
hindsight bank profile my-bank
```
</TabItem>
@@ -231,28 +200,25 @@ If not specified, banks use neutral defaults:
```python
{
"openness": 0.5,
"conscientiousness": 0.5,
"extraversion": 0.5,
"agreeableness": 0.5,
"neuroticism": 0.5,
"bias_strength": 0.5,
"skepticism": 3,
"literalism": 3,
"empathy": 3,
"background": ""
}
```
## Personality Templates
## Disposition Templates
Common personality configurations:
Common disposition configurations:
| Use Case | O | C | E | A | N | Bias |
|----------|---|---|---|---|---|------|
| **Customer Support** | 0.5 | 0.7 | 0.6 | 0.9 | 0.3 | 0.4 |
| **Code Reviewer** | 0.4 | 0.9 | 0.3 | 0.4 | 0.5 | 0.6 |
| **Creative Writer** | 0.9 | 0.4 | 0.7 | 0.6 | 0.5 | 0.7 |
| **Risk Analyst** | 0.3 | 0.9 | 0.3 | 0.4 | 0.8 | 0.6 |
| **Research Assistant** | 0.8 | 0.8 | 0.4 | 0.5 | 0.4 | 0.5 |
| **Neutral (default)** | 0.5 | 0.5 | 0.5 | 0.5 | 0.5 | 0.5 |
| Use Case | Skepticism | Literalism | Empathy |
|----------|------------|------------|---------|
| **Customer Support** | 2 | 2 | 5 |
| **Code Reviewer** | 4 | 5 | 2 |
| **Legal Analyst** | 5 | 5 | 2 |
| **Therapist/Coach** | 2 | 2 | 5 |
| **Research Assistant** | 4 | 3 | 3 |
| **Neutral (default)** | 3 | 3 | 3 |
<Tabs>
<TabItem value="python" label="Python">
@@ -262,13 +228,10 @@ Common personality configurations:
client.create_bank(
bank_id="support",
background="I am a friendly customer support agent",
personality={
"openness": 0.5,
"conscientiousness": 0.7,
"extraversion": 0.6,
"agreeableness": 0.9, # Very diplomatic
"neuroticism": 0.3, # Calm under pressure
"bias_strength": 0.4
disposition={
"skepticism": 2, # Trusting
"literalism": 2, # Flexible interpretation
"empathy": 5 # Very empathetic
}
)
@@ -276,13 +239,10 @@ client.create_bank(
client.create_bank(
bank_id="reviewer",
background="I am a thorough code reviewer focused on quality",
personality={
"openness": 0.4, # Prefers proven patterns
"conscientiousness": 0.9, # Very thorough
"extraversion": 0.3,
"agreeableness": 0.4, # Direct feedback
"neuroticism": 0.5,
"bias_strength": 0.6
disposition={
"skepticism": 4, # Questions assumptions
"literalism": 5, # Exact interpretation
"empathy": 2 # Direct, fact-focused
}
)
```
@@ -294,26 +254,20 @@ client.create_bank(
// Customer support bank
await client.createBank('support', {
background: 'I am a friendly customer support agent',
personality: {
openness: 0.5,
conscientiousness: 0.7,
extraversion: 0.6,
agreeableness: 0.9,
neuroticism: 0.3,
bias_strength: 0.4
disposition: {
skepticism: 2,
literalism: 2,
empathy: 5
}
});
// Code reviewer bank
await client.createBank('reviewer', {
background: 'I am a thorough code reviewer focused on quality',
personality: {
openness: 0.4,
conscientiousness: 0.9,
extraversion: 0.3,
agreeableness: 0.4,
neuroticism: 0.5,
bias_strength: 0.6
disposition: {
skepticism: 4,
literalism: 5,
empathy: 2
}
});
```
@@ -325,7 +279,7 @@ await client.createBank('reviewer', {
Each bank has:
- **Separate memories** — banks don't share memories
- **Own personality** — traits are per-bank
- **Own disposition** — traits are per-bank
- **Independent opinions** — formed from their own experiences
<Tabs>
+30 -54
View File
@@ -15,7 +15,7 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
## What Are Opinions?
Opinions are beliefs formed by the memory bank based on evidence and personality. Unlike world facts (objective information received) or experience (conversations and events), opinions are **judgments** with confidence scores.
Opinions are beliefs formed by the memory bank based on evidence and disposition. Unlike world facts (objective information received) or experience (conversations and events), opinions are **judgments** with confidence scores.
| Type | Example | Confidence |
|------|---------|------------|
@@ -25,16 +25,16 @@ Opinions are beliefs formed by the memory bank based on evidence and personality
## How Opinions Form
Opinions are created during `think` operations when the memory bank:
Opinions are created during `reflect` operations when the memory bank:
1. Retrieves relevant facts
2. Applies personality traits
2. Applies disposition traits
3. Forms a judgment
4. Assigns a confidence score
```mermaid
graph LR
F[Facts] --> P[Personality Filter]
P --> J[Judgment]
F[Facts] --> D[Disposition Filter]
D --> J[Judgment]
J --> O[Opinion + Confidence]
O --> S[(Store)]
```
@@ -44,13 +44,13 @@ graph LR
```python
# Ask a question that might form an opinion
answer = client.think(
agent_id="my-agent",
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["new_opinions"]:
for opinion in answer.get("new_opinions", []):
print(f"New opinion: {opinion['text']}")
print(f"Confidence: {opinion['confidence']}")
```
@@ -65,10 +65,10 @@ for opinion in answer["new_opinions"]:
```python
# Search only opinions
opinions = client.search_memories(
agent_id="my-agent",
opinions = client.recall(
bank_id="my-bank",
query="programming languages",
fact_type=["opinion"]
types=["opinion"]
)
for op in opinions:
@@ -79,7 +79,7 @@ for op in opinions:
<TabItem value="cli" label="CLI">
```bash
hindsight memory search my-agent "programming" --fact-type opinion
hindsight recall my-bank "programming" --types opinion
```
</TabItem>
@@ -107,23 +107,23 @@ t=2: "Python is best for data science, though Julia is faster" (0.75)
t=3: "Python is best for data science" (0.82)
```
## Personality Influence
## Disposition Influence
Different personalities form different opinions from the same facts:
Different dispositions form different opinions from the same facts:
<Tabs>
<TabItem value="python" label="Python">
```python
# Create two memory banks with different personalities
client.create_agent(
agent_id="open-minded",
personality={"openness": 0.9, "conscientiousness": 0.3, "bias_strength": 0.7}
# Create two memory banks with different dispositions
client.create_bank(
bank_id="open-minded",
disposition={"skepticism": 2, "literalism": 2, "empathy": 4}
)
client.create_agent(
agent_id="conservative",
personality={"openness": 0.2, "conscientiousness": 0.9, "bias_strength": 0.7}
client.create_bank(
bank_id="conservative",
disposition={"skepticism": 5, "literalism": 5, "empathy": 2}
)
# Store the same facts to both
@@ -133,59 +133,35 @@ facts = [
"Rust compile times are longer than C++"
]
for fact in facts:
client.store(agent_id="open-minded", content=fact)
client.store(agent_id="conservative", content=fact)
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.think(agent_id="open-minded", query=q)
answer1 = client.reflect(bank_id="open-minded", query=q)
# Likely: "Yes, Rust's safety benefits outweigh migration costs"
answer2 = client.think(agent_id="conservative", query=q)
answer2 = client.reflect(bank_id="conservative", query=q)
# Likely: "No, C++'s ecosystem and our team's expertise make it the safer choice"
```
</TabItem>
</Tabs>
## Bias Strength
## Opinions in Reflect Responses
The `bias_strength` parameter (0-1) controls how much personality influences opinions:
| Value | Behavior |
|-------|----------|
| 0.0 | Pure evidence-based reasoning |
| 0.5 | Balanced personality + evidence |
| 1.0 | Strongly personality-driven |
When `reflect` uses opinions, they appear in `based_on`:
```python
# Evidence-focused agent
client.create_agent(
agent_id="analyst",
personality={"bias_strength": 0.2} # Low bias
)
# Personality-driven agent
client.create_agent(
agent_id="advisor",
personality={"bias_strength": 0.8} # High bias
)
```
## Opinions in Think Responses
When `think` uses opinions, they appear in `based_on`:
```python
answer = client.think(agent_id="my-agent", query="What language should I learn?")
answer = client.reflect(bank_id="my-bank", query="What language should I learn?")
print("World facts used:")
for f in answer["based_on"]["world"]:
for f in answer.based_on.get("world", []):
print(f" {f['text']}")
print("\nOpinions used:")
for o in answer["based_on"]["opinion"]:
for o in answer.based_on.get("opinion", []):
print(f" {o['text']} (confidence: {o['confidence_score']})")
```
+16 -12
View File
@@ -9,15 +9,15 @@ Get up and running with Hindsight in 60 seconds.
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## Start the Server
## Start the API Server
<Tabs>
<TabItem value="pip" label="pip (API only)">
```bash
pip install hindsight-all
export HINDSIGHT_API_LLM_PROVIDER=groq
export HINDSIGHT_API_LLM_API_KEY=gsk_xxxxxxxxxxxx
pip install hindsight-api
export OPENAI_API_KEY=sk-xxx
export HINDSIGHT_API_LLM_API_KEY=$OPENAI_API_KEY
hindsight-api
```
@@ -28,9 +28,12 @@ API available at http://localhost:8888
<TabItem value="docker" label="Docker (Full Experience)">
```bash
docker run -p 8888:8888 -p 9999:9999 \
-e HINDSIGHT_API_LLM_PROVIDER=groq \
-e HINDSIGHT_API_LLM_API_KEY=gsk_xxxxxxxxxxxx \
export OPENAI_API_KEY=sk-xxx
docker run -it -p 8888:8888 -p 9999:9999 \
-e HINDSIGHT_API_LLM_API_KEY=$OPENAI_API_KEY \
-v $HOME/.hindsight-docker:/home/hindsight/.pg0 \
ghcr.io/vectorize-io/hindsight
```
@@ -41,7 +44,8 @@ docker run -p 8888:8888 -p 9999:9999 \
</Tabs>
:::tip LLM Provider
Hindsight requires an LLM with structured output support. Recommended: **Groq** with `gpt-oss-20b` for fast, cost-effective inference. Also supports OpenAI and Ollama.
Hindsight requires an LLM with structured output support. Recommended: **Groq** with `gpt-oss-20b` for fast, cost-effective inference.
See [LLM Providers](/developer/models#llm) for more details.
:::
---
@@ -66,7 +70,7 @@ client.retain(bank_id="my-bank", content="Alice works at Google as a software en
# Recall: Search memories
client.recall(bank_id="my-bank", query="What does Alice do?")
# Reflect: Generate personality-aware response
# Reflect: Generate disposition-aware response
client.reflect(bank_id="my-bank", query="Tell me about Alice")
```
@@ -121,7 +125,7 @@ hindsight memory reflect my-bank "Tell me about Alice"
|-----------|--------------|
| **Retain** | Content is processed, facts are extracted, entities are identified and linked in a knowledge graph |
| **Recall** | Four search strategies (semantic, keyword, graph, temporal) run in parallel to find relevant memories |
| **Reflect** | Retrieved memories are used to generate a personality-aware response |
| **Reflect** | Retrieved memories are used to generate a disposition-aware response |
---
@@ -129,6 +133,6 @@ hindsight memory reflect my-bank "Tell me about Alice"
- [**Retain**](./retain) — Advanced options for storing memories
- [**Recall**](./recall) — Search and retrieval strategies
- [**Reflect**](./reflect) — Personality-aware reasoning
- [**Memory Banks**](./memory-banks) — Configure personality and background
- [**Reflect**](./reflect) — Disposition-aware reasoning
- [**Memory Banks**](./memory-banks) — Configure disposition and background
- [**Server Deployment**](/developer/installation) — Docker Compose, Helm, and production setup
+21 -25
View File
@@ -4,7 +4,7 @@ sidebar_position: 3
# Reflect
Generate personality-aware responses using retrieved memories.
Generate disposition-aware responses using retrieved memories.
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
@@ -81,7 +81,7 @@ const response = await client.reflect('my-bank', 'What do you think about remote
</Tabs>
:::info How Reflect Works
Learn about personality-driven reasoning and opinion formation in the [Reflect Architecture](/developer/reflect) guide.
Learn about disposition-driven reasoning and opinion formation in the [Reflect Architecture](/developer/reflect) guide.
:::
## Opinion Formation
@@ -109,35 +109,32 @@ response = client.reflect(
New opinions are automatically stored and influence future responses.
## Personality Influence
## Disposition Influence
The bank's personality affects reflect responses:
The bank's disposition affects reflect responses:
| Trait | Effect on Reflect |
|-------|-----------------|
| High **Openness** | More willing to consider new ideas |
| High **Conscientiousness** | More structured, methodical responses |
| High **Extraversion** | More collaborative suggestions |
| High **Agreeableness** | More diplomatic, harmony-seeking |
| High **Neuroticism** | More risk-aware, cautious |
| Trait | Low (1) | High (5) |
|-------|---------|----------|
| **Skepticism** | Trusting, accepts claims | Questions and doubts claims |
| **Literalism** | Flexible interpretation | Exact, literal interpretation |
| **Empathy** | Detached, fact-focused | Considers emotional context |
<Tabs>
<TabItem value="python" label="Python">
```python
# Create a bank with specific personality
# Create a bank with specific disposition
client.create_bank(
bank_id="cautious-advisor",
background="I am a risk-aware financial advisor",
personality={
"openness": 0.3,
"conscientiousness": 0.9,
"neuroticism": 0.8,
"bias_strength": 0.7
disposition={
"skepticism": 5, # Very skeptical of claims
"literalism": 4, # Focuses on exact requirements
"empathy": 2 # Prioritizes facts over feelings
}
)
# Reflect responses will reflect this personality
# Reflect responses will reflect this disposition
response = client.reflect(
bank_id="cautious-advisor",
query="Should I invest in crypto?"
@@ -149,18 +146,17 @@ response = client.reflect(
<TabItem value="node" label="Node.js">
```typescript
// Create a bank with specific personality
// Create a bank with specific disposition
await client.createBank('cautious-advisor', {
background: 'I am a risk-aware financial advisor',
personality: {
openness: 0.3,
conscientiousness: 0.9,
neuroticism: 0.8,
bias_strength: 0.7
disposition: {
skepticism: 5,
literalism: 4,
empathy: 2
}
});
// Reflect responses will reflect this personality
// Reflect responses will reflect this disposition
const response = await client.reflect('cautious-advisor', 'Should I invest in crypto?');
```
@@ -15,7 +15,7 @@ When to use `search` vs `think`.
| **LLM calls** | 0 (retrieval only) | 1+ (generation) |
| **Speed** | Fast (~100-200ms) | Slower (~500-2000ms) |
| **Opinions** | Returns existing | Can form new ones |
| **Personality** | Not applied | Applied to response |
| **Disposition** | Not applied | Applied to response |
## When to Use Search
@@ -54,13 +54,13 @@ results = client.search(agent_id="my-agent", query="What do I know about Bob?")
**Use Think when you need:**
- A natural language response
- Personality-aware answers
- Disposition-aware answers
- Opinion formation
- Reasoning over multiple facts
- Source attribution
```python
# Get a complete answer with personality
# Get a complete answer with disposition
answer = client.think(agent_id="my-agent", query="What should I recommend to Alice?")
print(answer["text"]) # Natural language response
print(answer["based_on"]) # Sources used
@@ -78,7 +78,7 @@ answer = client.think(agent_id="my-agent", query="How are Alice and Bob connecte
# Opinion — agent forms a view
answer = client.think(agent_id="my-agent", query="What do you think about Python?")
# Recommendation — personality-influenced
# Recommendation — disposition-influenced
answer = client.think(agent_id="my-agent", query="What book should I read next?")
```
@@ -95,7 +95,7 @@ graph LR
subgraph Think
T1[Query] --> T2[4-way Retrieval]
T2 --> T3[RRF + Rerank]
T3 --> T4[Load Personality]
T3 --> T4[Load Disposition]
T4 --> T5[LLM Generation]
T5 --> T6[Store Opinions]
T6 --> T7[Response]
@@ -131,7 +131,7 @@ else:
graph TD
A[Need memory access] --> B{Need natural language response?}
B -->|No| C[Use Search]
B -->|Yes| D{Need personality/opinions?}
B -->|Yes| D{Need disposition/opinions?}
D -->|No| E{Building context for another LLM?}
E -->|Yes| C
E -->|No| F[Use Think]
@@ -6,6 +6,16 @@ Complete reference for configuring Hindsight server through environment variable
Hindsight is configured entirely through environment variables, making it easy to deploy across different environments and container orchestration platforms.
All environment variable names and defaults are defined in `hindsight_api.config`. You can use `MemoryEngine.from_env()` to create a MemoryEngine instance configured from environment variables:
```python
from hindsight_api import MemoryEngine
# Create from environment variables
memory = MemoryEngine.from_env()
await memory.initialize()
```
### LLM Provider Configuration
Configure the LLM provider used for fact extraction, entity resolution, and reasoning operations.
+11 -13
View File
@@ -86,19 +86,17 @@ graph LR
| **Graph** | Related entities, indirect connections |
| **Temporal** | "last spring", "in June", time ranges |
### Personality Framework (CARA)
### Disposition Traits
Memory banks have Big Five personality traits that influence opinion formation:
Memory banks have disposition traits that influence how opinions are formed during Reflect:
| Trait | Low | High |
|-------|-----|------|
| **Openness** | Prefers proven methods | Embraces new ideas |
| **Conscientiousness** | Flexible, spontaneous | Systematic, organized |
| **Extraversion** | Independent | Collaborative |
| **Agreeableness** | Direct, analytical | Diplomatic, harmonious |
| **Neuroticism** | Calm, optimistic | Risk-aware, cautious |
| Trait | Scale | Low (1) | High (5) |
|-------|-------|---------|----------|
| **Skepticism** | 1-5 | Trusting | Skeptical |
| **Literalism** | 1-5 | Flexible interpretation | Literal interpretation |
| **Empathy** | 1-5 | Detached | Empathetic |
The `bias_strength` parameter (0-1) controls how much personality influences opinions.
These traits only affect the `reflect` operation, not `recall`.
## Next Steps
@@ -109,13 +107,13 @@ The `bias_strength` parameter (0-1) controls how much personality influences opi
### Core Concepts
- [**Retain**](/developer/retain) — How memories are stored with multi-dimensional facts
- [**Recall**](/developer/retrieval) — How TEMPR's 4-way search retrieves memories
- [**Reflect**](/developer/reflect) — How personality influences reasoning and opinion formation
- [**Reflect**](/developer/reflect) — How disposition influences reasoning and opinion formation
### API Methods
- [**Retain**](/developer/api/retain) — Store information in memory banks
- [**Recall**](/developer/api/recall) — Search and retrieve memories
- [**Reflect**](/developer/api/reflect) — Reason with personality
- [**Memory Banks**](/developer/api/memory-banks) — Configure personality and background
- [**Reflect**](/developer/api/reflect) — Reason with disposition
- [**Memory Banks**](/developer/api/memory-banks) — Configure disposition and background
- [**Entities**](/developer/api/entities) — Track people, places, and concepts
- [**Documents**](/developer/api/documents) — Manage document sources
- [**Operations**](/developer/api/operations) — Monitor async tasks
+13 -8
View File
@@ -66,14 +66,14 @@ export HINDSIGHT_API_RERANK_ENABLED=true # Set to false to disable
Used for fact extraction, entity resolution, opinion generation, and answer synthesis.
**Supported providers:** Groq, OpenAI, Ollama
**Supported providers:** Groq, OpenAI, Ollama, Gemini
| Provider | Recommended Model | Best For |
|----------|-------------------|----------|
| **Groq** | `gpt-oss-20b` | Fast inference, high throughput (recommended) |
| **OpenAI** | `gpt-4o-mini` | Good quality, cost-effective |
| **OpenAI** | `gpt-4o` | Best quality |
| **Ollama** | `llama3.1` | Local deployment, privacy |
|----------|------------------|----------|
| **Groq** | `openai/gpt-oss-20b` | Fast inference, high throughput (recommended) |
| **OpenAI** | `gpt-5-mini` | Good quality |
| **Gemini** | `gemini-2.5-flash` | Good quality |
| **Ollama** | `gpt-oss-20b` | Local deployment, privacy |
**Configuration:**
@@ -86,12 +86,17 @@ export HINDSIGHT_API_LLM_MODEL=openai/gpt-oss-20b
# OpenAI
export HINDSIGHT_API_LLM_PROVIDER=openai
export HINDSIGHT_API_LLM_API_KEY=sk-xxxxxxxxxxxx
export HINDSIGHT_API_LLM_MODEL=gpt-4o-mini
export HINDSIGHT_API_LLM_MODEL=gpt-5-mini
# Gemini
export HINDSIGHT_API_LLM_PROVIDER=gemini
export HINDSIGHT_API_LLM_API_KEY=xxxxxxxxxxxx
export HINDSIGHT_API_LLM_MODEL=gemini-2.5-flash
# Ollama (local)
export HINDSIGHT_API_LLM_PROVIDER=ollama
export HINDSIGHT_API_LLM_BASE_URL=http://localhost:11434/v1
export HINDSIGHT_API_LLM_MODEL=llama3.1
export HINDSIGHT_API_LLM_MODEL=gpt-oss-20b
```
**Note:** The LLM is the primary bottleneck for write operations. See [Performance](./performance) for optimization strategies.
+1 -1
View File
@@ -8,7 +8,7 @@ Hindsight's performance is optimized across three key operations:
- **Retain (Ingestion)**: Batch processing with async operations for large-scale memory storage
- **Recall (Search)**: Sub-second semantic search with configurable thinking budgets
- **Reflect (Reasoning)**: Personality-aware answer generation with controllable compute
- **Reflect (Reasoning)**: Disposition-aware answer generation with controllable compute
## Design Philosophy: Optimized for Fast Reads
@@ -15,7 +15,7 @@ Traditional RAG (Retrieval-Augmented Generation) retrieves documents similar to
| **Temporal queries** | Keyword matching ("spring") | Date parsing and range filtering |
| **Entity understanding** | None | Entity resolution, observations, co-occurrence |
| **Belief formation** | Stateless | Opinions with confidence scores that evolve |
| **Personality** | None | Big Five traits influence interpretation |
| **Disposition** | None | 3 traits (skepticism, literalism, empathy) influence interpretation |
## Architecture Comparison
@@ -38,7 +38,7 @@ Single retrieval strategy. No state between queries.
| 2 | Execute 4 parallel retrievals: semantic, BM25, graph, temporal |
| 3 | Fuse results with RRF |
| 4 | Rerank with cross-encoder |
| 5 | Apply personality traits |
| 5 | Apply disposition traits |
| 6 | Generate response |
Multiple retrieval strategies. Persistent state across sessions.
@@ -106,5 +106,5 @@ Multiple retrieval strategies. Persistent state across sessions.
| Search with no temporal requirements | RAG |
| AI assistants with persistent memory | Hindsight |
| Applications requiring entity tracking | Hindsight |
| Systems needing consistent personality | Hindsight |
| Systems needing consistent disposition | Hindsight |
| Temporal queries ("last month", "in 2023") | Hindsight |
+20 -32
View File
@@ -51,19 +51,15 @@ With reflect:
---
## Disposition Framework (CARA)
## Disposition Traits
When you create a memory bank, you can configure its disposition using **Big Five traits**. These traits influence how the bank interprets information and forms opinions:
When you create a memory bank, you can configure its disposition using three traits. These traits influence how the bank interprets information and forms opinions during `reflect()`:
You can also provide a natural language **background** that describes the bank's identity and perspective, which shapes how these traits are applied.
| Trait | Low | High |
|-------|-----|------|
| **Openness** | Prefers proven methods | Embraces new ideas |
| **Conscientiousness** | Flexible, spontaneous | Systematic, organized |
| **Extraversion** | Independent | Collaborative |
| **Agreeableness** | Direct, analytical | Diplomatic, harmonious |
| **Neuroticism** | Calm, optimistic | Risk-aware, cautious |
| Trait | Scale | Low (1) | High (5) |
|-------|-------|---------|----------|
| **Skepticism** | 1-5 | Trusting, accepts information at face value | Skeptical, questions and doubts claims |
| **Literalism** | 1-5 | Flexible interpretation, reads between the lines | Literal interpretation, takes things at face value |
| **Empathy** | 1-5 | Detached, focuses on facts | Empathetic, considers emotional context |
### Background: Natural Language Identity
@@ -75,26 +71,18 @@ client.create_bank(
background="I am a senior software architect with 15 years of distributed "
"systems experience. I prefer simplicity over cutting-edge technology.",
disposition={
"openness": 0.3, # Prefers proven methods
"conscientiousness": 0.9, # Highly organized
# ... other traits
"skepticism": 4, # Questions new technologies
"literalism": 4, # Focuses on concrete specs
"empathy": 2 # Prioritizes technical facts
}
)
```
The background provides context that shapes how disposition traits are applied:
- "I prefer simplicity" + low openness → consistently favors established solutions
- "I prefer simplicity" + high skepticism → questions complex solutions
- "15 years experience" → responses reference this expertise
- First-person perspective → creates consistent voice
### Bias Strength
The `bias_strength` parameter (0-1) controls how much disposition influences reasoning:
- **0.0**: Purely evidence-based
- **0.5**: Balanced disposition and evidence
- **1.0**: Strongly disposition-driven
---
## Opinion Formation
@@ -105,11 +93,11 @@ When `reflect()` encounters a question that warrants forming an opinion, disposi
Two banks with different dispositions, given identical facts about remote work:
**Bank A** (high openness, low conscientiousness):
> "Remote work unlocks creative flexibility and spontaneous innovation. The freedom to work from anywhere enables breakthrough thinking."
**Bank A** (low skepticism, high empathy):
> "Remote work enables flexibility and work-life balance. The team seems happier and more productive when they can choose their environment."
**Bank B** (low openness, high conscientiousness):
> "Remote work lacks the structure and accountability needed for consistent performance. In-person collaboration is more reliable."
**Bank B** (high skepticism, low empathy):
> "Remote work claims need verification. What are the actual productivity metrics? The anecdotal benefits may not translate to measurable outcomes."
**Same facts → Different conclusions** because disposition shapes interpretation.
@@ -144,11 +132,11 @@ Different use cases benefit from different disposition configurations:
| Use Case | Recommended Traits | Why |
|----------|-------------------|-----|
| **Customer Support** | High agreeableness<br/>Low neuroticism | Diplomatic, calm under pressure |
| **Code Review** | High conscientiousness<br/>Low agreeableness | Detail-oriented, direct feedback |
| **Creative Writing** | High openness<br/>High extraversion | Embraces novelty, expressive |
| **Risk Analysis** | High neuroticism<br/>High conscientiousness | Risk-aware, methodical |
| **Research Assistant** | High openness<br/>High conscientiousness | Curious, thorough |
| **Customer Support** | skepticism: 2, literalism: 2, empathy: 5 | Trusting, flexible, understanding |
| **Code Review** | skepticism: 4, literalism: 5, empathy: 2 | Questions assumptions, precise, direct |
| **Legal Analysis** | skepticism: 5, literalism: 5, empathy: 2 | Highly skeptical, exact interpretation |
| **Therapist/Coach** | skepticism: 2, literalism: 2, empathy: 5 | Supportive, reads between lines |
| **Research Assistant** | skepticism: 4, literalism: 3, empathy: 3 | Questions claims, balanced interpretation |
---
+1 -1
View File
@@ -188,5 +188,5 @@ All stored in your isolated **memory bank**, ready for `recall()` and `reflect()
## Next Steps
- [**Recall**](./retrieval) — How multi-strategy search retrieves relevant memories
- [**Reflect**](./reflect) — How personality influences reasoning and opinion formation
- [**Reflect**](./reflect) — How disposition influences reasoning and opinion formation
- [API Reference](./api/retain) — Code examples for retaining memories
+1 -1
View File
@@ -203,4 +203,4 @@ The **fusion** of all four gives you exactly what you're looking for, even thoug
## Next Steps
- [**Retain**](./retain) — How memories are stored with rich context
- [**Reflect**](./reflect) — How personality influences reasoning
- [**Reflect**](./reflect) — How disposition influences reasoning
+3 -3
View File
@@ -82,7 +82,7 @@ hindsight memory recall <bank_id> "query" --trace
### Reflect (Generate Response)
Generate a response using memories and bank personality:
Generate a response using memories and bank disposition:
```bash
hindsight memory reflect <bank_id> "What do you know about Alice?"
@@ -125,8 +125,8 @@ hindsight bank name <bank_id> "My Assistant"
```bash
hindsight bank background <bank_id> "I am a helpful AI assistant interested in technology"
# Skip automatic personality inference
hindsight bank background <bank_id> "Background text" --no-update-personality
# Skip automatic disposition inference
hindsight bank background <bank_id> "Background text" --no-update-disposition
```
## Document Management
+11 -17
View File
@@ -28,7 +28,7 @@ for (const r of response.results) {
console.log(r.text);
}
// Reflect - generate response with personality
// Reflect - generate response with disposition
const answer = await client.reflect('my-agent', 'Tell me about Alice');
console.log(answer.text);
```
@@ -111,13 +111,10 @@ console.log(answer.based_on); // Memories used
await client.createBank('my-agent', {
name: 'Assistant',
background: 'I am a helpful AI assistant',
personality: {
openness: 0.7,
conscientiousness: 0.8,
extraversion: 0.5,
agreeableness: 0.6,
neuroticism: 0.3,
bias_strength: 0.5,
disposition: {
skepticism: 3, // 1-5: trusting to skeptical
literalism: 3, // 1-5: flexible to literal
empathy: 3, // 1-5: detached to empathetic
},
});
```
@@ -126,7 +123,7 @@ await client.createBank('my-agent', {
```typescript
const profile = await client.getBankProfile('my-agent');
console.log(profile.personality);
console.log(profile.disposition);
console.log(profile.background);
```
@@ -206,17 +203,14 @@ import { HindsightClient } from '@vectorize-io/hindsight-client';
async function main() {
const client = new HindsightClient({ baseUrl: 'http://localhost:8888' });
// Create a bank with personality
// Create a bank with disposition
await client.createBank('demo', {
name: 'Demo Agent',
background: 'A helpful assistant for demos',
personality: {
openness: 0.8,
conscientiousness: 0.7,
extraversion: 0.6,
agreeableness: 0.8,
neuroticism: 0.2,
bias_strength: 0.5,
disposition: {
skepticism: 2, // Trusting
literalism: 3, // Balanced
empathy: 4, // Empathetic
},
});
+7 -10
View File
@@ -56,7 +56,7 @@ with HindsightServer(
for r in results:
print(r.text)
# Reflect - generate response with personality
# Reflect - generate response with disposition
answer = client.reflect(bank_id="my-agent", query="Tell me about Alice")
print(answer.text)
```
@@ -77,7 +77,7 @@ results = client.recall(bank_id="my-agent", query="What does Alice do?")
for r in results:
print(r.text)
# Reflect - generate response with personality
# Reflect - generate response with disposition
answer = client.reflect(bank_id="my-agent", query="Tell me about Alice")
print(answer.text)
```
@@ -204,13 +204,10 @@ client.create_bank(
bank_id="my-agent",
name="Assistant",
background="I am a helpful AI assistant",
personality={
"openness": 0.7,
"conscientiousness": 0.8,
"extraversion": 0.5,
"agreeableness": 0.6,
"neuroticism": 0.3,
"bias_strength": 0.5,
disposition={
"skepticism": 3, # 1-5: trusting to skeptical
"literalism": 3, # 1-5: flexible to literal
"empathy": 3, # 1-5: detached to empathetic
},
)
```
@@ -270,7 +267,7 @@ from hindsight_client import (
RecallResult,
ReflectResponse,
BankProfileResponse,
PersonalityTraits,
DispositionTraits,
)
```
+37 -17
View File
@@ -1,7 +1,6 @@
import {themes as prismThemes} from 'prism-react-renderer';
import type {Config} from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
import type * as OpenApiPlugin from 'docusaurus-plugin-openapi-docs';
const config: Config = {
title: 'Hindsight',
@@ -51,6 +50,8 @@ const config: Config = {
attributes: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Nunito+Sans:wght@400;500;600;700;800&display=swap',
media: 'print',
onload: "this.media='all'",
},
},
],
@@ -63,7 +64,6 @@ const config: Config = {
sidebarPath: './sidebars.ts',
editUrl: 'https://github.com/vectorize-io/hindsight/tree/main/hindsight-docs/',
routeBasePath: '/',
docItemComponent: '@theme/ApiItem',
},
blog: false,
theme: {
@@ -71,28 +71,48 @@ const config: Config = {
},
} satisfies Preset.Options,
],
],
plugins: [
[
'docusaurus-plugin-openapi-docs',
'redocusaurus',
{
id: 'api',
docsPluginId: 'default',
config: {
hindsight: {
specPath: 'openapi.json',
outputDir: 'docs/api-reference/endpoints',
sidebarOptions: {
groupPathsBy: 'tag',
specs: [
{
id: 'hindsight-api',
spec: 'openapi.json',
route: '/api-reference',
url: '/openapi.json',
},
],
theme: {
primaryColor: '#0d9488',
sidebar: {
backgroundColor: '#09090b',
},
rightPanel: {
backgroundColor: '#18181b',
},
typography: {
fontSize: '15px',
fontFamily: "'Avenir Book', 'Avenir', 'Nunito Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
headings: {
fontFamily: "'Avenir', 'Avenir Book', 'Nunito Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
},
} satisfies OpenApiPlugin.Options,
code: {
fontFamily: "'JetBrains Mono', 'Fira Code', 'SF Mono', Monaco, Consolas, monospace",
fontSize: '13px',
},
},
},
config: {
scrollYOffset: 60,
nativeScrollbars: true,
expandSingleSchemaField: true,
expandResponses: '200,201',
},
},
],
],
themes: ['docusaurus-theme-openapi-docs', '@docusaurus/theme-mermaid'],
themes: ['@docusaurus/theme-mermaid'],
themeConfig: {
image: 'img/hindsight-social-card.jpg',
@@ -165,7 +185,7 @@ const config: Config = {
},
{
label: 'API Reference',
to: '/api-reference',
to: '/api-reference/',
},
],
},
+4 -4
View File
@@ -10,7 +10,7 @@
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "1.0.0"
"version": "0.1.0"
},
"paths": {
"/health": {
@@ -213,7 +213,7 @@
"Memory"
],
"summary": "Recall memory",
"description": "Recall memory using semantic similarity and spreading activation.\n\n The type parameter is optional and must be one of:\n - 'world': General knowledge about people, places, events, and things that happen\n - 'experience': Memories about experience, conversations, actions taken, and tasks performed\n - 'opinion': The bank's formed beliefs, perspectives, and viewpoints\n\n Set include_entities=true to get entity observations alongside recall results.",
"description": "Recall memory using semantic similarity and spreading activation.\n\nThe type parameter is optional and must be one of:\n- `world`: General knowledge about people, places, events, and things that happen\n- `experience`: Memories about experience, conversations, actions taken, and tasks performed\n- `opinion`: The bank's formed beliefs, perspectives, and viewpoints\n\nSet `include_entities=true` to get entity observations alongside recall results.",
"operationId": "recall_memories",
"parameters": [
{
@@ -266,7 +266,7 @@
"Memory"
],
"summary": "Reflect and generate answer",
"description": "Reflect and formulate an answer using bank identity, world facts, and opinions.\n\n This endpoint:\n 1. Retrieves experience (conversations and events)\n 2. Retrieves world facts relevant to the query\n 3. Retrieves existing opinions (bank's perspectives)\n 4. Uses LLM to formulate a contextual answer\n 5. Extracts and stores any new opinions formed\n 6. Returns plain text answer, the facts used, and new opinions",
"description": "Reflect and formulate an answer using bank identity, world facts, and opinions.\n\nThis endpoint:\n1. Retrieves experience (conversations and events)\n2. Retrieves world facts relevant to the query\n3. Retrieves existing opinions (bank's perspectives)\n4. Uses LLM to formulate a contextual answer\n5. Extracts and stores any new opinions formed\n6. Returns plain text answer, the facts used, and new opinions",
"operationId": "reflect",
"parameters": [
{
@@ -1054,7 +1054,7 @@
"Memory"
],
"summary": "Retain memories",
"description": "Retain memory items with automatic fact extraction.\n\n This is the main endpoint for storing memories. It supports both synchronous and asynchronous processing\n via the async parameter.\n\n Features:\n - Efficient batch processing\n - Automatic fact extraction from natural language\n - Entity recognition and linking\n - Document tracking with automatic upsert (when document_id is provided on items)\n - Temporal and semantic linking\n - Optional asynchronous processing\n\n The system automatically:\n 1. Extracts semantic facts from the content\n 2. Generates embeddings\n 3. Deduplicates similar facts\n 4. Creates temporal, semantic, and entity links\n 5. Tracks document metadata\n\n When async=true:\n - Returns immediately after queuing the task\n - Processing happens in the background\n - Use the operations endpoint to monitor progress\n\n When async=false (default):\n - Waits for processing to complete\n - Returns after all memories are stored\n\n Note: If a memory item has a document_id that already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). Items with the same document_id are grouped together for efficient processing.",
"description": "Retain memory items with automatic fact extraction.\n\nThis is the main endpoint for storing memories. It supports both synchronous and asynchronous processing via the `async` parameter.\n\n**Features:**\n- Efficient batch processing\n- Automatic fact extraction from natural language\n- Entity recognition and linking\n- Document tracking with automatic upsert (when document_id is provided)\n- Temporal and semantic linking\n- Optional asynchronous processing\n\n**The system automatically:**\n1. Extracts semantic facts from the content\n2. Generates embeddings\n3. Deduplicates similar facts\n4. Creates temporal, semantic, and entity links\n5. Tracks document metadata\n\n**When `async=true`:** Returns immediately after queuing. Use the operations endpoint to monitor progress.\n\n**When `async=false` (default):** Waits for processing to complete.\n\n**Note:** If a memory item has a `document_id` that already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior).",
"operationId": "retain_memories",
"parameters": [
{
+418 -3403
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -23,11 +23,10 @@
"@mdx-js/react": "^3.0.0",
"@phosphor-icons/react": "^2.1.10",
"clsx": "^2.0.0",
"docusaurus-plugin-openapi-docs": "^4.5.1",
"docusaurus-theme-openapi-docs": "^4.5.1",
"prism-react-renderer": "^2.3.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react-dom": "^19.0.0",
"redocusaurus": "^2.5.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.9.2",
-26
View File
@@ -1,5 +1,4 @@
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
import apiSidebar from './docs/api-reference/endpoints/sidebar';
const sidebars: SidebarsConfig = {
developerSidebar: [
@@ -171,31 +170,6 @@ const sidebars: SidebarsConfig = {
],
},
],
apiReferenceSidebar: [
{
type: 'doc',
id: 'api-reference/index',
label: 'Overview',
},
{
type: 'category',
label: 'HTTP API',
collapsible: false,
items: apiSidebar,
},
{
type: 'category',
label: 'MCP API',
collapsible: false,
items: [
{
type: 'doc',
id: 'api-reference/mcp',
label: 'Tools Reference',
},
],
},
],
cookbookSidebar: [
{
type: 'doc',
+9 -84
View File
@@ -318,9 +318,15 @@ th {
padding: 0.5rem 1rem;
}
/* Smooth scrolling */
html {
scroll-behavior: smooth;
/* Redoc sidebar - expand all tags by default */
[class*="redoc-wrap"] [class*="menu-content"] ul {
display: block !important;
}
/* Hide Redoc footer/branding */
[class*="redoc-wrap"] a[href*="redocly.com"] {
display: none !important;
}
/* List styling */
@@ -332,84 +338,3 @@ article li {
margin-bottom: 0.25rem;
}
/* API Method badges in sidebar - OpenAPI plugin */
li.api-method {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
}
li.api-method > a.menu__link {
order: 2;
}
/* Style the badge added by openapi plugin */
li.api-method::before {
order: 1;
flex-shrink: 0;
font-size: 0.5625rem;
font-weight: 700;
text-transform: uppercase;
padding: 0.125rem 0.375rem;
border-radius: 0.25rem;
font-family: var(--ifm-font-family-monospace);
letter-spacing: 0.025em;
line-height: 1;
}
.api-method.get::before {
content: 'GET';
background-color: rgba(34, 197, 94, 0.15);
color: #22c55e;
}
.api-method.post::before {
content: 'POST';
background-color: rgba(59, 130, 246, 0.15);
color: #3b82f6;
}
.api-method.put::before {
content: 'PUT';
background-color: rgba(249, 115, 22, 0.15);
color: #f97316;
}
.api-method.delete::before {
content: 'DEL';
background-color: rgba(239, 68, 68, 0.15);
color: #ef4444;
}
.api-method.patch::before {
content: 'PATCH';
background-color: rgba(168, 85, 247, 0.15);
color: #a855f7;
}
/* Dark mode adjustments */
[data-theme='dark'] .api-method.get::before {
background-color: rgba(34, 197, 94, 0.2);
color: #4ade80;
}
[data-theme='dark'] .api-method.post::before {
background-color: rgba(59, 130, 246, 0.2);
color: #60a5fa;
}
[data-theme='dark'] .api-method.put::before {
background-color: rgba(249, 115, 22, 0.2);
color: #fb923c;
}
[data-theme='dark'] .api-method.delete::before {
background-color: rgba(239, 68, 68, 0.2);
color: #f87171;
}
[data-theme='dark'] .api-method.patch::before {
background-color: rgba(168, 85, 247, 0.2);
color: #c084fc;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-1
View File
@@ -119,7 +119,6 @@ class Server:
app = create_app(
memory=self._memory,
mcp_api_enabled=self.mcp_enabled,
run_migrations=True,
initialize_memory=True,
)
+4 -4
View File
@@ -10,7 +10,7 @@
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "1.0.0"
"version": "0.1.0"
},
"paths": {
"/health": {
@@ -213,7 +213,7 @@
"Memory"
],
"summary": "Recall memory",
"description": "Recall memory using semantic similarity and spreading activation.\n\n The type parameter is optional and must be one of:\n - 'world': General knowledge about people, places, events, and things that happen\n - 'experience': Memories about experience, conversations, actions taken, and tasks performed\n - 'opinion': The bank's formed beliefs, perspectives, and viewpoints\n\n Set include_entities=true to get entity observations alongside recall results.",
"description": "Recall memory using semantic similarity and spreading activation.\n\nThe type parameter is optional and must be one of:\n- `world`: General knowledge about people, places, events, and things that happen\n- `experience`: Memories about experience, conversations, actions taken, and tasks performed\n- `opinion`: The bank's formed beliefs, perspectives, and viewpoints\n\nSet `include_entities=true` to get entity observations alongside recall results.",
"operationId": "recall_memories",
"parameters": [
{
@@ -266,7 +266,7 @@
"Memory"
],
"summary": "Reflect and generate answer",
"description": "Reflect and formulate an answer using bank identity, world facts, and opinions.\n\n This endpoint:\n 1. Retrieves experience (conversations and events)\n 2. Retrieves world facts relevant to the query\n 3. Retrieves existing opinions (bank's perspectives)\n 4. Uses LLM to formulate a contextual answer\n 5. Extracts and stores any new opinions formed\n 6. Returns plain text answer, the facts used, and new opinions",
"description": "Reflect and formulate an answer using bank identity, world facts, and opinions.\n\nThis endpoint:\n1. Retrieves experience (conversations and events)\n2. Retrieves world facts relevant to the query\n3. Retrieves existing opinions (bank's perspectives)\n4. Uses LLM to formulate a contextual answer\n5. Extracts and stores any new opinions formed\n6. Returns plain text answer, the facts used, and new opinions",
"operationId": "reflect",
"parameters": [
{
@@ -1054,7 +1054,7 @@
"Memory"
],
"summary": "Retain memories",
"description": "Retain memory items with automatic fact extraction.\n\n This is the main endpoint for storing memories. It supports both synchronous and asynchronous processing\n via the async parameter.\n\n Features:\n - Efficient batch processing\n - Automatic fact extraction from natural language\n - Entity recognition and linking\n - Document tracking with automatic upsert (when document_id is provided on items)\n - Temporal and semantic linking\n - Optional asynchronous processing\n\n The system automatically:\n 1. Extracts semantic facts from the content\n 2. Generates embeddings\n 3. Deduplicates similar facts\n 4. Creates temporal, semantic, and entity links\n 5. Tracks document metadata\n\n When async=true:\n - Returns immediately after queuing the task\n - Processing happens in the background\n - Use the operations endpoint to monitor progress\n\n When async=false (default):\n - Waits for processing to complete\n - Returns after all memories are stored\n\n Note: If a memory item has a document_id that already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). Items with the same document_id are grouped together for efficient processing.",
"description": "Retain memory items with automatic fact extraction.\n\nThis is the main endpoint for storing memories. It supports both synchronous and asynchronous processing via the `async` parameter.\n\n**Features:**\n- Efficient batch processing\n- Automatic fact extraction from natural language\n- Entity recognition and linking\n- Document tracking with automatic upsert (when document_id is provided)\n- Temporal and semantic linking\n- Optional asynchronous processing\n\n**The system automatically:**\n1. Extracts semantic facts from the content\n2. Generates embeddings\n3. Deduplicates similar facts\n4. Creates temporal, semantic, and entity links\n5. Tracks document metadata\n\n**When `async=true`:** Returns immediately after queuing. Use the operations endpoint to monitor progress.\n\n**When `async=false` (default):** Waits for processing to complete.\n\n**Note:** If a memory item has a `document_id` that already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior).",
"operationId": "retain_memories",
"parameters": [
{
+1 -1
View File
@@ -72,4 +72,4 @@ if [[ ${#SERVER_ARGS[@]} -eq 0 ]]; then
SERVER_ARGS=(--host 0.0.0.0 --port 8888)
fi
uv run python -m hindsight_api.web.server "${SERVER_ARGS[@]}"
uv run hindsight-api "${SERVER_ARGS[@]}"
+3 -3
View File
@@ -14,12 +14,12 @@ uv run generate-openapi
echo ""
echo "Copying OpenAPI spec to documentation..."
cp "$ROOT_DIR/openapi.json" "$ROOT_DIR/hindsight-docs/openapi.json"
cp "$ROOT_DIR/openapi.json" "$ROOT_DIR/hindsight-docs/static/openapi.json"
echo ""
echo "Regenerating API reference documentation..."
echo "Building documentation..."
cd "$ROOT_DIR/hindsight-docs"
npx docusaurus clean-api-docs hindsight
npx docusaurus gen-api-docs hindsight
npm run build
echo ""
echo "OpenAPI spec and documentation generated successfully!"