Compare commits

..
15 Commits
Author SHA1 Message Date
Nicolò Boschi 4a6942fb06 fixes 2025-12-23 12:39:42 +01:00
Nicolò Boschi b1f8627eed fixes 2025-12-23 12:00:34 +01:00
Nicolò Boschi 8573cc3292 others 2025-12-23 11:29:21 +01:00
Nicolò Boschi eb725002c0 others 2025-12-23 11:20:43 +01:00
Nicolò Boschi 2de75062eb doc: changelog and delete doc info 2025-12-23 10:41:27 +01:00
Nicolò Boschi e599346e59 Release v0.1.14
- Update version to 0.1.14 in all components
- Python packages: hindsight-api, hindsight-dev, hindsight-all, hindsight-litellm
- Python client: hindsight-clients/python
- TypeScript client: hindsight-clients/typescript
- Rust CLI: hindsight-cli
- Control Plane: hindsight-control-plane
- Helm chart
2025-12-23 10:37:23 +01:00
Nicolò Boschi 0b352d1bfa fix: embed get-skill installer (#69) 2025-12-23 10:36:36 +01:00
Nicolò Boschi c882511f10 Release v0.1.13
- Update version to 0.1.13 in all components
- Python packages: hindsight-api, hindsight-dev, hindsight-all, hindsight-litellm
- Python client: hindsight-clients/python
- TypeScript client: hindsight-clients/typescript
- Rust CLI: hindsight-cli
- Control Plane: hindsight-control-plane
- Helm chart
2025-12-22 22:27:49 +01:00
Nicolò Boschi 234d426499 fix(ui): timestamp is not considered in retain (#68) 2025-12-22 22:27:31 +01:00
Nicolò Boschi e6511e7d77 feat: refactor hindsight-embed architecture (#66)
* feat: refactor hindsight-embed architecture

* feat: refactor hindsight-embed architecture

* refactor deamin

* refactor deamin

* refactor deamin

* refactor deamin
2025-12-22 22:02:40 +01:00
Chris Bartholomew 904ea4de24 fix: propagate exceptions from task handlers to enable retry logic (#65)
Task handlers were swallowing exceptions, causing operations to be
marked as completed even when they failed. This prevented the retry
logic in execute_task() from working and led to accumulation of
pending operations that never completed.

Fixed handlers:
- _handle_batch_retain: remove try/except wrapper
- _handle_access_count_update: remove try/except wrapper
- _handle_regenerate_observations: remove outer try/except, keep
  inner one for individual entity failures
2025-12-22 20:42:57 +01:00
Nicolò Boschi 6168a77846 Release v0.1.12
- Update version to 0.1.12 in all components
- Python packages: hindsight-api, hindsight-dev, hindsight-all, hindsight-litellm
- Python client: hindsight-clients/python
- TypeScript client: hindsight-clients/typescript
- Rust CLI: hindsight-cli
- Control Plane: hindsight-control-plane
- Helm chart
2025-12-22 16:44:05 +01:00
Nicolò Boschi da44a5e839 feat: add hindsight-embed and native agentic skill (#64) 2025-12-22 16:42:11 +01:00
Nicolò Boschi 32bca12c6f fix: ollama structured support (#63)
* fix: ollama structured support

* fix: ollama structured support

* fix: ollama structured support
2025-12-22 16:35:24 +01:00
Nicolò Boschi 26850a0156 doc: add documentation for extensions (#62)
* add doc for extensions

* add doc for extensions
2025-12-22 11:58:05 +01:00
182 changed files with 17602 additions and 12438 deletions
+12
View File
@@ -42,6 +42,10 @@ jobs:
working-directory: ./hindsight-integrations/litellm
run: uv build --out-dir dist
- name: Build hindsight-embed
working-directory: ./hindsight-embed
run: uv build --out-dir dist
# Publish in order (client and api first, then hindsight-all which depends on them)
- name: Publish hindsight-client to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
@@ -67,6 +71,12 @@ jobs:
packages-dir: ./hindsight-integrations/litellm/dist
skip-existing: true
- name: Publish hindsight-embed to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ./hindsight-embed/dist
skip-existing: true
# Upload artifacts for GitHub release
- name: Upload artifacts
uses: actions/upload-artifact@v4
@@ -77,6 +87,7 @@ jobs:
hindsight-api/dist/*
hindsight/dist/*
hindsight-integrations/litellm/dist/*
hindsight-embed/dist/*
retention-days: 1
release-typescript-client:
@@ -416,6 +427,7 @@ jobs:
cp artifacts/python-packages/hindsight-api/dist/* release-assets/ || true
cp artifacts/python-packages/hindsight/dist/* release-assets/ || true
cp artifacts/python-packages/hindsight-integrations/litellm/dist/* release-assets/ || true
cp artifacts/python-packages/hindsight-embed/dist/* release-assets/ || true
# TypeScript client
cp artifacts/typescript-client/*.tgz release-assets/ || true
# Control Plane
+119
View File
@@ -20,6 +20,8 @@ jobs:
path: hindsight-api
- name: hindsight-client
path: hindsight-clients/python
- name: hindsight-embed
path: hindsight-embed
steps:
- uses: actions/checkout@v4
@@ -180,6 +182,83 @@ jobs:
path: hindsight-cli/target/release/hindsight
retention-days: 1
test-rust-cli:
runs-on: ubuntu-latest
needs: build-rust-cli
env:
HINDSIGHT_API_LLM_PROVIDER: groq
HINDSIGHT_API_LLM_API_KEY: ${{ secrets.GROQ_API_KEY }}
HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b
HINDSIGHT_API_URL: http://localhost:8888
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UV_INDEX: pytorch=https://download.pytorch.org/whl/cpu
steps:
- uses: actions/checkout@v4
- name: Download CLI artifact
uses: actions/download-artifact@v4
with:
name: hindsight-cli
path: /tmp/cli
- name: Make CLI executable
run: chmod +x /tmp/cli/hindsight
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
prune-cache: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: ".python-version"
- name: Build API
working-directory: ./hindsight-api
run: uv build
- name: Install API dependencies
working-directory: ./hindsight-api
run: uv sync --no-install-project --index-strategy unsafe-best-match
- name: Create .env file
run: |
cat > .env << EOF
HINDSIGHT_API_LLM_PROVIDER=${{ env.HINDSIGHT_API_LLM_PROVIDER }}
HINDSIGHT_API_LLM_API_KEY=${{ env.HINDSIGHT_API_LLM_API_KEY }}
HINDSIGHT_API_LLM_MODEL=${{ env.HINDSIGHT_API_LLM_MODEL }}
EOF
- name: Start API server
run: |
./scripts/dev/start-api.sh > /tmp/api-server.log 2>&1 &
echo "Waiting for API server to be ready..."
for i in {1..60}; do
if curl -sf http://localhost:8888/health > /dev/null 2>&1; then
echo "API server is ready after ${i}s"
break
fi
if [ $i -eq 60 ]; then
echo "API server failed to start after 60s"
cat /tmp/api-server.log
exit 1
fi
sleep 1
done
- name: Run CLI smoke test
run: |
HINDSIGHT_CLI=/tmp/cli/hindsight ./hindsight-cli/smoke-test.sh
- name: Show API server logs
if: always()
run: |
echo "=== API Server Logs ==="
cat /tmp/api-server.log || echo "No API server log found"
lint-helm-chart:
runs-on: ubuntu-latest
@@ -563,6 +642,46 @@ jobs:
working-directory: ./hindsight-integrations/litellm
run: uv run pytest tests -v
test-embed:
runs-on: ubuntu-latest
env:
HINDSIGHT_EMBED_LLM_PROVIDER: groq
HINDSIGHT_EMBED_LLM_API_KEY: ${{ secrets.GROQ_API_KEY }}
HINDSIGHT_EMBED_LLM_MODEL: openai/gpt-oss-20b
# Prefer CPU-only PyTorch in CI
UV_INDEX: pytorch=https://download.pytorch.org/whl/cpu
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
prune-cache: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: ".python-version"
- name: Install dependencies
working-directory: ./hindsight-embed
run: uv sync --index-strategy unsafe-best-match
- name: Cache HuggingFace models
uses: actions/cache@v4
with:
path: ~/.cache/huggingface
key: ${{ runner.os }}-huggingface-embed-${{ hashFiles('hindsight-embed/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-huggingface-embed-
${{ runner.os }}-huggingface-
- name: Run smoke test
working-directory: ./hindsight-embed
run: ./test.sh
test-doc-examples:
runs-on: ubuntu-latest
needs: build-rust-cli
+3 -1
View File
@@ -14,6 +14,7 @@ This document captures architectural decisions and coding conventions for the Hi
hindsight/ # Python package for embedded usage
hindsight-api/ # FastAPI server (core memory engine)
hindsight-cli/ # Rust CLI client
hindsight-embed/ # Embedded CLI (no server needed)
hindsight-control-plane/ # Next.js admin UI
hindsight-docs/ # Docusaurus documentation site
hindsight-dev/ # Development tools and benchmarks
@@ -148,4 +149,5 @@ Note: The maintained wrapper `hindsight_client.py` and `README.md` are preserved
# Branding
## Colors
- Primary: gradient from #0074d9 to #009296
- Primary: gradient from #0074d9 to #009296
+2 -2
View File
@@ -2,8 +2,8 @@ apiVersion: v2
name: hindsight
description: Hindsight helm chart
type: application
version: 0.1.11
appVersion: "0.1.11"
version: 0.1.14
appVersion: "0.1.14"
keywords:
- ai
- memory
+168 -25
View File
@@ -29,7 +29,7 @@ def _parse_metadata(metadata: Any) -> dict[str, Any]:
return {}
from pydantic import BaseModel, ConfigDict, Field
from pydantic import BaseModel, ConfigDict, Field, field_validator
from hindsight_api import MemoryEngine
from hindsight_api.engine.db_utils import acquire_with_retry
@@ -291,7 +291,7 @@ class MemoryItem(BaseModel):
"metadata": {"source": "slack", "channel": "engineering"},
"document_id": "meeting_notes_2024_01_15",
}
}
},
)
content: str
@@ -300,6 +300,23 @@ class MemoryItem(BaseModel):
metadata: dict[str, str] | None = None
document_id: str | None = Field(default=None, description="Optional document ID for this memory item.")
@field_validator("timestamp", mode="before")
@classmethod
def validate_timestamp(cls, v):
if v is None or v == "":
return None
if isinstance(v, datetime):
return v
if isinstance(v, str):
try:
# Try parsing as ISO format
return datetime.fromisoformat(v.replace("Z", "+00:00"))
except ValueError as e:
raise ValueError(
f"Invalid timestamp/event_date format: '{v}'. Expected ISO format like '2024-01-15T10:30:00' or '2024-01-15T10:30:00Z'"
) from e
raise ValueError(f"timestamp must be a string or datetime, got {type(v).__name__}")
class RetainRequest(BaseModel):
"""Request model for retain endpoint."""
@@ -672,6 +689,26 @@ class DocumentResponse(BaseModel):
memory_unit_count: int
class DeleteDocumentResponse(BaseModel):
"""Response model for delete document endpoint."""
model_config = ConfigDict(
json_schema_extra={
"example": {
"success": True,
"message": "Document 'session_1' and 5 associated memory units deleted successfully",
"document_id": "session_1",
"memory_units_deleted": 5,
}
}
)
success: bool
message: str
document_id: str
memory_units_deleted: int
class ChunkResponse(BaseModel):
"""Response model for get chunk endpoint."""
@@ -708,6 +745,108 @@ class DeleteResponse(BaseModel):
deleted_count: int | None = None
class BankStatsResponse(BaseModel):
"""Response model for bank statistics endpoint."""
model_config = ConfigDict(
json_schema_extra={
"example": {
"bank_id": "user123",
"total_nodes": 150,
"total_links": 300,
"total_documents": 10,
"nodes_by_fact_type": {"fact": 100, "preference": 30, "observation": 20},
"links_by_link_type": {"temporal": 150, "semantic": 100, "entity": 50},
"links_by_fact_type": {"fact": 200, "preference": 60, "observation": 40},
"links_breakdown": {"fact": {"temporal": 100, "semantic": 60, "entity": 40}},
"pending_operations": 2,
"failed_operations": 0,
}
}
)
bank_id: str
total_nodes: int
total_links: int
total_documents: int
nodes_by_fact_type: dict[str, int]
links_by_link_type: dict[str, int]
links_by_fact_type: dict[str, int]
links_breakdown: dict[str, dict[str, int]]
pending_operations: int
failed_operations: int
class OperationResponse(BaseModel):
"""Response model for a single async operation."""
model_config = ConfigDict(
json_schema_extra={
"example": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"task_type": "retain",
"items_count": 5,
"document_id": "meeting-notes-2024",
"created_at": "2024-01-15T10:30:00Z",
"status": "pending",
"error_message": None,
}
}
)
id: str
task_type: str
items_count: int
document_id: str | None
created_at: str
status: str
error_message: str | None
class OperationsListResponse(BaseModel):
"""Response model for list operations endpoint."""
model_config = ConfigDict(
json_schema_extra={
"example": {
"bank_id": "user123",
"operations": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"task_type": "retain",
"items_count": 5,
"document_id": None,
"created_at": "2024-01-15T10:30:00Z",
"status": "pending",
"error_message": None,
}
],
}
}
)
bank_id: str
operations: list[OperationResponse]
class CancelOperationResponse(BaseModel):
"""Response model for cancel operation endpoint."""
model_config = ConfigDict(
json_schema_extra={
"example": {
"success": True,
"message": "Operation 550e8400-e29b-41d4-a716-446655440000 cancelled",
"operation_id": "550e8400-e29b-41d4-a716-446655440000",
}
}
)
success: bool
message: str
operation_id: str
def create_app(
memory: MemoryEngine,
initialize_memory: bool = True,
@@ -1125,6 +1264,7 @@ def _register_routes(app: FastAPI):
@app.get(
"/v1/default/banks/{bank_id}/stats",
response_model=BankStatsResponse,
summary="Get statistics for memory bank",
description="Get statistics about nodes and links for a specific agent",
operation_id="get_agent_stats",
@@ -1225,18 +1365,18 @@ def _register_routes(app: FastAPI):
total_nodes = sum(nodes_by_type.values())
total_links = sum(links_by_type.values())
return {
"bank_id": bank_id,
"total_nodes": total_nodes,
"total_links": total_links,
"total_documents": total_documents,
"nodes_by_fact_type": nodes_by_type,
"links_by_link_type": links_by_type,
"links_by_fact_type": links_by_fact_type,
"links_breakdown": links_breakdown,
"pending_operations": pending_operations,
"failed_operations": failed_operations,
}
return BankStatsResponse(
bank_id=bank_id,
total_nodes=total_nodes,
total_links=total_links,
total_documents=total_documents,
nodes_by_fact_type=nodes_by_type,
links_by_link_type=links_by_type,
links_by_fact_type=links_by_fact_type,
links_breakdown=links_breakdown,
pending_operations=pending_operations,
failed_operations=failed_operations,
)
except Exception as e:
import traceback
@@ -1460,6 +1600,7 @@ def _register_routes(app: FastAPI):
@app.delete(
"/v1/default/banks/{bank_id}/documents/{document_id}",
response_model=DeleteDocumentResponse,
summary="Delete a document",
description="Delete a document and all its associated memory units and links.\n\n"
"This will cascade delete:\n"
@@ -1486,12 +1627,12 @@ def _register_routes(app: FastAPI):
if result["document_deleted"] == 0:
raise HTTPException(status_code=404, detail="Document not found")
return {
"success": True,
"message": f"Document '{document_id}' and {result['memory_units_deleted']} associated memory units deleted successfully",
"document_id": document_id,
"memory_units_deleted": result["memory_units_deleted"],
}
return DeleteDocumentResponse(
success=True,
message=f"Document '{document_id}' and {result['memory_units_deleted']} associated memory units deleted successfully",
document_id=document_id,
memory_units_deleted=result["memory_units_deleted"],
)
except HTTPException:
raise
except Exception as e:
@@ -1503,6 +1644,7 @@ def _register_routes(app: FastAPI):
@app.get(
"/v1/default/banks/{bank_id}/operations",
response_model=OperationsListResponse,
summary="List async operations",
description="Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations",
operation_id="list_operations",
@@ -1512,10 +1654,10 @@ def _register_routes(app: FastAPI):
"""List all async operations (pending and failed) for a memory bank."""
try:
operations = await app.state.memory.list_operations(bank_id, request_context=request_context)
return {
"bank_id": bank_id,
"operations": operations,
}
return OperationsListResponse(
bank_id=bank_id,
operations=[OperationResponse(**op) for op in operations],
)
except Exception as e:
import traceback
@@ -1525,6 +1667,7 @@ def _register_routes(app: FastAPI):
@app.delete(
"/v1/default/banks/{bank_id}/operations/{operation_id}",
response_model=CancelOperationResponse,
summary="Cancel a pending async operation",
description="Cancel a pending async operation by removing it from the queue",
operation_id="cancel_operation",
@@ -1542,7 +1685,7 @@ def _register_routes(app: FastAPI):
raise HTTPException(status_code=400, detail=f"Invalid operation_id format: {operation_id}")
result = await app.state.memory.cancel_operation(bank_id, operation_id, request_context=request_context)
return result
return CancelOperationResponse(**result)
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
except Exception as e:
+11
View File
@@ -33,6 +33,10 @@ ENV_GRAPH_RETRIEVER = "HINDSIGHT_API_GRAPH_RETRIEVER"
ENV_MCP_LOCAL_BANK_ID = "HINDSIGHT_API_MCP_LOCAL_BANK_ID"
ENV_MCP_INSTRUCTIONS = "HINDSIGHT_API_MCP_INSTRUCTIONS"
# Optimization flags
ENV_SKIP_LLM_VERIFICATION = "HINDSIGHT_API_SKIP_LLM_VERIFICATION"
ENV_LAZY_RERANKER = "HINDSIGHT_API_LAZY_RERANKER"
# Default values
DEFAULT_DATABASE_URL = "pg0"
DEFAULT_LLM_PROVIDER = "openai"
@@ -107,6 +111,10 @@ class HindsightConfig:
# Recall
graph_retriever: str
# Optimization flags
skip_llm_verification: bool
lazy_reranker: bool
@classmethod
def from_env(cls) -> "HindsightConfig":
"""Create configuration from environment variables."""
@@ -133,6 +141,9 @@ class HindsightConfig:
mcp_enabled=os.getenv(ENV_MCP_ENABLED, str(DEFAULT_MCP_ENABLED)).lower() == "true",
# Recall
graph_retriever=os.getenv(ENV_GRAPH_RETRIEVER, DEFAULT_GRAPH_RETRIEVER),
# Optimization flags
skip_llm_verification=os.getenv(ENV_SKIP_LLM_VERIFICATION, "false").lower() == "true",
lazy_reranker=os.getenv(ENV_LAZY_RERANKER, "false").lower() == "true",
)
def get_llm_base_url(self) -> str:
+204
View File
@@ -0,0 +1,204 @@
"""
Daemon mode support for Hindsight API.
Provides idle timeout and lockfile management for running as a background daemon.
"""
import asyncio
import fcntl
import logging
import os
import sys
import time
from pathlib import Path
logger = logging.getLogger(__name__)
# Default daemon configuration
DEFAULT_DAEMON_PORT = 8889
DEFAULT_IDLE_TIMEOUT = 0 # 0 = no auto-exit (hindsight-embed passes its own timeout)
LOCKFILE_PATH = Path.home() / ".hindsight" / "daemon.lock"
DAEMON_LOG_PATH = Path.home() / ".hindsight" / "daemon.log"
class IdleTimeoutMiddleware:
"""ASGI middleware that tracks activity and exits after idle timeout."""
def __init__(self, app, idle_timeout: int = DEFAULT_IDLE_TIMEOUT):
self.app = app
self.idle_timeout = idle_timeout
self.last_activity = time.time()
self._checker_task = None
async def __call__(self, scope, receive, send):
# Update activity timestamp on each request
self.last_activity = time.time()
await self.app(scope, receive, send)
def start_idle_checker(self):
"""Start the background task that checks for idle timeout."""
self._checker_task = asyncio.create_task(self._check_idle())
async def _check_idle(self):
"""Background task that exits the process after idle timeout."""
# If idle_timeout is 0, don't auto-exit
if self.idle_timeout <= 0:
return
while True:
await asyncio.sleep(30) # Check every 30 seconds
idle_time = time.time() - self.last_activity
if idle_time > self.idle_timeout:
logger.info(f"Idle timeout reached ({self.idle_timeout}s), shutting down daemon")
# Give a moment for any in-flight requests
await asyncio.sleep(1)
os._exit(0)
class DaemonLock:
"""
File-based lock to prevent multiple daemon instances.
Uses fcntl.flock for atomic locking on Unix systems.
"""
def __init__(self, lockfile: Path = LOCKFILE_PATH):
self.lockfile = lockfile
self._fd = None
def acquire(self) -> bool:
"""
Try to acquire the daemon lock.
Returns True if lock acquired, False if another daemon is running.
"""
self.lockfile.parent.mkdir(parents=True, exist_ok=True)
try:
self._fd = open(self.lockfile, "w")
fcntl.flock(self._fd.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
# Write PID for debugging
self._fd.write(str(os.getpid()))
self._fd.flush()
return True
except (IOError, OSError):
# Lock is held by another process
if self._fd:
self._fd.close()
self._fd = None
return False
def release(self):
"""Release the daemon lock."""
if self._fd:
try:
fcntl.flock(self._fd.fileno(), fcntl.LOCK_UN)
self._fd.close()
except Exception:
pass
finally:
self._fd = None
# Remove lockfile
try:
self.lockfile.unlink()
except Exception:
pass
def is_locked(self) -> bool:
"""Check if the lock is held by another process."""
if not self.lockfile.exists():
return False
try:
fd = open(self.lockfile, "r")
fcntl.flock(fd.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
# We got the lock, so no one else has it
fcntl.flock(fd.fileno(), fcntl.LOCK_UN)
fd.close()
return False
except (IOError, OSError):
return True
def get_pid(self) -> int | None:
"""Get the PID of the daemon holding the lock."""
if not self.lockfile.exists():
return None
try:
with open(self.lockfile, "r") as f:
return int(f.read().strip())
except (ValueError, IOError):
return None
def daemonize():
"""
Fork the current process into a background daemon.
Uses double-fork technique to properly detach from terminal.
"""
# First fork
pid = os.fork()
if pid > 0:
# Parent exits
sys.exit(0)
# Create new session
os.setsid()
# Second fork to prevent zombie processes
pid = os.fork()
if pid > 0:
sys.exit(0)
# Redirect standard file descriptors to log file
DAEMON_LOG_PATH.parent.mkdir(parents=True, exist_ok=True)
sys.stdout.flush()
sys.stderr.flush()
# Redirect stdin to /dev/null
with open("/dev/null", "r") as devnull:
os.dup2(devnull.fileno(), sys.stdin.fileno())
# Redirect stdout/stderr to log file
log_fd = open(DAEMON_LOG_PATH, "a")
os.dup2(log_fd.fileno(), sys.stdout.fileno())
os.dup2(log_fd.fileno(), sys.stderr.fileno())
def check_daemon_running(port: int = DEFAULT_DAEMON_PORT) -> bool:
"""Check if a daemon is running and responsive on the given port."""
import socket
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex(("127.0.0.1", port))
sock.close()
return result == 0
except Exception:
return False
def stop_daemon(port: int = DEFAULT_DAEMON_PORT) -> bool:
"""Stop a running daemon by sending SIGTERM to the process."""
lock = DaemonLock()
pid = lock.get_pid()
if pid is None:
return False
try:
import signal
os.kill(pid, signal.SIGTERM)
# Wait for process to exit
for _ in range(50): # Wait up to 5 seconds
time.sleep(0.1)
try:
os.kill(pid, 0) # Check if process exists
except OSError:
return True # Process exited
return False
except OSError:
return False
@@ -3,11 +3,13 @@ LLM wrapper for unified configuration across providers.
"""
import asyncio
import json
import logging
import os
import time
from typing import Any
import httpx
from google import genai
from google.genai import errors as genai_errors
from google.genai import types as genai_types
@@ -157,7 +159,6 @@ class LLMProvider:
"""
async with _global_llm_semaphore:
start_time = time.time()
import json
# Handle Gemini provider separately
if self.provider == "gemini":
@@ -165,6 +166,20 @@ class LLMProvider:
messages, response_format, max_retries, initial_backoff, max_backoff, skip_validation, start_time
)
# Handle Ollama with native API for structured output (better schema enforcement)
if self.provider == "ollama" and response_format is not None:
return await self._call_ollama_native(
messages,
response_format,
max_completion_tokens,
temperature,
max_retries,
initial_backoff,
max_backoff,
skip_validation,
start_time,
)
call_params = {
"model": self.model,
"messages": messages,
@@ -324,6 +339,129 @@ class LLMProvider:
raise last_exception
raise RuntimeError("LLM call failed after all retries with no exception captured")
async def _call_ollama_native(
self,
messages: list[dict[str, str]],
response_format: Any,
max_completion_tokens: int | None,
temperature: float | None,
max_retries: int,
initial_backoff: float,
max_backoff: float,
skip_validation: bool,
start_time: float,
) -> Any:
"""
Call Ollama using native API with JSON schema enforcement.
Ollama's native API supports passing a full JSON schema in the 'format' parameter,
which provides better structured output control than the OpenAI-compatible API.
"""
# Get the JSON schema from the Pydantic model
schema = response_format.model_json_schema() if hasattr(response_format, "model_json_schema") else None
# Build the base URL for Ollama's native API
# Default OpenAI-compatible URL is http://localhost:11434/v1
# Native API is at http://localhost:11434/api/chat
base_url = self.base_url or "http://localhost:11434/v1"
if base_url.endswith("/v1"):
native_url = base_url[:-3] + "/api/chat"
else:
native_url = base_url.rstrip("/") + "/api/chat"
# Build request payload
payload = {
"model": self.model,
"messages": messages,
"stream": False,
}
# Add schema as format parameter for structured output
if schema:
payload["format"] = schema
# Add optional parameters with optimized defaults for Ollama
# Benchmarking shows num_ctx=16384 + num_batch=512 is optimal
options = {
"num_ctx": 16384, # 16k context window for larger prompts
"num_batch": 512, # Optimal batch size for prompt processing
}
if max_completion_tokens:
options["num_predict"] = max_completion_tokens
if temperature is not None:
options["temperature"] = temperature
payload["options"] = options
last_exception = None
async with httpx.AsyncClient(timeout=300.0) as client:
for attempt in range(max_retries + 1):
try:
response = await client.post(native_url, json=payload)
response.raise_for_status()
result = response.json()
content = result.get("message", {}).get("content", "")
# Parse JSON response
try:
json_data = json.loads(content)
except json.JSONDecodeError as json_err:
content_preview = content[:500] if content else "<empty>"
if content and len(content) > 700:
content_preview = f"{content[:500]}...TRUNCATED...{content[-200:]}"
logger.warning(
f"Ollama JSON parse error (attempt {attempt + 1}/{max_retries + 1}): {json_err}\n"
f" Model: ollama/{self.model}\n"
f" Content length: {len(content) if content else 0} chars\n"
f" Content preview: {content_preview!r}"
)
if attempt < max_retries:
backoff = min(initial_backoff * (2**attempt), max_backoff)
await asyncio.sleep(backoff)
last_exception = json_err
continue
else:
raise
# Validate against Pydantic model or return raw JSON
if skip_validation:
return json_data
else:
return response_format.model_validate(json_data)
except httpx.HTTPStatusError as e:
last_exception = e
if attempt < max_retries:
logger.warning(
f"Ollama HTTP error (attempt {attempt + 1}/{max_retries + 1}): {e.response.status_code}"
)
backoff = min(initial_backoff * (2**attempt), max_backoff)
await asyncio.sleep(backoff)
continue
else:
logger.error(f"Ollama HTTP error after {max_retries + 1} attempts: {e}")
raise
except httpx.RequestError as e:
last_exception = e
if attempt < max_retries:
logger.warning(f"Ollama connection error (attempt {attempt + 1}/{max_retries + 1}): {e}")
backoff = min(initial_backoff * (2**attempt), max_backoff)
await asyncio.sleep(backoff)
continue
else:
logger.error(f"Ollama connection error after {max_retries + 1} attempts: {e}")
raise
except Exception as e:
logger.error(f"Unexpected error during Ollama call: {type(e).__name__}: {e}")
raise
if last_exception:
raise last_exception
raise RuntimeError("Ollama call failed after all retries")
async def _call_gemini(
self,
messages: list[dict[str, str]],
@@ -335,8 +473,6 @@ class LLMProvider:
start_time: float,
) -> Any:
"""Handle Gemini-specific API calls."""
import json
# Convert OpenAI-style messages to Gemini format
system_instruction = None
gemini_contents = []
@@ -202,6 +202,8 @@ class MemoryEngine(MemoryEngineInterface):
run_migrations: bool = True,
operation_validator: "OperationValidatorExtension | None" = None,
tenant_extension: "TenantExtension | None" = None,
skip_llm_verification: bool | None = None,
lazy_reranker: bool | None = None,
):
"""
Initialize the temporal + semantic memory system.
@@ -227,17 +229,29 @@ class MemoryEngine(MemoryEngineInterface):
If provided, retain/recall/reflect operations will be validated.
tenant_extension: Optional extension for multi-tenancy and API key authentication.
If provided, operations require a RequestContext for authentication.
skip_llm_verification: Skip LLM connection verification during initialization.
Defaults to HINDSIGHT_API_SKIP_LLM_VERIFICATION env var or False.
lazy_reranker: Delay reranker initialization until first use. Useful for retain-only
operations that don't need the cross-encoder. Defaults to
HINDSIGHT_API_LAZY_RERANKER env var or False.
"""
# Load config from environment for any missing parameters
from ..config import get_config
config = get_config()
# Apply optimization flags from config if not explicitly provided
self._skip_llm_verification = (
skip_llm_verification if skip_llm_verification is not None else config.skip_llm_verification
)
self._lazy_reranker = lazy_reranker if lazy_reranker is not None else config.lazy_reranker
# 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
if not memory_llm_api_key:
# Ollama doesn't require an API key
if not memory_llm_api_key and memory_llm_provider != "ollama":
raise ValueError("LLM API key is required. Set HINDSIGHT_API_LLM_API_KEY environment variable.")
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
@@ -395,22 +409,22 @@ class MemoryEngine(MemoryEngineInterface):
Args:
task_dict: Dict with 'node_ids' key containing list of node IDs to update
Raises:
Exception: Any exception from database operations (propagates to execute_task for retry)
"""
node_ids = task_dict.get("node_ids", [])
if not node_ids:
return
pool = await self._get_pool()
try:
# Convert string UUIDs to UUID type for faster matching
uuid_list = [uuid.UUID(nid) for nid in node_ids]
async with acquire_with_retry(pool) as conn:
await conn.execute(
f"UPDATE {fq_table('memory_units')} SET access_count = access_count + 1 WHERE id = ANY($1::uuid[])",
uuid_list,
)
except Exception as e:
logger.error(f"Access count handler: Error updating access counts: {e}")
# Convert string UUIDs to UUID type for faster matching
uuid_list = [uuid.UUID(nid) for nid in node_ids]
async with acquire_with_retry(pool) as conn:
await conn.execute(
f"UPDATE {fq_table('memory_units')} SET access_count = access_count + 1 WHERE id = ANY($1::uuid[])",
uuid_list,
)
async def _handle_batch_retain(self, task_dict: dict[str, Any]):
"""
@@ -418,29 +432,27 @@ class MemoryEngine(MemoryEngineInterface):
Args:
task_dict: Dict with 'bank_id', 'contents'
Raises:
ValueError: If bank_id is missing
Exception: Any exception from retain_batch_async (propagates to execute_task for retry)
"""
try:
bank_id = task_dict.get("bank_id")
if not bank_id:
raise ValueError("bank_id is required for batch retain task")
contents = task_dict.get("contents", [])
bank_id = task_dict.get("bank_id")
if not bank_id:
raise ValueError("bank_id is required for batch retain task")
contents = task_dict.get("contents", [])
logger.info(
f"[BATCH_RETAIN_TASK] Starting background batch retain for bank_id={bank_id}, {len(contents)} items"
)
logger.info(
f"[BATCH_RETAIN_TASK] Starting background batch retain for bank_id={bank_id}, {len(contents)} items"
)
# Use internal request context for background tasks
from hindsight_api.models import RequestContext
# Use internal request context for background tasks
from hindsight_api.models import RequestContext
internal_context = RequestContext()
await self.retain_batch_async(bank_id=bank_id, contents=contents, request_context=internal_context)
internal_context = RequestContext()
await self.retain_batch_async(bank_id=bank_id, contents=contents, request_context=internal_context)
logger.info(f"[BATCH_RETAIN_TASK] Completed background batch retain for bank_id={bank_id}")
except Exception as e:
logger.error(f"Batch retain handler: Error processing batch retain: {e}")
import traceback
traceback.print_exc()
logger.info(f"[BATCH_RETAIN_TASK] Completed background batch retain for bank_id={bank_id}")
async def execute_task(self, task_dict: dict[str, Any]):
"""
@@ -593,6 +605,8 @@ class MemoryEngine(MemoryEngineInterface):
await loop.run_in_executor(None, lambda: asyncio.run(cross_encoder.initialize()))
else:
await cross_encoder.initialize()
# Mark reranker as initialized
self._cross_encoder_reranker._initialized = True
async def init_query_analyzer():
"""Initialize query analyzer model."""
@@ -601,16 +615,26 @@ class MemoryEngine(MemoryEngineInterface):
async def verify_llm():
"""Verify LLM connection is working."""
await self._llm_config.verify_connection()
if not self._skip_llm_verification:
await self._llm_config.verify_connection()
# Run pg0 and all model initializations in parallel
await asyncio.gather(
# Build list of initialization tasks
init_tasks = [
start_pg0(),
init_embeddings(),
init_cross_encoder(),
init_query_analyzer(),
verify_llm(),
)
]
# Only init cross-encoder eagerly if not using lazy initialization
if not self._lazy_reranker:
init_tasks.append(init_cross_encoder())
# Only verify LLM if not skipping
if not self._skip_llm_verification:
init_tasks.append(verify_llm())
# Run pg0 and selected model initializations in parallel
await asyncio.gather(*init_tasks)
# Run database migrations if enabled
if self._run_migrations:
@@ -671,7 +695,14 @@ class MemoryEngine(MemoryEngineInterface):
Returns:
dict with status and optional error message
Note:
Returns unhealthy until initialize() has completed successfully.
"""
# Not healthy until fully initialized
if not self._initialized:
return {"status": "unhealthy", "reason": "not_initialized"}
try:
pool = await self._get_pool()
async with pool.acquire() as conn:
@@ -1640,6 +1671,9 @@ class MemoryEngine(MemoryEngineInterface):
step_start = time.time()
reranker_instance = self._cross_encoder_reranker
# Ensure reranker is initialized (for lazy initialization mode)
await reranker_instance.ensure_initialized()
# Rerank using cross-encoder
scored_results = reranker_instance.rerank(query, merged_candidates)
@@ -3648,90 +3682,87 @@ Guidelines:
task_dict: Dict with 'bank_id' and either:
- 'entity_ids' (list): Process multiple entities
- 'entity_id', 'entity_name': Process single entity (legacy)
Raises:
ValueError: If required fields are missing
Exception: Any exception from regenerate_entity_observations (propagates to execute_task for retry)
"""
try:
bank_id = task_dict.get("bank_id")
# Use internal request context for background tasks
from hindsight_api.models import RequestContext
bank_id = task_dict.get("bank_id")
# Use internal request context for background tasks
from hindsight_api.models import RequestContext
internal_context = RequestContext()
internal_context = RequestContext()
# New format: multiple entity_ids
if "entity_ids" in task_dict:
entity_ids = task_dict.get("entity_ids", [])
min_facts = task_dict.get("min_facts", 5)
# New format: multiple entity_ids
if "entity_ids" in task_dict:
entity_ids = task_dict.get("entity_ids", [])
min_facts = task_dict.get("min_facts", 5)
if not bank_id or not entity_ids:
logger.error(f"[OBSERVATIONS] Missing required fields in task: {task_dict}")
return
if not bank_id or not entity_ids:
raise ValueError(f"[OBSERVATIONS] Missing required fields in task: {task_dict}")
# Process each entity
pool = await self._get_pool()
async with pool.acquire() as conn:
for entity_id in entity_ids:
try:
# Fetch entity name and check fact count
import uuid as uuid_module
# Process each entity
pool = await self._get_pool()
async with pool.acquire() as conn:
for entity_id in entity_ids:
try:
# Fetch entity name and check fact count
import uuid as uuid_module
entity_uuid = uuid_module.UUID(entity_id) if isinstance(entity_id, str) else entity_id
entity_uuid = uuid_module.UUID(entity_id) if isinstance(entity_id, str) else entity_id
# First check if entity exists
entity_exists = await conn.fetchrow(
f"SELECT canonical_name FROM {fq_table('entities')} WHERE id = $1 AND bank_id = $2",
entity_uuid,
bank_id,
)
# First check if entity exists
entity_exists = await conn.fetchrow(
f"SELECT canonical_name FROM {fq_table('entities')} WHERE id = $1 AND bank_id = $2",
entity_uuid,
bank_id,
)
if not entity_exists:
logger.debug(f"[OBSERVATIONS] Entity {entity_id} not yet in bank {bank_id}, skipping")
continue
entity_name = entity_exists["canonical_name"]
# Count facts linked to this entity
fact_count = (
await conn.fetchval(
f"SELECT COUNT(*) FROM {fq_table('unit_entities')} WHERE entity_id = $1",
entity_uuid,
)
or 0
)
# Only regenerate if entity has enough facts
if fact_count >= min_facts:
await self.regenerate_entity_observations(
bank_id, entity_id, entity_name, version=None, request_context=internal_context
)
else:
logger.debug(
f"[OBSERVATIONS] Skipping {entity_name} ({fact_count} facts < {min_facts} threshold)"
)
except Exception as e:
logger.error(f"[OBSERVATIONS] Error processing entity {entity_id}: {e}")
if not entity_exists:
logger.debug(f"[OBSERVATIONS] Entity {entity_id} not yet in bank {bank_id}, skipping")
continue
# Legacy format: single entity
else:
entity_id = task_dict.get("entity_id")
entity_name = task_dict.get("entity_name")
version = task_dict.get("version")
entity_name = entity_exists["canonical_name"]
if not all([bank_id, entity_id, entity_name]):
logger.error(f"[OBSERVATIONS] Missing required fields in task: {task_dict}")
return
# Count facts linked to this entity
fact_count = (
await conn.fetchval(
f"SELECT COUNT(*) FROM {fq_table('unit_entities')} WHERE entity_id = $1",
entity_uuid,
)
or 0
)
# Type assertions after validation
assert isinstance(bank_id, str) and isinstance(entity_id, str) and isinstance(entity_name, str)
await self.regenerate_entity_observations(
bank_id, entity_id, entity_name, version=version, request_context=internal_context
)
# Only regenerate if entity has enough facts
if fact_count >= min_facts:
await self.regenerate_entity_observations(
bank_id, entity_id, entity_name, version=None, request_context=internal_context
)
else:
logger.debug(
f"[OBSERVATIONS] Skipping {entity_name} ({fact_count} facts < {min_facts} threshold)"
)
except Exception as e:
logger.error(f"[OBSERVATIONS] Error regenerating observations: {e}")
import traceback
except Exception as e:
# Log but continue processing other entities - individual entity failures
# shouldn't fail the whole batch
logger.error(f"[OBSERVATIONS] Error processing entity {entity_id}: {e}")
continue
traceback.print_exc()
# Legacy format: single entity
else:
entity_id = task_dict.get("entity_id")
entity_name = task_dict.get("entity_name")
version = task_dict.get("version")
if not all([bank_id, entity_id, entity_name]):
raise ValueError(f"[OBSERVATIONS] Missing required fields in task: {task_dict}")
# Type assertions after validation
assert isinstance(bank_id, str) and isinstance(entity_id, str) and isinstance(entity_name, str)
await self.regenerate_entity_observations(
bank_id, entity_id, entity_name, version=version, request_context=internal_context
)
# =========================================================================
# Statistics & Operations (for HTTP API layer)
@@ -106,9 +106,62 @@ async def retain_batch(
)
if not extracted_facts:
# Still need to create document if document_id was provided
async with acquire_with_retry(pool) as conn:
async with conn.transaction():
await fact_storage.ensure_bank_exists(conn, bank_id)
# Handle document tracking even with no facts
if document_id:
combined_content = "\n".join([c.get("content", "") for c in contents_dicts])
retain_params = {}
if contents_dicts:
first_item = contents_dicts[0]
if first_item.get("context"):
retain_params["context"] = first_item["context"]
if first_item.get("event_date"):
retain_params["event_date"] = (
first_item["event_date"].isoformat()
if hasattr(first_item["event_date"], "isoformat")
else str(first_item["event_date"])
)
if first_item.get("metadata"):
retain_params["metadata"] = first_item["metadata"]
await fact_storage.handle_document_tracking(
conn, bank_id, document_id, combined_content, is_first_batch, retain_params
)
else:
# Check for per-item document_ids
from collections import defaultdict
contents_by_doc = defaultdict(list)
for idx, content_dict in enumerate(contents_dicts):
doc_id = content_dict.get("document_id")
if doc_id:
contents_by_doc[doc_id].append((idx, content_dict))
for doc_id, doc_contents in contents_by_doc.items():
combined_content = "\n".join([c.get("content", "") for _, c in doc_contents])
retain_params = {}
if doc_contents:
first_item = doc_contents[0][1]
if first_item.get("context"):
retain_params["context"] = first_item["context"]
if first_item.get("event_date"):
retain_params["event_date"] = (
first_item["event_date"].isoformat()
if hasattr(first_item["event_date"], "isoformat")
else str(first_item["event_date"])
)
if first_item.get("metadata"):
retain_params["metadata"] = first_item["metadata"]
await fact_storage.handle_document_tracking(
conn, bank_id, doc_id, combined_content, is_first_batch, retain_params
)
total_time = time.time() - start_time
logger.info(
f"RETAIN_BATCH COMPLETE: 0 facts extracted from {len(contents)} contents in {total_time:.3f}s (nothing to store)"
f"RETAIN_BATCH COMPLETE: 0 facts extracted from {len(contents)} contents in {total_time:.3f}s (document tracked, no facts)"
)
return [[] for _ in contents]
@@ -26,6 +26,23 @@ class CrossEncoderReranker:
cross_encoder = create_cross_encoder_from_env()
self.cross_encoder = cross_encoder
self._initialized = False
async def ensure_initialized(self):
"""Ensure the cross-encoder model is initialized (for lazy initialization)."""
if self._initialized:
return
import asyncio
cross_encoder = self.cross_encoder
# For local providers, run in thread pool to avoid blocking event loop
if cross_encoder.provider_name == "local":
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, lambda: asyncio.run(cross_encoder.initialize()))
else:
await cross_encoder.initialize()
self._initialized = True
def rerank(self, query: str, candidates: list[MergedCandidate]) -> list[ScoredResult]:
"""
@@ -89,6 +89,38 @@ class TaskBackend(ABC):
traceback.print_exc()
class SyncTaskBackend(TaskBackend):
"""
Synchronous task backend that executes tasks immediately.
This is useful for embedded/CLI usage where we don't want background
workers that prevent clean exit. Tasks are executed inline rather than
being queued.
"""
async def initialize(self):
"""No-op for sync backend."""
self._initialized = True
logger.debug("SyncTaskBackend initialized")
async def submit_task(self, task_dict: dict[str, Any]):
"""
Execute the task immediately (synchronously).
Args:
task_dict: Task dictionary to execute
"""
if not self._initialized:
await self.initialize()
await self._execute_task(task_dict)
async def shutdown(self):
"""No-op for sync backend."""
self._initialized = False
logger.debug("SyncTaskBackend shutdown")
class AsyncIOQueueBackend(TaskBackend):
"""
Task backend implementation using asyncio queues.
+95 -15
View File
@@ -4,6 +4,9 @@ Command-line interface for Hindsight API.
Run the server with:
hindsight-api
Run as background daemon:
hindsight-api --daemon
Stop with Ctrl+C.
"""
@@ -21,9 +24,13 @@ from . import MemoryEngine
from .api import create_app
from .banner import print_banner
from .config import HindsightConfig, get_config
print()
print_banner()
from .daemon import (
DEFAULT_DAEMON_PORT,
DEFAULT_IDLE_TIMEOUT,
DaemonLock,
IdleTimeoutMiddleware,
daemonize,
)
# Filter deprecation warnings from third-party libraries
warnings.filterwarnings("ignore", message="websockets.legacy is deprecated")
@@ -106,8 +113,52 @@ def main():
parser.add_argument("--ssl-keyfile", default=None, help="SSL key file")
parser.add_argument("--ssl-certfile", default=None, help="SSL certificate file")
# Daemon mode options
parser.add_argument(
"--daemon",
action="store_true",
help=f"Run as background daemon (uses port {DEFAULT_DAEMON_PORT}, auto-exits after idle)",
)
parser.add_argument(
"--idle-timeout",
type=int,
default=DEFAULT_IDLE_TIMEOUT,
help=f"Idle timeout in seconds before auto-exit in daemon mode (default: {DEFAULT_IDLE_TIMEOUT})",
)
args = parser.parse_args()
# Daemon mode handling
if args.daemon:
# Use fixed daemon port
args.port = DEFAULT_DAEMON_PORT
args.host = "127.0.0.1" # Only bind to localhost for security
# Check if another daemon is already running
daemon_lock = DaemonLock()
if not daemon_lock.acquire():
print(f"Daemon already running (PID: {daemon_lock.get_pid()})", file=sys.stderr)
sys.exit(1)
# Fork into background
daemonize()
# Re-acquire lock in child process
daemon_lock = DaemonLock()
if not daemon_lock.acquire():
sys.exit(1)
# Register cleanup to release lock
def release_lock():
daemon_lock.release()
atexit.register(release_lock)
# Print banner (not in daemon mode)
if not args.daemon:
print()
print_banner()
# Configure Python logging based on log level
# Update config with CLI override if provided
if args.log_level != config.log_level:
@@ -128,9 +179,12 @@ def main():
log_level=args.log_level,
mcp_enabled=config.mcp_enabled,
graph_retriever=config.graph_retriever,
skip_llm_verification=config.skip_llm_verification,
lazy_reranker=config.lazy_reranker,
)
config.configure_logging()
config.log_config()
if not args.daemon:
config.log_config()
# Register cleanup handlers
atexit.register(_cleanup)
@@ -149,6 +203,12 @@ def main():
initialize_memory=True,
)
# Wrap with idle timeout middleware in daemon mode
idle_middleware = None
if args.daemon:
idle_middleware = IdleTimeoutMiddleware(app, idle_timeout=args.idle_timeout)
app = idle_middleware
# Prepare uvicorn config
uvicorn_config = {
"app": app,
@@ -172,18 +232,38 @@ def main():
if args.ssl_certfile:
uvicorn_config["ssl_certfile"] = args.ssl_certfile
from .banner import print_startup_info
# Print startup info (not in daemon mode)
if not args.daemon:
from .banner import print_startup_info
print_startup_info(
host=args.host,
port=args.port,
database_url=config.database_url,
llm_provider=config.llm_provider,
llm_model=config.llm_model,
embeddings_provider=config.embeddings_provider,
reranker_provider=config.reranker_provider,
mcp_enabled=config.mcp_enabled,
)
print_startup_info(
host=args.host,
port=args.port,
database_url=config.database_url,
llm_provider=config.llm_provider,
llm_model=config.llm_model,
embeddings_provider=config.embeddings_provider,
reranker_provider=config.reranker_provider,
mcp_enabled=config.mcp_enabled,
)
# Start idle checker in daemon mode
if idle_middleware is not None:
# Start the idle checker in a background thread with its own event loop
import threading
def run_idle_checker():
import time
time.sleep(2) # Wait for uvicorn to start
try:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(idle_middleware._check_idle())
except Exception:
pass
threading.Thread(target=run_idle_checker, daemon=True).start()
uvicorn.run(**uvicorn_config) # type: ignore[invalid-argument-type] - dict kwargs
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "hindsight-api"
version = "0.1.11"
version = "0.1.14"
description = "Hindsight: Agent Memory That Works Like Human Memory"
readme = "README.md"
requires-python = ">=3.11"
+11 -2
View File
@@ -26,6 +26,9 @@ MODEL_MATRIX = [
("gemini", "gemini-2.5-flash"),
("gemini", "gemini-2.5-flash-lite"),
("gemini", "gemini-3-pro-preview"),
# Ollama models (local)
("ollama", "gemma3:12b"),
("ollama", "gemma3:1b"),
]
@@ -48,12 +51,18 @@ async def test_llm_provider_memory_operations(provider: str, model: str):
All models must pass this test.
"""
api_key = get_api_key_for_provider(provider)
if not api_key:
# Skip Ollama tests in CI (no models available)
if provider == "ollama" and os.getenv("CI"):
pytest.skip(f"Skipping {provider}/{model}: Ollama not available in CI")
# Other providers need an API key
if provider != "ollama" and not api_key:
pytest.skip(f"Skipping {provider}/{model}: no API key available")
llm = LLMProvider(
provider=provider,
api_key=api_key,
api_key=api_key or "",
base_url="",
model=model,
)
-102
View File
@@ -1,102 +0,0 @@
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_name: memora
release_name: memora-linux-x86_64
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
artifact_name: memora
release_name: memora-linux-arm64
- os: macos-latest
target: x86_64-apple-darwin
artifact_name: memora
release_name: memora-macos-x86_64
- os: macos-latest
target: aarch64-apple-darwin
artifact_name: memora
release_name: memora-macos-arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross-compilation tools (Linux ARM64)
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
- name: Build
run: cargo build --release --target ${{ matrix.target }}
- name: Strip binary (Linux)
if: runner.os == 'Linux'
run: strip target/${{ matrix.target }}/release/${{ matrix.artifact_name }}
- name: Strip binary (macOS)
if: runner.os == 'macOS'
run: strip target/${{ matrix.target }}/release/${{ matrix.artifact_name }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.release_name }}
path: target/${{ matrix.target }}/release/${{ matrix.artifact_name }}
release:
name: Create Release
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create checksums
run: |
cd artifacts
for dir in */; do
cd "$dir"
sha256sum * > SHA256SUMS
cd ..
done
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: |
artifacts/memora-linux-x86_64/memora
artifacts/memora-linux-arm64/memora
artifacts/memora-macos-x86_64/memora
artifacts/memora-macos-arm64/memora
artifacts/*/SHA256SUMS
draft: false
prerelease: false
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "hindsight-cli"
version = "0.1.11"
version = "0.1.14"
edition = "2021"
authors = ["Hindsight Team"]
description = "A beautiful CLI for Hindsight - semantic memory system"
+128
View File
@@ -0,0 +1,128 @@
#!/bin/bash
# CLI smoke test - verifies basic CLI functionality against a running API server
#
# Prerequisites:
# - hindsight CLI must be in PATH or HINDSIGHT_CLI env var set
# - API server must be running at HINDSIGHT_API_URL (default: http://localhost:8888)
#
# Usage:
# ./hindsight-cli/smoke-test.sh
# HINDSIGHT_CLI=/path/to/hindsight ./hindsight-cli/smoke-test.sh
set -e
# Configuration
HINDSIGHT_CLI="${HINDSIGHT_CLI:-hindsight}"
export HINDSIGHT_API_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
TEST_BANK="cli-smoke-test-$(date +%s)"
echo "=== Hindsight CLI Smoke Test ==="
echo "CLI: $HINDSIGHT_CLI"
echo "API URL: $HINDSIGHT_API_URL"
echo "Test bank: $TEST_BANK"
echo ""
# Helper function
run_test() {
local name="$1"
shift
echo -n "Testing: $name... "
if "$@" > /tmp/cli-test-output.txt 2>&1; then
echo "OK"
return 0
else
echo "FAILED"
echo " Command: $*"
echo " Output:"
cat /tmp/cli-test-output.txt | sed 's/^/ /'
return 1
fi
}
run_test_output() {
local name="$1"
local expected="$2"
shift 2
echo -n "Testing: $name... "
if "$@" > /tmp/cli-test-output.txt 2>&1; then
if grep -qi "$expected" /tmp/cli-test-output.txt; then
echo "OK"
return 0
else
echo "FAILED (expected '$expected' not found)"
echo " Command: $*"
echo " Output:"
cat /tmp/cli-test-output.txt | sed 's/^/ /'
return 1
fi
else
echo "FAILED"
echo " Command: $*"
echo " Output:"
cat /tmp/cli-test-output.txt | sed 's/^/ /'
return 1
fi
}
cleanup() {
echo ""
echo "Cleaning up test bank..."
"$HINDSIGHT_CLI" bank delete "$TEST_BANK" 2>/dev/null || true
}
trap cleanup EXIT
FAILED=0
# Test 1: Version
run_test "version" "$HINDSIGHT_CLI" --version || FAILED=1
# Test 2: Help
run_test "help" "$HINDSIGHT_CLI" --help || FAILED=1
# Test 3: Configure help
run_test "configure help" "$HINDSIGHT_CLI" configure --help || FAILED=1
# Test 4: List banks (JSON output)
run_test "list banks" "$HINDSIGHT_CLI" bank list -o json || FAILED=1
# Test 5: Set bank name (creates the bank)
run_test "set bank name" "$HINDSIGHT_CLI" bank name "$TEST_BANK" "CLI Smoke Test Bank" || FAILED=1
# Test 6: Get bank disposition
run_test_output "get bank disposition" "CLI Smoke Test Bank" "$HINDSIGHT_CLI" bank disposition "$TEST_BANK" || FAILED=1
# Test 7: Retain memory
run_test "retain memory" "$HINDSIGHT_CLI" memory retain "$TEST_BANK" "Alice is a software engineer who loves Rust programming" || FAILED=1
# Test 8: Retain more memories
run_test "retain more memories" "$HINDSIGHT_CLI" memory retain "$TEST_BANK" "Bob is Alice's colleague who prefers Python" || FAILED=1
# Test 9: Recall memories
run_test_output "recall memories" "Alice" "$HINDSIGHT_CLI" memory recall "$TEST_BANK" "Who is Alice?" || FAILED=1
# Test 10: Reflect on memories
run_test_output "reflect" "Alice" "$HINDSIGHT_CLI" memory reflect "$TEST_BANK" "What do you know about Alice?" || FAILED=1
# Test 11: Get bank stats
run_test "bank stats" "$HINDSIGHT_CLI" bank stats "$TEST_BANK" || FAILED=1
# Test 12: List entities
run_test "list entities" "$HINDSIGHT_CLI" entity list "$TEST_BANK" || FAILED=1
# Test 13: List documents
run_test "list documents" "$HINDSIGHT_CLI" document list "$TEST_BANK" || FAILED=1
# Test 14: Clear memories
run_test "clear memories" "$HINDSIGHT_CLI" memory clear "$TEST_BANK" || FAILED=1
# Test 15: Delete bank
run_test "delete bank" "$HINDSIGHT_CLI" bank delete "$TEST_BANK" || FAILED=1
echo ""
if [ $FAILED -eq 0 ]; then
echo "=== All smoke tests passed! ==="
exit 0
else
echo "=== Some smoke tests failed ==="
exit 1
fi
+37 -24
View File
@@ -89,14 +89,14 @@ impl ApiClient {
pub fn list_agents(&self, _verbose: bool) -> Result<Vec<types::BankListItem>> {
self.runtime.block_on(async {
let response = self.client.list_banks().await?;
let response = self.client.list_banks(None).await?;
Ok(response.into_inner().banks)
})
}
pub fn get_profile(&self, agent_id: &str, _verbose: bool) -> Result<types::BankProfileResponse> {
self.runtime.block_on(async {
let response = self.client.get_bank_profile(agent_id).await?;
let response = self.client.get_bank_profile(agent_id, None).await?;
Ok(response.into_inner())
})
}
@@ -105,7 +105,9 @@ impl ApiClient {
self.runtime.block_on(async {
let response = self.client.get_agent_stats(agent_id).await?;
let value = response.into_inner();
let stats: AgentStats = serde_json::from_value(value)?;
// Convert to JSON Value first, then parse into our type
let json_value = serde_json::to_value(&value)?;
let stats: AgentStats = serde_json::from_value(json_value)?;
Ok(stats)
})
}
@@ -117,7 +119,7 @@ impl ApiClient {
background: None,
disposition: None,
};
let response = self.client.create_or_update_bank(agent_id, &request).await?;
let response = self.client.create_or_update_bank(agent_id, None, &request).await?;
Ok(response.into_inner())
})
}
@@ -128,7 +130,7 @@ impl ApiClient {
content: content.to_string(),
update_disposition,
};
let response = self.client.add_bank_background(agent_id, &request).await?;
let response = self.client.add_bank_background(agent_id, None, &request).await?;
Ok(response.into_inner())
})
}
@@ -138,21 +140,21 @@ impl ApiClient {
eprintln!("Request body: {}", serde_json::to_string_pretty(request).unwrap_or_default());
}
self.runtime.block_on(async {
let response = self.client.recall_memories(agent_id, request).await?;
let response = self.client.recall_memories(agent_id, None, request).await?;
Ok(response.into_inner())
})
}
pub fn reflect(&self, agent_id: &str, request: &types::ReflectRequest, _verbose: bool) -> Result<types::ReflectResponse> {
self.runtime.block_on(async {
let response = self.client.reflect(agent_id, request).await?;
let response = self.client.reflect(agent_id, None, request).await?;
Ok(response.into_inner())
})
}
pub fn retain(&self, agent_id: &str, request: &types::RetainRequest, _async_mode: bool, _verbose: bool) -> Result<MemoryPutResult> {
self.runtime.block_on(async {
let response = self.client.retain_memories(agent_id, request).await?;
let response = self.client.retain_memories(agent_id, None, request).await?;
let result = response.into_inner();
Ok(MemoryPutResult {
success: result.success,
@@ -170,7 +172,7 @@ impl ApiClient {
pub fn clear_memories(&self, agent_id: &str, fact_type: Option<&str>, _verbose: bool) -> Result<types::DeleteResponse> {
self.runtime.block_on(async {
let response = self.client.clear_bank_memories(agent_id, fact_type).await?;
let response = self.client.clear_bank_memories(agent_id, None, Some(fact_type)).await?;
Ok(response.into_inner())
})
}
@@ -181,7 +183,8 @@ impl ApiClient {
agent_id,
limit.map(|l| l as i64),
offset.map(|o| o as i64),
q
q,
None,
).await?;
Ok(response.into_inner())
})
@@ -189,69 +192,79 @@ impl ApiClient {
pub fn get_document(&self, agent_id: &str, document_id: &str, _verbose: bool) -> Result<types::DocumentResponse> {
self.runtime.block_on(async {
let response = self.client.get_document(agent_id, document_id).await?;
let response = self.client.get_document(agent_id, document_id, None).await?;
Ok(response.into_inner())
})
}
pub fn delete_document(&self, agent_id: &str, document_id: &str, _verbose: bool) -> Result<types::DeleteResponse> {
self.runtime.block_on(async {
let response = self.client.delete_document(agent_id, document_id).await?;
let response = self.client.delete_document(agent_id, document_id, None).await?;
let value = response.into_inner();
let result: types::DeleteResponse = serde_json::from_value(value)?;
Ok(result)
// Convert typed response to DeleteResponse
Ok(types::DeleteResponse {
deleted_count: Some(value.memory_units_deleted),
message: Some(value.message),
success: value.success,
})
})
}
pub fn list_operations(&self, agent_id: &str, _verbose: bool) -> Result<OperationsResponse> {
self.runtime.block_on(async {
let response = self.client.list_operations(agent_id).await?;
let response = self.client.list_operations(agent_id, None).await?;
let value = response.into_inner();
let ops: OperationsResponse = serde_json::from_value(value)?;
// Convert to JSON Value first, then parse into our type
let json_value = serde_json::to_value(&value)?;
let ops: OperationsResponse = serde_json::from_value(json_value)?;
Ok(ops)
})
}
pub fn cancel_operation(&self, agent_id: &str, operation_id: &str, _verbose: bool) -> Result<types::DeleteResponse> {
self.runtime.block_on(async {
let response = self.client.cancel_operation(agent_id, operation_id).await?;
let response = self.client.cancel_operation(agent_id, operation_id, None).await?;
let value = response.into_inner();
let result: types::DeleteResponse = serde_json::from_value(value)?;
Ok(result)
// Convert typed response to DeleteResponse
Ok(types::DeleteResponse {
deleted_count: None,
message: Some(value.message),
success: value.success,
})
})
}
pub fn list_memories(&self, bank_id: &str, type_filter: Option<&str>, q: Option<&str>, limit: Option<i64>, offset: Option<i64>, _verbose: bool) -> Result<types::ListMemoryUnitsResponse> {
self.runtime.block_on(async {
let response = self.client.list_memories(bank_id, limit, offset, q, type_filter).await?;
let response = self.client.list_memories(bank_id, limit, offset, q, type_filter, None).await?;
Ok(response.into_inner())
})
}
pub fn list_entities(&self, bank_id: &str, limit: Option<i64>, _verbose: bool) -> Result<types::EntityListResponse> {
self.runtime.block_on(async {
let response = self.client.list_entities(bank_id, limit).await?;
let response = self.client.list_entities(bank_id, limit, None).await?;
Ok(response.into_inner())
})
}
pub fn get_entity(&self, bank_id: &str, entity_id: &str, _verbose: bool) -> Result<types::EntityDetailResponse> {
self.runtime.block_on(async {
let response = self.client.get_entity(bank_id, entity_id).await?;
let response = self.client.get_entity(bank_id, entity_id, None).await?;
Ok(response.into_inner())
})
}
pub fn regenerate_entity(&self, bank_id: &str, entity_id: &str, _verbose: bool) -> Result<types::EntityDetailResponse> {
self.runtime.block_on(async {
let response = self.client.regenerate_entity_observations(bank_id, entity_id).await?;
let response = self.client.regenerate_entity_observations(bank_id, entity_id, None).await?;
Ok(response.into_inner())
})
}
pub fn delete_bank(&self, bank_id: &str, _verbose: bool) -> Result<types::DeleteResponse> {
self.runtime.block_on(async {
let response = self.client.delete_bank(bank_id).await?;
let response = self.client.delete_bank(bank_id, None).await?;
Ok(response.into_inner())
})
}
@@ -1,7 +1,11 @@
hindsight_client_api/__init__.py
hindsight_client_api/api/__init__.py
hindsight_client_api/api/default_api.py
hindsight_client_api/api/banks_api.py
hindsight_client_api/api/documents_api.py
hindsight_client_api/api/entities_api.py
hindsight_client_api/api/memory_api.py
hindsight_client_api/api/monitoring_api.py
hindsight_client_api/api/operations_api.py
hindsight_client_api/api_client.py
hindsight_client_api/api_response.py
hindsight_client_api/configuration.py
@@ -10,15 +14,20 @@ hindsight_client_api/docs/BackgroundResponse.md
hindsight_client_api/docs/BankListItem.md
hindsight_client_api/docs/BankListResponse.md
hindsight_client_api/docs/BankProfileResponse.md
hindsight_client_api/docs/BankStatsResponse.md
hindsight_client_api/docs/BanksApi.md
hindsight_client_api/docs/Budget.md
hindsight_client_api/docs/CancelOperationResponse.md
hindsight_client_api/docs/ChunkData.md
hindsight_client_api/docs/ChunkIncludeOptions.md
hindsight_client_api/docs/ChunkResponse.md
hindsight_client_api/docs/CreateBankRequest.md
hindsight_client_api/docs/DefaultApi.md
hindsight_client_api/docs/DeleteDocumentResponse.md
hindsight_client_api/docs/DeleteResponse.md
hindsight_client_api/docs/DispositionTraits.md
hindsight_client_api/docs/DocumentResponse.md
hindsight_client_api/docs/DocumentsApi.md
hindsight_client_api/docs/EntitiesApi.md
hindsight_client_api/docs/EntityDetailResponse.md
hindsight_client_api/docs/EntityIncludeOptions.md
hindsight_client_api/docs/EntityListItem.md
@@ -30,8 +39,12 @@ hindsight_client_api/docs/HTTPValidationError.md
hindsight_client_api/docs/IncludeOptions.md
hindsight_client_api/docs/ListDocumentsResponse.md
hindsight_client_api/docs/ListMemoryUnitsResponse.md
hindsight_client_api/docs/MemoryApi.md
hindsight_client_api/docs/MemoryItem.md
hindsight_client_api/docs/MonitoringApi.md
hindsight_client_api/docs/OperationResponse.md
hindsight_client_api/docs/OperationsApi.md
hindsight_client_api/docs/OperationsListResponse.md
hindsight_client_api/docs/RecallRequest.md
hindsight_client_api/docs/RecallResponse.md
hindsight_client_api/docs/RecallResult.md
@@ -51,11 +64,14 @@ hindsight_client_api/models/background_response.py
hindsight_client_api/models/bank_list_item.py
hindsight_client_api/models/bank_list_response.py
hindsight_client_api/models/bank_profile_response.py
hindsight_client_api/models/bank_stats_response.py
hindsight_client_api/models/budget.py
hindsight_client_api/models/cancel_operation_response.py
hindsight_client_api/models/chunk_data.py
hindsight_client_api/models/chunk_include_options.py
hindsight_client_api/models/chunk_response.py
hindsight_client_api/models/create_bank_request.py
hindsight_client_api/models/delete_document_response.py
hindsight_client_api/models/delete_response.py
hindsight_client_api/models/disposition_traits.py
hindsight_client_api/models/document_response.py
@@ -71,6 +87,8 @@ hindsight_client_api/models/include_options.py
hindsight_client_api/models/list_documents_response.py
hindsight_client_api/models/list_memory_units_response.py
hindsight_client_api/models/memory_item.py
hindsight_client_api/models/operation_response.py
hindsight_client_api/models/operations_list_response.py
hindsight_client_api/models/recall_request.py
hindsight_client_api/models/recall_response.py
hindsight_client_api/models/recall_result.py
@@ -90,15 +108,20 @@ hindsight_client_api/test/test_background_response.py
hindsight_client_api/test/test_bank_list_item.py
hindsight_client_api/test/test_bank_list_response.py
hindsight_client_api/test/test_bank_profile_response.py
hindsight_client_api/test/test_bank_stats_response.py
hindsight_client_api/test/test_banks_api.py
hindsight_client_api/test/test_budget.py
hindsight_client_api/test/test_cancel_operation_response.py
hindsight_client_api/test/test_chunk_data.py
hindsight_client_api/test/test_chunk_include_options.py
hindsight_client_api/test/test_chunk_response.py
hindsight_client_api/test/test_create_bank_request.py
hindsight_client_api/test/test_default_api.py
hindsight_client_api/test/test_delete_document_response.py
hindsight_client_api/test/test_delete_response.py
hindsight_client_api/test/test_disposition_traits.py
hindsight_client_api/test/test_document_response.py
hindsight_client_api/test/test_documents_api.py
hindsight_client_api/test/test_entities_api.py
hindsight_client_api/test/test_entity_detail_response.py
hindsight_client_api/test/test_entity_include_options.py
hindsight_client_api/test/test_entity_list_item.py
@@ -110,8 +133,12 @@ hindsight_client_api/test/test_http_validation_error.py
hindsight_client_api/test/test_include_options.py
hindsight_client_api/test/test_list_documents_response.py
hindsight_client_api/test/test_list_memory_units_response.py
hindsight_client_api/test/test_memory_api.py
hindsight_client_api/test/test_memory_item.py
hindsight_client_api/test/test_monitoring_api.py
hindsight_client_api/test/test_operation_response.py
hindsight_client_api/test/test_operations_api.py
hindsight_client_api/test/test_operations_list_response.py
hindsight_client_api/test/test_recall_request.py
hindsight_client_api/test/test_recall_response.py
hindsight_client_api/test/test_recall_result.py
@@ -10,7 +10,7 @@ from typing import Optional, List, Dict, Any
from datetime import datetime
import hindsight_client_api
from hindsight_client_api.api import default_api
from hindsight_client_api.api import memory_api, banks_api
from hindsight_client_api.models import (
recall_request,
retain_request,
@@ -74,7 +74,8 @@ class Hindsight:
"""
config = hindsight_client_api.Configuration(host=base_url, access_token=api_key)
self._api_client = hindsight_client_api.ApiClient(config)
self._api = default_api.DefaultApi(self._api_client)
self._memory_api = memory_api.MemoryApi(self._api_client)
self._banks_api = banks_api.BanksApi(self._api_client)
def __enter__(self):
"""Context manager entry."""
@@ -85,9 +86,21 @@ class Hindsight:
self.close()
def close(self):
"""Close the API client."""
"""Close the API client (sync version - use aclose() in async code)."""
if self._api_client:
_run_async(self._api_client.close())
try:
loop = asyncio.get_running_loop()
# We're in an async context - schedule but don't wait
# The caller should use aclose() instead
loop.create_task(self._api_client.close())
except RuntimeError:
# No running loop - safe to run synchronously
_run_async(self._api_client.close())
async def aclose(self):
"""Close the API client (async version)."""
if self._api_client:
await self._api_client.close()
# Simplified methods for main operations
@@ -156,7 +169,7 @@ class Hindsight:
async_=retain_async,
)
return _run_async(self._api.retain_memories(bank_id, request_obj))
return _run_async(self._memory_api.retain_memories(bank_id, request_obj))
def recall(
self,
@@ -208,7 +221,7 @@ class Hindsight:
include=include_opts,
)
return _run_async(self._api.recall_memories(bank_id, request_obj))
return _run_async(self._memory_api.recall_memories(bank_id, request_obj))
def reflect(
self,
@@ -235,7 +248,7 @@ class Hindsight:
context=context,
)
return _run_async(self._api.reflect(bank_id, request_obj))
return _run_async(self._memory_api.reflect(bank_id, request_obj))
def list_memories(
self,
@@ -246,7 +259,7 @@ class Hindsight:
offset: int = 0,
) -> ListMemoryUnitsResponse:
"""List memory units with pagination."""
return _run_async(self._api.list_memories(
return _run_async(self._memory_api.list_memories(
bank_id=bank_id,
type=type,
q=search_query,
@@ -274,7 +287,7 @@ class Hindsight:
disposition=disposition_obj,
)
return _run_async(self._api.create_or_update_bank(bank_id, request_obj))
return _run_async(self._banks_api.create_or_update_bank(bank_id, request_obj))
# Async methods (native async, no _run_async wrapper)
@@ -314,7 +327,7 @@ class Hindsight:
async_=retain_async,
)
return await self._api.retain_memories(bank_id, request_obj)
return await self._memory_api.retain_memories(bank_id, request_obj)
async def aretain(
self,
@@ -374,7 +387,7 @@ class Hindsight:
trace=False,
)
response = await self._api.recall_memories(bank_id, request_obj)
response = await self._memory_api.recall_memories(bank_id, request_obj)
return response.results if hasattr(response, 'results') else []
async def areflect(
@@ -402,4 +415,4 @@ class Hindsight:
context=context,
)
return await self._api.reflect(bank_id, request_obj)
return await self._memory_api.reflect(bank_id, request_obj)
@@ -7,7 +7,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -18,8 +18,12 @@ __version__ = "0.0.7"
# Define package exports
__all__ = [
"BanksApi",
"DocumentsApi",
"EntitiesApi",
"MemoryApi",
"MonitoringApi",
"DefaultApi",
"OperationsApi",
"ApiResponse",
"ApiClient",
"Configuration",
@@ -34,11 +38,14 @@ __all__ = [
"BankListItem",
"BankListResponse",
"BankProfileResponse",
"BankStatsResponse",
"Budget",
"CancelOperationResponse",
"ChunkData",
"ChunkIncludeOptions",
"ChunkResponse",
"CreateBankRequest",
"DeleteDocumentResponse",
"DeleteResponse",
"DispositionTraits",
"DocumentResponse",
@@ -54,6 +61,8 @@ __all__ = [
"ListDocumentsResponse",
"ListMemoryUnitsResponse",
"MemoryItem",
"OperationResponse",
"OperationsListResponse",
"RecallRequest",
"RecallResponse",
"RecallResult",
@@ -69,8 +78,12 @@ __all__ = [
]
# import apis into sdk package
from hindsight_client_api.api.banks_api import BanksApi as BanksApi
from hindsight_client_api.api.documents_api import DocumentsApi as DocumentsApi
from hindsight_client_api.api.entities_api import EntitiesApi as EntitiesApi
from hindsight_client_api.api.memory_api import MemoryApi as MemoryApi
from hindsight_client_api.api.monitoring_api import MonitoringApi as MonitoringApi
from hindsight_client_api.api.default_api import DefaultApi as DefaultApi
from hindsight_client_api.api.operations_api import OperationsApi as OperationsApi
# import ApiClient
from hindsight_client_api.api_response import ApiResponse as ApiResponse
@@ -89,11 +102,14 @@ from hindsight_client_api.models.background_response import BackgroundResponse a
from hindsight_client_api.models.bank_list_item import BankListItem as BankListItem
from hindsight_client_api.models.bank_list_response import BankListResponse as BankListResponse
from hindsight_client_api.models.bank_profile_response import BankProfileResponse as BankProfileResponse
from hindsight_client_api.models.bank_stats_response import BankStatsResponse as BankStatsResponse
from hindsight_client_api.models.budget import Budget as Budget
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse as CancelOperationResponse
from hindsight_client_api.models.chunk_data import ChunkData as ChunkData
from hindsight_client_api.models.chunk_include_options import ChunkIncludeOptions as ChunkIncludeOptions
from hindsight_client_api.models.chunk_response import ChunkResponse as ChunkResponse
from hindsight_client_api.models.create_bank_request import CreateBankRequest as CreateBankRequest
from hindsight_client_api.models.delete_document_response import DeleteDocumentResponse as DeleteDocumentResponse
from hindsight_client_api.models.delete_response import DeleteResponse as DeleteResponse
from hindsight_client_api.models.disposition_traits import DispositionTraits as DispositionTraits
from hindsight_client_api.models.document_response import DocumentResponse as DocumentResponse
@@ -109,6 +125,8 @@ from hindsight_client_api.models.include_options import IncludeOptions as Includ
from hindsight_client_api.models.list_documents_response import ListDocumentsResponse as ListDocumentsResponse
from hindsight_client_api.models.list_memory_units_response import ListMemoryUnitsResponse as ListMemoryUnitsResponse
from hindsight_client_api.models.memory_item import MemoryItem as MemoryItem
from hindsight_client_api.models.operation_response import OperationResponse as OperationResponse
from hindsight_client_api.models.operations_list_response import OperationsListResponse as OperationsListResponse
from hindsight_client_api.models.recall_request import RecallRequest as RecallRequest
from hindsight_client_api.models.recall_response import RecallResponse as RecallResponse
from hindsight_client_api.models.recall_result import RecallResult as RecallResult
@@ -1,6 +1,10 @@
# flake8: noqa
# import apis into api package
from hindsight_client_api.api.banks_api import BanksApi
from hindsight_client_api.api.documents_api import DocumentsApi
from hindsight_client_api.api.entities_api import EntitiesApi
from hindsight_client_api.api.memory_api import MemoryApi
from hindsight_client_api.api.monitoring_api import MonitoringApi
from hindsight_client_api.api.default_api import DefaultApi
from hindsight_client_api.api.operations_api import OperationsApi
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,921 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import warnings
from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
from typing import Any, Dict, List, Optional, Tuple, Union
from typing_extensions import Annotated
from pydantic import Field, StrictInt, StrictStr
from typing import Optional
from typing_extensions import Annotated
from hindsight_client_api.models.entity_detail_response import EntityDetailResponse
from hindsight_client_api.models.entity_list_response import EntityListResponse
from hindsight_client_api.api_client import ApiClient, RequestSerialized
from hindsight_client_api.api_response import ApiResponse
from hindsight_client_api.rest import RESTResponseType
class EntitiesApi:
"""NOTE: This class is auto generated by OpenAPI Generator
Ref: https://openapi-generator.tech
Do not edit the class manually.
"""
def __init__(self, api_client=None) -> None:
if api_client is None:
api_client = ApiClient.get_default()
self.api_client = api_client
@validate_call
async def get_entity(
self,
bank_id: StrictStr,
entity_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> EntityDetailResponse:
"""Get entity details
Get detailed information about an entity including observations (mental model).
:param bank_id: (required)
:type bank_id: str
:param entity_id: (required)
:type entity_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._get_entity_serialize(
bank_id=bank_id,
entity_id=entity_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityDetailResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
async def get_entity_with_http_info(
self,
bank_id: StrictStr,
entity_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[EntityDetailResponse]:
"""Get entity details
Get detailed information about an entity including observations (mental model).
:param bank_id: (required)
:type bank_id: str
:param entity_id: (required)
:type entity_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._get_entity_serialize(
bank_id=bank_id,
entity_id=entity_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityDetailResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
async def get_entity_without_preload_content(
self,
bank_id: StrictStr,
entity_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""Get entity details
Get detailed information about an entity including observations (mental model).
:param bank_id: (required)
:type bank_id: str
:param entity_id: (required)
:type entity_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._get_entity_serialize(
bank_id=bank_id,
entity_id=entity_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityDetailResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
return response_data.response
def _get_entity_serialize(
self,
bank_id,
entity_id,
authorization,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {
}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if bank_id is not None:
_path_params['bank_id'] = bank_id
if entity_id is not None:
_path_params['entity_id'] = entity_id
# process the query parameters
# process the header parameters
if authorization is not None:
_header_params['authorization'] = authorization
# process the form parameters
# process the body parameter
# set the HTTP header `Accept`
if 'Accept' not in _header_params:
_header_params['Accept'] = self.api_client.select_header_accept(
[
'application/json'
]
)
# authentication setting
_auth_settings: List[str] = [
]
return self.api_client.param_serialize(
method='GET',
resource_path='/v1/default/banks/{bank_id}/entities/{entity_id}',
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth
)
@validate_call
async def list_entities(
self,
bank_id: StrictStr,
limit: Annotated[Optional[StrictInt], Field(description="Maximum number of entities to return")] = None,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> EntityListResponse:
"""List entities
List all entities (people, organizations, etc.) known by the bank, ordered by mention count.
:param bank_id: (required)
:type bank_id: str
:param limit: Maximum number of entities to return
:type limit: int
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._list_entities_serialize(
bank_id=bank_id,
limit=limit,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityListResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
async def list_entities_with_http_info(
self,
bank_id: StrictStr,
limit: Annotated[Optional[StrictInt], Field(description="Maximum number of entities to return")] = None,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[EntityListResponse]:
"""List entities
List all entities (people, organizations, etc.) known by the bank, ordered by mention count.
:param bank_id: (required)
:type bank_id: str
:param limit: Maximum number of entities to return
:type limit: int
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._list_entities_serialize(
bank_id=bank_id,
limit=limit,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityListResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
async def list_entities_without_preload_content(
self,
bank_id: StrictStr,
limit: Annotated[Optional[StrictInt], Field(description="Maximum number of entities to return")] = None,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""List entities
List all entities (people, organizations, etc.) known by the bank, ordered by mention count.
:param bank_id: (required)
:type bank_id: str
:param limit: Maximum number of entities to return
:type limit: int
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._list_entities_serialize(
bank_id=bank_id,
limit=limit,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityListResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
return response_data.response
def _list_entities_serialize(
self,
bank_id,
limit,
authorization,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {
}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if bank_id is not None:
_path_params['bank_id'] = bank_id
# process the query parameters
if limit is not None:
_query_params.append(('limit', limit))
# process the header parameters
if authorization is not None:
_header_params['authorization'] = authorization
# process the form parameters
# process the body parameter
# set the HTTP header `Accept`
if 'Accept' not in _header_params:
_header_params['Accept'] = self.api_client.select_header_accept(
[
'application/json'
]
)
# authentication setting
_auth_settings: List[str] = [
]
return self.api_client.param_serialize(
method='GET',
resource_path='/v1/default/banks/{bank_id}/entities',
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth
)
@validate_call
async def regenerate_entity_observations(
self,
bank_id: StrictStr,
entity_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> EntityDetailResponse:
"""Regenerate entity observations
Regenerate observations for an entity based on all facts mentioning it.
:param bank_id: (required)
:type bank_id: str
:param entity_id: (required)
:type entity_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._regenerate_entity_observations_serialize(
bank_id=bank_id,
entity_id=entity_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityDetailResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
async def regenerate_entity_observations_with_http_info(
self,
bank_id: StrictStr,
entity_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[EntityDetailResponse]:
"""Regenerate entity observations
Regenerate observations for an entity based on all facts mentioning it.
:param bank_id: (required)
:type bank_id: str
:param entity_id: (required)
:type entity_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._regenerate_entity_observations_serialize(
bank_id=bank_id,
entity_id=entity_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityDetailResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
async def regenerate_entity_observations_without_preload_content(
self,
bank_id: StrictStr,
entity_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""Regenerate entity observations
Regenerate observations for an entity based on all facts mentioning it.
:param bank_id: (required)
:type bank_id: str
:param entity_id: (required)
:type entity_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._regenerate_entity_observations_serialize(
bank_id=bank_id,
entity_id=entity_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "EntityDetailResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
return response_data.response
def _regenerate_entity_observations_serialize(
self,
bank_id,
entity_id,
authorization,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {
}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if bank_id is not None:
_path_params['bank_id'] = bank_id
if entity_id is not None:
_path_params['entity_id'] = entity_id
# process the query parameters
# process the header parameters
if authorization is not None:
_header_params['authorization'] = authorization
# process the form parameters
# process the body parameter
# set the HTTP header `Accept`
if 'Accept' not in _header_params:
_header_params['Accept'] = self.api_client.select_header_accept(
[
'application/json'
]
)
# authentication setting
_auth_settings: List[str] = [
]
return self.api_client.param_serialize(
method='POST',
resource_path='/v1/default/banks/{bank_id}/entities/{entity_id}/regenerate',
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth
)
File diff suppressed because it is too large Load Diff
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -0,0 +1,610 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import warnings
from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
from typing import Any, Dict, List, Optional, Tuple, Union
from typing_extensions import Annotated
from pydantic import StrictStr
from typing import Optional
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse
from hindsight_client_api.models.operations_list_response import OperationsListResponse
from hindsight_client_api.api_client import ApiClient, RequestSerialized
from hindsight_client_api.api_response import ApiResponse
from hindsight_client_api.rest import RESTResponseType
class OperationsApi:
"""NOTE: This class is auto generated by OpenAPI Generator
Ref: https://openapi-generator.tech
Do not edit the class manually.
"""
def __init__(self, api_client=None) -> None:
if api_client is None:
api_client = ApiClient.get_default()
self.api_client = api_client
@validate_call
async def cancel_operation(
self,
bank_id: StrictStr,
operation_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> CancelOperationResponse:
"""Cancel a pending async operation
Cancel a pending async operation by removing it from the queue
:param bank_id: (required)
:type bank_id: str
:param operation_id: (required)
:type operation_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._cancel_operation_serialize(
bank_id=bank_id,
operation_id=operation_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "CancelOperationResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
async def cancel_operation_with_http_info(
self,
bank_id: StrictStr,
operation_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[CancelOperationResponse]:
"""Cancel a pending async operation
Cancel a pending async operation by removing it from the queue
:param bank_id: (required)
:type bank_id: str
:param operation_id: (required)
:type operation_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._cancel_operation_serialize(
bank_id=bank_id,
operation_id=operation_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "CancelOperationResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
async def cancel_operation_without_preload_content(
self,
bank_id: StrictStr,
operation_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""Cancel a pending async operation
Cancel a pending async operation by removing it from the queue
:param bank_id: (required)
:type bank_id: str
:param operation_id: (required)
:type operation_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._cancel_operation_serialize(
bank_id=bank_id,
operation_id=operation_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "CancelOperationResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
return response_data.response
def _cancel_operation_serialize(
self,
bank_id,
operation_id,
authorization,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {
}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if bank_id is not None:
_path_params['bank_id'] = bank_id
if operation_id is not None:
_path_params['operation_id'] = operation_id
# process the query parameters
# process the header parameters
if authorization is not None:
_header_params['authorization'] = authorization
# process the form parameters
# process the body parameter
# set the HTTP header `Accept`
if 'Accept' not in _header_params:
_header_params['Accept'] = self.api_client.select_header_accept(
[
'application/json'
]
)
# authentication setting
_auth_settings: List[str] = [
]
return self.api_client.param_serialize(
method='DELETE',
resource_path='/v1/default/banks/{bank_id}/operations/{operation_id}',
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth
)
@validate_call
async def list_operations(
self,
bank_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> OperationsListResponse:
"""List async operations
Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations
:param bank_id: (required)
:type bank_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._list_operations_serialize(
bank_id=bank_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "OperationsListResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
async def list_operations_with_http_info(
self,
bank_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[OperationsListResponse]:
"""List async operations
Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations
:param bank_id: (required)
:type bank_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._list_operations_serialize(
bank_id=bank_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "OperationsListResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
await response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
async def list_operations_without_preload_content(
self,
bank_id: StrictStr,
authorization: Optional[StrictStr] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""List async operations
Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations
:param bank_id: (required)
:type bank_id: str
:param authorization:
:type authorization: str
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._list_operations_serialize(
bank_id=bank_id,
authorization=authorization,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index
)
_response_types_map: Dict[str, Optional[str]] = {
'200': "OperationsListResponse",
'422': "HTTPValidationError",
}
response_data = await self.api_client.call_api(
*_param,
_request_timeout=_request_timeout
)
return response_data.response
def _list_operations_serialize(
self,
bank_id,
authorization,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {
}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if bank_id is not None:
_path_params['bank_id'] = bank_id
# process the query parameters
# process the header parameters
if authorization is not None:
_header_params['authorization'] = authorization
# process the form parameters
# process the body parameter
# set the HTTP header `Accept`
if 'Accept' not in _header_params:
_header_params['Accept'] = self.api_client.select_header_accept(
[
'application/json'
]
)
# authentication setting
_auth_settings: List[str] = [
]
return self.api_client.param_serialize(
method='GET',
resource_path='/v1/default/banks/{bank_id}/operations',
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth
)
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -500,7 +500,7 @@ class Configuration:
return "Python SDK Debug Report:\n"\
"OS: {env}\n"\
"Python Version: {pyversion}\n"\
"Version of the API: 1.0.0\n"\
"Version of the API: 0.1.0\n"\
"SDK Package Version: 0.0.7".\
format(env=sys.platform, pyversion=sys.version)
@@ -7,9 +7,9 @@ Bank list item with profile summary.
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**bank_id** | **str** | |
**name** | **str** | |
**name** | **str** | | [optional]
**disposition** | [**DispositionTraits**](DispositionTraits.md) | |
**background** | **str** | |
**background** | **str** | | [optional]
**created_at** | **str** | | [optional]
**updated_at** | **str** | | [optional]
@@ -0,0 +1,39 @@
# BankStatsResponse
Response model for bank statistics endpoint.
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**bank_id** | **str** | |
**total_nodes** | **int** | |
**total_links** | **int** | |
**total_documents** | **int** | |
**nodes_by_fact_type** | **Dict[str, int]** | |
**links_by_link_type** | **Dict[str, int]** | |
**links_by_fact_type** | **Dict[str, int]** | |
**links_breakdown** | **Dict[str, Dict[str, int]]** | |
**pending_operations** | **int** | |
**failed_operations** | **int** | |
## Example
```python
from hindsight_client_api.models.bank_stats_response import BankStatsResponse
# TODO update the JSON string below
json = "{}"
# create an instance of BankStatsResponse from a JSON string
bank_stats_response_instance = BankStatsResponse.from_json(json)
# print the JSON string representation of the object
print(BankStatsResponse.to_json())
# convert the object into a dict
bank_stats_response_dict = bank_stats_response_instance.to_dict()
# create an instance of BankStatsResponse from a dict
bank_stats_response_from_dict = BankStatsResponse.from_dict(bank_stats_response_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
@@ -0,0 +1,517 @@
# hindsight_client_api.BanksApi
All URIs are relative to *http://localhost*
Method | HTTP request | Description
------------- | ------------- | -------------
[**add_bank_background**](BanksApi.md#add_bank_background) | **POST** /v1/default/banks/{bank_id}/background | Add/merge memory bank background
[**create_or_update_bank**](BanksApi.md#create_or_update_bank) | **PUT** /v1/default/banks/{bank_id} | Create or update memory bank
[**delete_bank**](BanksApi.md#delete_bank) | **DELETE** /v1/default/banks/{bank_id} | Delete memory bank
[**get_agent_stats**](BanksApi.md#get_agent_stats) | **GET** /v1/default/banks/{bank_id}/stats | Get statistics for memory bank
[**get_bank_profile**](BanksApi.md#get_bank_profile) | **GET** /v1/default/banks/{bank_id}/profile | Get memory bank profile
[**list_banks**](BanksApi.md#list_banks) | **GET** /v1/default/banks | List all memory banks
[**update_bank_disposition**](BanksApi.md#update_bank_disposition) | **PUT** /v1/default/banks/{bank_id}/profile | Update memory bank disposition
# **add_bank_background**
> BackgroundResponse add_bank_background(bank_id, add_background_request, authorization=authorization)
Add/merge memory bank background
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.add_background_request import AddBackgroundRequest
from hindsight_client_api.models.background_response import BackgroundResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.BanksApi(api_client)
bank_id = 'bank_id_example' # str |
add_background_request = hindsight_client_api.AddBackgroundRequest() # AddBackgroundRequest |
authorization = 'authorization_example' # str | (optional)
try:
# Add/merge memory bank background
api_response = await api_instance.add_bank_background(bank_id, add_background_request, authorization=authorization)
print("The response of BanksApi->add_bank_background:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling BanksApi->add_bank_background: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**add_background_request** | [**AddBackgroundRequest**](AddBackgroundRequest.md)| |
**authorization** | **str**| | [optional]
### Return type
[**BackgroundResponse**](BackgroundResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **create_or_update_bank**
> BankProfileResponse create_or_update_bank(bank_id, create_bank_request, authorization=authorization)
Create or update memory bank
Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
from hindsight_client_api.models.create_bank_request import CreateBankRequest
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.BanksApi(api_client)
bank_id = 'bank_id_example' # str |
create_bank_request = hindsight_client_api.CreateBankRequest() # CreateBankRequest |
authorization = 'authorization_example' # str | (optional)
try:
# Create or update memory bank
api_response = await api_instance.create_or_update_bank(bank_id, create_bank_request, authorization=authorization)
print("The response of BanksApi->create_or_update_bank:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling BanksApi->create_or_update_bank: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**create_bank_request** | [**CreateBankRequest**](CreateBankRequest.md)| |
**authorization** | **str**| | [optional]
### Return type
[**BankProfileResponse**](BankProfileResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **delete_bank**
> DeleteResponse delete_bank(bank_id, authorization=authorization)
Delete memory bank
Delete an entire memory bank including all memories, entities, documents, and the bank profile itself. This is a destructive operation that cannot be undone.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.delete_response import DeleteResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.BanksApi(api_client)
bank_id = 'bank_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# Delete memory bank
api_response = await api_instance.delete_bank(bank_id, authorization=authorization)
print("The response of BanksApi->delete_bank:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling BanksApi->delete_bank: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**DeleteResponse**](DeleteResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **get_agent_stats**
> BankStatsResponse get_agent_stats(bank_id)
Get statistics for memory bank
Get statistics about nodes and links for a specific agent
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.bank_stats_response import BankStatsResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.BanksApi(api_client)
bank_id = 'bank_id_example' # str |
try:
# Get statistics for memory bank
api_response = await api_instance.get_agent_stats(bank_id)
print("The response of BanksApi->get_agent_stats:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling BanksApi->get_agent_stats: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
### Return type
[**BankStatsResponse**](BankStatsResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **get_bank_profile**
> BankProfileResponse get_bank_profile(bank_id, authorization=authorization)
Get memory bank profile
Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.BanksApi(api_client)
bank_id = 'bank_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# Get memory bank profile
api_response = await api_instance.get_bank_profile(bank_id, authorization=authorization)
print("The response of BanksApi->get_bank_profile:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling BanksApi->get_bank_profile: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**BankProfileResponse**](BankProfileResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **list_banks**
> BankListResponse list_banks(authorization=authorization)
List all memory banks
Get a list of all agents with their profiles
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.bank_list_response import BankListResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.BanksApi(api_client)
authorization = 'authorization_example' # str | (optional)
try:
# List all memory banks
api_response = await api_instance.list_banks(authorization=authorization)
print("The response of BanksApi->list_banks:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling BanksApi->list_banks: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**authorization** | **str**| | [optional]
### Return type
[**BankListResponse**](BankListResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **update_bank_disposition**
> BankProfileResponse update_bank_disposition(bank_id, update_disposition_request, authorization=authorization)
Update memory bank disposition
Update bank's disposition traits (skepticism, literalism, empathy)
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
from hindsight_client_api.models.update_disposition_request import UpdateDispositionRequest
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.BanksApi(api_client)
bank_id = 'bank_id_example' # str |
update_disposition_request = hindsight_client_api.UpdateDispositionRequest() # UpdateDispositionRequest |
authorization = 'authorization_example' # str | (optional)
try:
# Update memory bank disposition
api_response = await api_instance.update_bank_disposition(bank_id, update_disposition_request, authorization=authorization)
print("The response of BanksApi->update_bank_disposition:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling BanksApi->update_bank_disposition: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**update_disposition_request** | [**UpdateDispositionRequest**](UpdateDispositionRequest.md)| |
**authorization** | **str**| | [optional]
### Return type
[**BankProfileResponse**](BankProfileResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
@@ -0,0 +1,32 @@
# CancelOperationResponse
Response model for cancel operation endpoint.
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**success** | **bool** | |
**message** | **str** | |
**operation_id** | **str** | |
## Example
```python
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse
# TODO update the JSON string below
json = "{}"
# create an instance of CancelOperationResponse from a JSON string
cancel_operation_response_instance = CancelOperationResponse.from_json(json)
# print the JSON string representation of the object
print(CancelOperationResponse.to_json())
# convert the object into a dict
cancel_operation_response_dict = cancel_operation_response_instance.to_dict()
# create an instance of CancelOperationResponse from a dict
cancel_operation_response_from_dict = CancelOperationResponse.from_dict(cancel_operation_response_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,33 @@
# DeleteDocumentResponse
Response model for delete document endpoint.
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**success** | **bool** | |
**message** | **str** | |
**document_id** | **str** | |
**memory_units_deleted** | **int** | |
## Example
```python
from hindsight_client_api.models.delete_document_response import DeleteDocumentResponse
# TODO update the JSON string below
json = "{}"
# create an instance of DeleteDocumentResponse from a JSON string
delete_document_response_instance = DeleteDocumentResponse.from_json(json)
# print the JSON string representation of the object
print(DeleteDocumentResponse.to_json())
# convert the object into a dict
delete_document_response_dict = delete_document_response_instance.to_dict()
# create an instance of DeleteDocumentResponse from a dict
delete_document_response_from_dict = DeleteDocumentResponse.from_dict(delete_document_response_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
@@ -7,6 +7,8 @@ Response model for delete operations.
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**success** | **bool** | |
**message** | **str** | | [optional]
**deleted_count** | **int** | | [optional]
## Example
@@ -0,0 +1,313 @@
# hindsight_client_api.DocumentsApi
All URIs are relative to *http://localhost*
Method | HTTP request | Description
------------- | ------------- | -------------
[**delete_document**](DocumentsApi.md#delete_document) | **DELETE** /v1/default/banks/{bank_id}/documents/{document_id} | Delete a document
[**get_chunk**](DocumentsApi.md#get_chunk) | **GET** /v1/default/chunks/{chunk_id} | Get chunk details
[**get_document**](DocumentsApi.md#get_document) | **GET** /v1/default/banks/{bank_id}/documents/{document_id} | Get document details
[**list_documents**](DocumentsApi.md#list_documents) | **GET** /v1/default/banks/{bank_id}/documents | List documents
# **delete_document**
> DeleteDocumentResponse delete_document(bank_id, document_id, authorization=authorization)
Delete a document
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.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.delete_document_response import DeleteDocumentResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.DocumentsApi(api_client)
bank_id = 'bank_id_example' # str |
document_id = 'document_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# Delete a document
api_response = await api_instance.delete_document(bank_id, document_id, authorization=authorization)
print("The response of DocumentsApi->delete_document:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling DocumentsApi->delete_document: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**document_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**DeleteDocumentResponse**](DeleteDocumentResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **get_chunk**
> ChunkResponse get_chunk(chunk_id, authorization=authorization)
Get chunk details
Get a specific chunk by its ID
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.chunk_response import ChunkResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.DocumentsApi(api_client)
chunk_id = 'chunk_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# Get chunk details
api_response = await api_instance.get_chunk(chunk_id, authorization=authorization)
print("The response of DocumentsApi->get_chunk:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling DocumentsApi->get_chunk: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**chunk_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**ChunkResponse**](ChunkResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **get_document**
> DocumentResponse get_document(bank_id, document_id, authorization=authorization)
Get document details
Get a specific document including its original text
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.document_response import DocumentResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.DocumentsApi(api_client)
bank_id = 'bank_id_example' # str |
document_id = 'document_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# Get document details
api_response = await api_instance.get_document(bank_id, document_id, authorization=authorization)
print("The response of DocumentsApi->get_document:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling DocumentsApi->get_document: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**document_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**DocumentResponse**](DocumentResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **list_documents**
> ListDocumentsResponse list_documents(bank_id, q=q, limit=limit, offset=offset, authorization=authorization)
List documents
List documents with pagination and optional search. Documents are the source content from which memory units are extracted.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.list_documents_response import ListDocumentsResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.DocumentsApi(api_client)
bank_id = 'bank_id_example' # str |
q = 'q_example' # str | (optional)
limit = 100 # int | (optional) (default to 100)
offset = 0 # int | (optional) (default to 0)
authorization = 'authorization_example' # str | (optional)
try:
# List documents
api_response = await api_instance.list_documents(bank_id, q=q, limit=limit, offset=offset, authorization=authorization)
print("The response of DocumentsApi->list_documents:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling DocumentsApi->list_documents: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**q** | **str**| | [optional]
**limit** | **int**| | [optional] [default to 100]
**offset** | **int**| | [optional] [default to 0]
**authorization** | **str**| | [optional]
### Return type
[**ListDocumentsResponse**](ListDocumentsResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
@@ -0,0 +1,230 @@
# hindsight_client_api.EntitiesApi
All URIs are relative to *http://localhost*
Method | HTTP request | Description
------------- | ------------- | -------------
[**get_entity**](EntitiesApi.md#get_entity) | **GET** /v1/default/banks/{bank_id}/entities/{entity_id} | Get entity details
[**list_entities**](EntitiesApi.md#list_entities) | **GET** /v1/default/banks/{bank_id}/entities | List entities
[**regenerate_entity_observations**](EntitiesApi.md#regenerate_entity_observations) | **POST** /v1/default/banks/{bank_id}/entities/{entity_id}/regenerate | Regenerate entity observations
# **get_entity**
> EntityDetailResponse get_entity(bank_id, entity_id, authorization=authorization)
Get entity details
Get detailed information about an entity including observations (mental model).
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.entity_detail_response import EntityDetailResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.EntitiesApi(api_client)
bank_id = 'bank_id_example' # str |
entity_id = 'entity_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# Get entity details
api_response = await api_instance.get_entity(bank_id, entity_id, authorization=authorization)
print("The response of EntitiesApi->get_entity:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling EntitiesApi->get_entity: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**entity_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**EntityDetailResponse**](EntityDetailResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **list_entities**
> EntityListResponse list_entities(bank_id, limit=limit, authorization=authorization)
List entities
List all entities (people, organizations, etc.) known by the bank, ordered by mention count.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.entity_list_response import EntityListResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.EntitiesApi(api_client)
bank_id = 'bank_id_example' # str |
limit = 100 # int | Maximum number of entities to return (optional) (default to 100)
authorization = 'authorization_example' # str | (optional)
try:
# List entities
api_response = await api_instance.list_entities(bank_id, limit=limit, authorization=authorization)
print("The response of EntitiesApi->list_entities:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling EntitiesApi->list_entities: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**limit** | **int**| Maximum number of entities to return | [optional] [default to 100]
**authorization** | **str**| | [optional]
### Return type
[**EntityListResponse**](EntityListResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **regenerate_entity_observations**
> EntityDetailResponse regenerate_entity_observations(bank_id, entity_id, authorization=authorization)
Regenerate entity observations
Regenerate observations for an entity based on all facts mentioning it.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.entity_detail_response import EntityDetailResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.EntitiesApi(api_client)
bank_id = 'bank_id_example' # str |
entity_id = 'entity_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# Regenerate entity observations
api_response = await api_instance.regenerate_entity_observations(bank_id, entity_id, authorization=authorization)
print("The response of EntitiesApi->regenerate_entity_observations:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling EntitiesApi->regenerate_entity_observations: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**entity_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**EntityDetailResponse**](EntityDetailResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
@@ -0,0 +1,499 @@
# hindsight_client_api.MemoryApi
All URIs are relative to *http://localhost*
Method | HTTP request | Description
------------- | ------------- | -------------
[**clear_bank_memories**](MemoryApi.md#clear_bank_memories) | **DELETE** /v1/default/banks/{bank_id}/memories | Clear memory bank memories
[**get_graph**](MemoryApi.md#get_graph) | **GET** /v1/default/banks/{bank_id}/graph | Get memory graph data
[**list_memories**](MemoryApi.md#list_memories) | **GET** /v1/default/banks/{bank_id}/memories/list | List memory units
[**recall_memories**](MemoryApi.md#recall_memories) | **POST** /v1/default/banks/{bank_id}/memories/recall | Recall memory
[**reflect**](MemoryApi.md#reflect) | **POST** /v1/default/banks/{bank_id}/reflect | Reflect and generate answer
[**retain_memories**](MemoryApi.md#retain_memories) | **POST** /v1/default/banks/{bank_id}/memories | Retain memories
# **clear_bank_memories**
> DeleteResponse clear_bank_memories(bank_id, type=type, authorization=authorization)
Clear memory bank memories
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.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.delete_response import DeleteResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.MemoryApi(api_client)
bank_id = 'bank_id_example' # str |
type = 'type_example' # str | Optional fact type filter (world, experience, opinion) (optional)
authorization = 'authorization_example' # str | (optional)
try:
# Clear memory bank memories
api_response = await api_instance.clear_bank_memories(bank_id, type=type, authorization=authorization)
print("The response of MemoryApi->clear_bank_memories:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling MemoryApi->clear_bank_memories: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**type** | **str**| Optional fact type filter (world, experience, opinion) | [optional]
**authorization** | **str**| | [optional]
### Return type
[**DeleteResponse**](DeleteResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **get_graph**
> GraphDataResponse get_graph(bank_id, type=type, authorization=authorization)
Get memory graph data
Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.graph_data_response import GraphDataResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.MemoryApi(api_client)
bank_id = 'bank_id_example' # str |
type = 'type_example' # str | (optional)
authorization = 'authorization_example' # str | (optional)
try:
# Get memory graph data
api_response = await api_instance.get_graph(bank_id, type=type, authorization=authorization)
print("The response of MemoryApi->get_graph:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling MemoryApi->get_graph: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**type** | **str**| | [optional]
**authorization** | **str**| | [optional]
### Return type
[**GraphDataResponse**](GraphDataResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **list_memories**
> ListMemoryUnitsResponse list_memories(bank_id, type=type, q=q, limit=limit, offset=offset, authorization=authorization)
List memory units
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).
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.list_memory_units_response import ListMemoryUnitsResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.MemoryApi(api_client)
bank_id = 'bank_id_example' # str |
type = 'type_example' # str | (optional)
q = 'q_example' # str | (optional)
limit = 100 # int | (optional) (default to 100)
offset = 0 # int | (optional) (default to 0)
authorization = 'authorization_example' # str | (optional)
try:
# List memory units
api_response = await api_instance.list_memories(bank_id, type=type, q=q, limit=limit, offset=offset, authorization=authorization)
print("The response of MemoryApi->list_memories:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling MemoryApi->list_memories: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**type** | **str**| | [optional]
**q** | **str**| | [optional]
**limit** | **int**| | [optional] [default to 100]
**offset** | **int**| | [optional] [default to 0]
**authorization** | **str**| | [optional]
### Return type
[**ListMemoryUnitsResponse**](ListMemoryUnitsResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **recall_memories**
> RecallResponse recall_memories(bank_id, recall_request, authorization=authorization)
Recall memory
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.
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.recall_request import RecallRequest
from hindsight_client_api.models.recall_response import RecallResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.MemoryApi(api_client)
bank_id = 'bank_id_example' # str |
recall_request = hindsight_client_api.RecallRequest() # RecallRequest |
authorization = 'authorization_example' # str | (optional)
try:
# Recall memory
api_response = await api_instance.recall_memories(bank_id, recall_request, authorization=authorization)
print("The response of MemoryApi->recall_memories:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling MemoryApi->recall_memories: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**recall_request** | [**RecallRequest**](RecallRequest.md)| |
**authorization** | **str**| | [optional]
### Return type
[**RecallResponse**](RecallResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **reflect**
> ReflectResponse reflect(bank_id, reflect_request, authorization=authorization)
Reflect and generate answer
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
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.reflect_request import ReflectRequest
from hindsight_client_api.models.reflect_response import ReflectResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.MemoryApi(api_client)
bank_id = 'bank_id_example' # str |
reflect_request = hindsight_client_api.ReflectRequest() # ReflectRequest |
authorization = 'authorization_example' # str | (optional)
try:
# Reflect and generate answer
api_response = await api_instance.reflect(bank_id, reflect_request, authorization=authorization)
print("The response of MemoryApi->reflect:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling MemoryApi->reflect: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**reflect_request** | [**ReflectRequest**](ReflectRequest.md)| |
**authorization** | **str**| | [optional]
### Return type
[**ReflectResponse**](ReflectResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **retain_memories**
> RetainResponse retain_memories(bank_id, retain_request, authorization=authorization)
Retain memories
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)
- 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. Use the operations endpoint to monitor progress.
**When `async=false` (default):** Waits for processing to complete.
**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).
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.retain_request import RetainRequest
from hindsight_client_api.models.retain_response import RetainResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.MemoryApi(api_client)
bank_id = 'bank_id_example' # str |
retain_request = hindsight_client_api.RetainRequest() # RetainRequest |
authorization = 'authorization_example' # str | (optional)
try:
# Retain memories
api_response = await api_instance.retain_memories(bank_id, retain_request, authorization=authorization)
print("The response of MemoryApi->retain_memories:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling MemoryApi->retain_memories: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**retain_request** | [**RetainRequest**](RetainRequest.md)| |
**authorization** | **str**| | [optional]
### Return type
[**RetainResponse**](RetainResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
@@ -0,0 +1,36 @@
# OperationResponse
Response model for a single async operation.
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**id** | **str** | |
**task_type** | **str** | |
**items_count** | **int** | |
**document_id** | **str** | |
**created_at** | **str** | |
**status** | **str** | |
**error_message** | **str** | |
## Example
```python
from hindsight_client_api.models.operation_response import OperationResponse
# TODO update the JSON string below
json = "{}"
# create an instance of OperationResponse from a JSON string
operation_response_instance = OperationResponse.from_json(json)
# print the JSON string representation of the object
print(OperationResponse.to_json())
# convert the object into a dict
operation_response_dict = operation_response_instance.to_dict()
# create an instance of OperationResponse from a dict
operation_response_from_dict = OperationResponse.from_dict(operation_response_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
@@ -0,0 +1,154 @@
# hindsight_client_api.OperationsApi
All URIs are relative to *http://localhost*
Method | HTTP request | Description
------------- | ------------- | -------------
[**cancel_operation**](OperationsApi.md#cancel_operation) | **DELETE** /v1/default/banks/{bank_id}/operations/{operation_id} | Cancel a pending async operation
[**list_operations**](OperationsApi.md#list_operations) | **GET** /v1/default/banks/{bank_id}/operations | List async operations
# **cancel_operation**
> CancelOperationResponse cancel_operation(bank_id, operation_id, authorization=authorization)
Cancel a pending async operation
Cancel a pending async operation by removing it from the queue
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.OperationsApi(api_client)
bank_id = 'bank_id_example' # str |
operation_id = 'operation_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# Cancel a pending async operation
api_response = await api_instance.cancel_operation(bank_id, operation_id, authorization=authorization)
print("The response of OperationsApi->cancel_operation:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling OperationsApi->cancel_operation: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**operation_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**CancelOperationResponse**](CancelOperationResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **list_operations**
> OperationsListResponse list_operations(bank_id, authorization=authorization)
List async operations
Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations
### Example
```python
import hindsight_client_api
from hindsight_client_api.models.operations_list_response import OperationsListResponse
from hindsight_client_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = hindsight_client_api.Configuration(
host = "http://localhost"
)
# Enter a context with an instance of the API client
async with hindsight_client_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = hindsight_client_api.OperationsApi(api_client)
bank_id = 'bank_id_example' # str |
authorization = 'authorization_example' # str | (optional)
try:
# List async operations
api_response = await api_instance.list_operations(bank_id, authorization=authorization)
print("The response of OperationsApi->list_operations:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling OperationsApi->list_operations: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**bank_id** | **str**| |
**authorization** | **str**| | [optional]
### Return type
[**OperationsListResponse**](OperationsListResponse.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Successful Response | - |
**422** | Validation Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
@@ -0,0 +1,31 @@
# OperationsListResponse
Response model for list operations endpoint.
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**bank_id** | **str** | |
**operations** | [**List[OperationResponse]**](OperationResponse.md) | |
## Example
```python
from hindsight_client_api.models.operations_list_response import OperationsListResponse
# TODO update the JSON string below
json = "{}"
# create an instance of OperationsListResponse from a JSON string
operations_list_response_instance = OperationsListResponse.from_json(json)
# print the JSON string representation of the object
print(OperationsListResponse.to_json())
# convert the object into a dict
operations_list_response_dict = operations_list_response_instance.to_dict()
# create an instance of OperationsListResponse from a dict
operations_list_response_from_dict = OperationsListResponse.from_dict(operations_list_response_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -6,7 +6,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -18,11 +18,14 @@ from hindsight_client_api.models.background_response import BackgroundResponse
from hindsight_client_api.models.bank_list_item import BankListItem
from hindsight_client_api.models.bank_list_response import BankListResponse
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
from hindsight_client_api.models.bank_stats_response import BankStatsResponse
from hindsight_client_api.models.budget import Budget
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse
from hindsight_client_api.models.chunk_data import ChunkData
from hindsight_client_api.models.chunk_include_options import ChunkIncludeOptions
from hindsight_client_api.models.chunk_response import ChunkResponse
from hindsight_client_api.models.create_bank_request import CreateBankRequest
from hindsight_client_api.models.delete_document_response import DeleteDocumentResponse
from hindsight_client_api.models.delete_response import DeleteResponse
from hindsight_client_api.models.disposition_traits import DispositionTraits
from hindsight_client_api.models.document_response import DocumentResponse
@@ -38,6 +41,8 @@ from hindsight_client_api.models.include_options import IncludeOptions
from hindsight_client_api.models.list_documents_response import ListDocumentsResponse
from hindsight_client_api.models.list_memory_units_response import ListMemoryUnitsResponse
from hindsight_client_api.models.memory_item import MemoryItem
from hindsight_client_api.models.operation_response import OperationResponse
from hindsight_client_api.models.operations_list_response import OperationsListResponse
from hindsight_client_api.models.recall_request import RecallRequest
from hindsight_client_api.models.recall_response import RecallResponse
from hindsight_client_api.models.recall_result import RecallResult
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -28,9 +28,9 @@ class BankListItem(BaseModel):
Bank list item with profile summary.
""" # noqa: E501
bank_id: StrictStr
name: StrictStr
name: Optional[StrictStr] = None
disposition: DispositionTraits
background: StrictStr
background: Optional[StrictStr] = None
created_at: Optional[StrictStr] = None
updated_at: Optional[StrictStr] = None
__properties: ClassVar[List[str]] = ["bank_id", "name", "disposition", "background", "created_at", "updated_at"]
@@ -77,6 +77,16 @@ class BankListItem(BaseModel):
# override the default output from pydantic by calling `to_dict()` of disposition
if self.disposition:
_dict['disposition'] = self.disposition.to_dict()
# set to None if name (nullable) is None
# and model_fields_set contains the field
if self.name is None and "name" in self.model_fields_set:
_dict['name'] = None
# set to None if background (nullable) is None
# and model_fields_set contains the field
if self.background is None and "background" in self.model_fields_set:
_dict['background'] = None
# set to None if created_at (nullable) is None
# and model_fields_set contains the field
if self.created_at is None and "created_at" in self.model_fields_set:
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -0,0 +1,105 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List
from typing import Optional, Set
from typing_extensions import Self
class BankStatsResponse(BaseModel):
"""
Response model for bank statistics endpoint.
""" # noqa: E501
bank_id: StrictStr
total_nodes: StrictInt
total_links: StrictInt
total_documents: StrictInt
nodes_by_fact_type: Dict[str, StrictInt]
links_by_link_type: Dict[str, StrictInt]
links_by_fact_type: Dict[str, StrictInt]
links_breakdown: Dict[str, Dict[str, StrictInt]]
pending_operations: StrictInt
failed_operations: StrictInt
__properties: ClassVar[List[str]] = ["bank_id", "total_nodes", "total_links", "total_documents", "nodes_by_fact_type", "links_by_link_type", "links_by_fact_type", "links_breakdown", "pending_operations", "failed_operations"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of BankStatsResponse from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of BankStatsResponse from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"bank_id": obj.get("bank_id"),
"total_nodes": obj.get("total_nodes"),
"total_links": obj.get("total_links"),
"total_documents": obj.get("total_documents"),
"nodes_by_fact_type": obj.get("nodes_by_fact_type"),
"links_by_link_type": obj.get("links_by_link_type"),
"links_by_fact_type": obj.get("links_by_fact_type"),
"links_breakdown": obj.get("links_breakdown"),
"pending_operations": obj.get("pending_operations"),
"failed_operations": obj.get("failed_operations")
})
return _obj
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -0,0 +1,91 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr
from typing import Any, ClassVar, Dict, List
from typing import Optional, Set
from typing_extensions import Self
class CancelOperationResponse(BaseModel):
"""
Response model for cancel operation endpoint.
""" # noqa: E501
success: StrictBool
message: StrictStr
operation_id: StrictStr
__properties: ClassVar[List[str]] = ["success", "message", "operation_id"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of CancelOperationResponse from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of CancelOperationResponse from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"success": obj.get("success"),
"message": obj.get("message"),
"operation_id": obj.get("operation_id")
})
return _obj
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -0,0 +1,93 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List
from typing import Optional, Set
from typing_extensions import Self
class DeleteDocumentResponse(BaseModel):
"""
Response model for delete document endpoint.
""" # noqa: E501
success: StrictBool
message: StrictStr
document_id: StrictStr
memory_units_deleted: StrictInt
__properties: ClassVar[List[str]] = ["success", "message", "document_id", "memory_units_deleted"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of DeleteDocumentResponse from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of DeleteDocumentResponse from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"success": obj.get("success"),
"message": obj.get("message"),
"document_id": obj.get("document_id"),
"memory_units_deleted": obj.get("memory_units_deleted")
})
return _obj
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -17,8 +17,8 @@ import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, StrictBool
from typing import Any, ClassVar, Dict, List
from pydantic import BaseModel, ConfigDict, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing import Optional, Set
from typing_extensions import Self
@@ -27,7 +27,9 @@ class DeleteResponse(BaseModel):
Response model for delete operations.
""" # noqa: E501
success: StrictBool
__properties: ClassVar[List[str]] = ["success"]
message: Optional[StrictStr] = None
deleted_count: Optional[StrictInt] = None
__properties: ClassVar[List[str]] = ["success", "message", "deleted_count"]
model_config = ConfigDict(
populate_by_name=True,
@@ -68,6 +70,16 @@ class DeleteResponse(BaseModel):
exclude=excluded_fields,
exclude_none=True,
)
# set to None if message (nullable) is None
# and model_fields_set contains the field
if self.message is None and "message" in self.model_fields_set:
_dict['message'] = None
# set to None if deleted_count (nullable) is None
# and model_fields_set contains the field
if self.deleted_count is None and "deleted_count" in self.model_fields_set:
_dict['deleted_count'] = None
return _dict
@classmethod
@@ -80,7 +92,9 @@ class DeleteResponse(BaseModel):
return cls.model_validate(obj)
_obj = cls.model_validate({
"success": obj.get("success")
"success": obj.get("success"),
"message": obj.get("message"),
"deleted_count": obj.get("deleted_count")
})
return _obj
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -0,0 +1,109 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing import Optional, Set
from typing_extensions import Self
class OperationResponse(BaseModel):
"""
Response model for a single async operation.
""" # noqa: E501
id: StrictStr
task_type: StrictStr
items_count: StrictInt
document_id: Optional[StrictStr]
created_at: StrictStr
status: StrictStr
error_message: Optional[StrictStr]
__properties: ClassVar[List[str]] = ["id", "task_type", "items_count", "document_id", "created_at", "status", "error_message"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of OperationResponse from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# set to None if document_id (nullable) is None
# and model_fields_set contains the field
if self.document_id is None and "document_id" in self.model_fields_set:
_dict['document_id'] = None
# set to None if error_message (nullable) is None
# and model_fields_set contains the field
if self.error_message is None and "error_message" in self.model_fields_set:
_dict['error_message'] = None
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of OperationResponse from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"id": obj.get("id"),
"task_type": obj.get("task_type"),
"items_count": obj.get("items_count"),
"document_id": obj.get("document_id"),
"created_at": obj.get("created_at"),
"status": obj.get("status"),
"error_message": obj.get("error_message")
})
return _obj
@@ -0,0 +1,97 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, StrictStr
from typing import Any, ClassVar, Dict, List
from hindsight_client_api.models.operation_response import OperationResponse
from typing import Optional, Set
from typing_extensions import Self
class OperationsListResponse(BaseModel):
"""
Response model for list operations endpoint.
""" # noqa: E501
bank_id: StrictStr
operations: List[OperationResponse]
__properties: ClassVar[List[str]] = ["bank_id", "operations"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of OperationsListResponse from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of each item in operations (list)
_items = []
if self.operations:
for _item_operations in self.operations:
if _item_operations:
_items.append(_item_operations.to_dict())
_dict['operations'] = _items
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of OperationsListResponse from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"bank_id": obj.get("bank_id"),
"operations": [OperationResponse.from_dict(_item) for _item in obj["operations"]] if obj.get("operations") is not None else None
})
return _obj
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
The version of the OpenAPI document: 0.1.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -1,53 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.add_background_request import AddBackgroundRequest
class TestAddBackgroundRequest(unittest.TestCase):
"""AddBackgroundRequest unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> AddBackgroundRequest:
"""Test AddBackgroundRequest
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `AddBackgroundRequest`
"""
model = AddBackgroundRequest()
if include_optional:
return AddBackgroundRequest(
content = '',
update_disposition = True
)
else:
return AddBackgroundRequest(
content = '',
)
"""
def testAddBackgroundRequest(self):
"""Test AddBackgroundRequest"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()
@@ -1,53 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.background_response import BackgroundResponse
class TestBackgroundResponse(unittest.TestCase):
"""BackgroundResponse unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> BackgroundResponse:
"""Test BackgroundResponse
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `BackgroundResponse`
"""
model = BackgroundResponse()
if include_optional:
return BackgroundResponse(
background = '',
disposition = {empathy=3, literalism=3, skepticism=3}
)
else:
return BackgroundResponse(
background = '',
)
"""
def testBackgroundResponse(self):
"""Test BackgroundResponse"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()
@@ -1,60 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.bank_list_item import BankListItem
class TestBankListItem(unittest.TestCase):
"""BankListItem unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> BankListItem:
"""Test BankListItem
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `BankListItem`
"""
model = BankListItem()
if include_optional:
return BankListItem(
bank_id = '',
name = '',
disposition = {empathy=3, literalism=3, skepticism=3},
background = '',
created_at = '',
updated_at = ''
)
else:
return BankListItem(
bank_id = '',
name = '',
disposition = {empathy=3, literalism=3, skepticism=3},
background = '',
)
"""
def testBankListItem(self):
"""Test BankListItem"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()
@@ -1,68 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.bank_list_response import BankListResponse
class TestBankListResponse(unittest.TestCase):
"""BankListResponse unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> BankListResponse:
"""Test BankListResponse
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `BankListResponse`
"""
model = BankListResponse()
if include_optional:
return BankListResponse(
banks = [
hindsight_client_api.models.bank_list_item.BankListItem(
bank_id = '',
name = '',
disposition = {empathy=3, literalism=3, skepticism=3},
background = '',
created_at = '',
updated_at = '', )
]
)
else:
return BankListResponse(
banks = [
hindsight_client_api.models.bank_list_item.BankListItem(
bank_id = '',
name = '',
disposition = {empathy=3, literalism=3, skepticism=3},
background = '',
created_at = '',
updated_at = '', )
],
)
"""
def testBankListResponse(self):
"""Test BankListResponse"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()
@@ -1,58 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
class TestBankProfileResponse(unittest.TestCase):
"""BankProfileResponse unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> BankProfileResponse:
"""Test BankProfileResponse
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `BankProfileResponse`
"""
model = BankProfileResponse()
if include_optional:
return BankProfileResponse(
bank_id = '',
name = '',
disposition = {empathy=3, literalism=3, skepticism=3},
background = ''
)
else:
return BankProfileResponse(
bank_id = '',
name = '',
disposition = {empathy=3, literalism=3, skepticism=3},
background = '',
)
"""
def testBankProfileResponse(self):
"""Test BankProfileResponse"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()
@@ -1,33 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.budget import Budget
class TestBudget(unittest.TestCase):
"""Budget unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def testBudget(self):
"""Test Budget"""
# inst = Budget()
if __name__ == '__main__':
unittest.main()
@@ -1,57 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.chunk_data import ChunkData
class TestChunkData(unittest.TestCase):
"""ChunkData unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> ChunkData:
"""Test ChunkData
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `ChunkData`
"""
model = ChunkData()
if include_optional:
return ChunkData(
id = '',
text = '',
chunk_index = 56,
truncated = True
)
else:
return ChunkData(
id = '',
text = '',
chunk_index = 56,
)
"""
def testChunkData(self):
"""Test ChunkData"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()
@@ -1,51 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.chunk_include_options import ChunkIncludeOptions
class TestChunkIncludeOptions(unittest.TestCase):
"""ChunkIncludeOptions unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> ChunkIncludeOptions:
"""Test ChunkIncludeOptions
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `ChunkIncludeOptions`
"""
model = ChunkIncludeOptions()
if include_optional:
return ChunkIncludeOptions(
max_tokens = 56
)
else:
return ChunkIncludeOptions(
)
"""
def testChunkIncludeOptions(self):
"""Test ChunkIncludeOptions"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()
@@ -1,62 +0,0 @@
# coding: utf-8
"""
Hindsight HTTP API
HTTP API for Hindsight
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from hindsight_client_api.models.chunk_response import ChunkResponse
class TestChunkResponse(unittest.TestCase):
"""ChunkResponse unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> ChunkResponse:
"""Test ChunkResponse
include_optional is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `ChunkResponse`
"""
model = ChunkResponse()
if include_optional:
return ChunkResponse(
chunk_id = '',
document_id = '',
bank_id = '',
chunk_index = 56,
chunk_text = '',
created_at = ''
)
else:
return ChunkResponse(
chunk_id = '',
document_id = '',
bank_id = '',
chunk_index = 56,
chunk_text = '',
created_at = '',
)
"""
def testChunkResponse(self):
"""Test ChunkResponse"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()

Some files were not shown because too many files have changed in this diff Show More