Skip to main content

Official Python SDK for the Yod personal memory assistant API

Project description

Yod Python SDK

Website PyPI License: Apache 2.0

Official Python client for the Yod personal memory assistant API.

Installation

pip install yod

Quick Start

from yod import YodClient

# Initialize with your API key (get one from the dashboard)
client = YodClient(api_key="sk-yod-...")

# Ingest information
client.ingest_chat("My favorite color is blue and I love hiking on weekends")

# Query your memories
response = client.chat("What are my hobbies?")
print(response.answer)
# Output: "You love hiking on weekends."

print(response.citations)
# Output: [Citation(source_id='...', quote='I love hiking on weekends')]

Authentication

The SDK supports multiple authentication methods:

API Key (Recommended)

client = YodClient(api_key="sk-yod-...")

JWT Bearer Token

client = YodClient(bearer_token="eyJ...")

Development Mode (X-User-Id header)

client = YodClient(
    base_url="http://localhost:8000",
    user_id="test-user-123"
)

API Reference

Client Initialization

from yod import YodClient, AsyncYodClient

# Sync client
client = YodClient(
    api_key="sk-yod-...",           # API key
    base_url="https://api.yod.agames.ai",  # API base URL (optional)
    timeout=30.0,                      # Request timeout in seconds
    max_retries=3,                     # Max retry attempts
)

# Async client
async_client = AsyncYodClient(api_key="sk-yod-...")

Ingest Text

Store text and extract memories:

response = client.ingest_chat(
    text="I started learning piano last month. My teacher is Sarah.",
    source_id="conversation-123",  # Optional: track the source
    timestamp="2024-01-15T10:30:00Z",  # Optional: set timestamp
    session_id="sess_abc123",  # Optional: session scoping
)

print(response.source_id)  # Source identifier
print(response.chunks)     # Number of chunks processed
print(response.entities)   # Extracted entities (people, places, etc.)
print(response.memories)   # Extracted memories

Chat / Query

Query your memories with natural language:

response = client.chat(
    question="Who is my piano teacher?",
    language="en",  # Optional: response language
    as_of="2024-06-01T00:00:00Z",  # Optional: temporal query
    session_id="sess_abc123",  # Optional: session scoping
)

print(response.answer)          # "Your piano teacher is Sarah."
print(response.citations)       # Source citations with quotes
print(response.used_memory_ids) # Memory IDs used to generate answer

List Memories

memories = client.list_memories(
    limit=50,              # Max memories to return
    kind="preference",     # Filter by type (preference, event, fact, etc.)
    search="piano",        # Search term
    include_inactive=False # Include superseded memories
)

for memory in memories.memories:
    print(f"[{memory.kind}] {memory.summary} (confidence: {memory.confidence})")

Get Single Memory

memory = client.get_memory("mem_abc123")
print(memory.summary)
print(memory.entity_ids)  # Related entities
print(memory.support)     # Supporting sources with quotes

Update Memory

client.update_memory(
    "mem_abc123",
    summary="Updated summary text",
    confidence=0.95,
    kind="fact"
)

Delete Memory

client.delete_memory("mem_abc123")

Memory History

Get temporal versions of a memory:

history = client.get_memory_history("mem_abc123")
for version in history.memories:
    print(f"{version.updated_at}: {version.summary}")

Session Management

Sessions allow you to scope memories to specific contexts (e.g., per-agent or per-conversation):

# Create a new session
session = client.create_session(
    agent_id="support-bot",  # Optional: associate with an agent
    metadata={"context": "customer-support"}  # Optional metadata
)
print(session.session_id)  # "sess_abc123"

# List all sessions
sessions = client.list_sessions()
for s in sessions.sessions:
    print(f"{s.session_id}: agent={s.agent_id}, created={s.created_at}")

# Use session_id in ingest and chat
client.ingest_chat(
    "User prefers formal language",
    session_id=session.session_id
)
response = client.chat(
    "What tone should I use?",
    session_id=session.session_id
)

# Delete a session (also deletes session-scoped memories)
client.delete_session(session.session_id)

Memory Linking (A-MEM)

When MEMORY_LINKING_ENABLED=true on the server, the system automatically discovers semantic relationships between memories using the A-MEM algorithm.

Accessing links in ingest responses:

response = client.ingest_chat("I love eating steak for dinner")

for memory in response.memories:
    print(f"Memory: {memory.summary}")
    for link in memory.links:
        print(f"  -> {link.type} {link.target} (confidence: {link.confidence})")
        # Example output:
        # -> contradicts clm_vegetarian (confidence: 1.0)

Link types:

  • supports - First claim provides evidence for second
  • contradicts - Claims cannot both be true simultaneously
  • refines - First is more specific version of second
  • elaborates - First adds detail/context to second
  • supersedes - First replaces second (temporal update)

Accessing contradictions in chat responses:

response = client.chat("What are my dietary preferences?")

print(response.answer)
# "Your memories show some conflicting information..."

for contradiction in response.contradictions:
    print(f"Conflict: {contradiction.claim_a} vs {contradiction.claim_b}")
    if contradiction.reason:
        print(f"  Reason: {contradiction.reason}")

Health Checks

# Basic health check
health = client.health()
print(health.status)  # "ok"

# Detailed readiness check
ready = client.ready()
print(ready.status)      # "ok" or "degraded"
print(ready.neo4j.ok)    # Neo4j status
print(ready.qdrant.ok)   # Qdrant status

Async Usage

All methods are available as async:

from yod import AsyncYodClient

async def main():
    async with AsyncYodClient(api_key="sk-yod-...") as client:
        # Create a session for this conversation
        session = await client.create_session(agent_id="reading-assistant")

        # Ingest with session scoping
        await client.ingest_chat(
            "I enjoy reading science fiction",
            session_id=session.session_id
        )

        # Query within session context
        response = await client.chat(
            "What kind of books do I like?",
            session_id=session.session_id
        )
        print(response.answer)

        # List memories
        memories = await client.list_memories()
        for m in memories.memories:
            print(m.summary)

import asyncio
asyncio.run(main())

Error Handling

The SDK provides specific exception types:

from yod import (
    YodError,           # Base exception
    YodAPIError,        # API returned an error
    AuthenticationError,  # 401 - Invalid credentials
    AuthorizationError,   # 403 - Insufficient permissions
    NotFoundError,        # 404 - Resource not found
    ValidationError,      # 422 - Invalid request
    RateLimitError,       # 429 - Rate limit exceeded
    ServerError,          # 5xx - Server error
    YodConnectionError, # Network error
    YodTimeoutError,    # Request timeout
)

try:
    response = client.chat("What's my name?")
except AuthenticationError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except YodAPIError as e:
    print(f"API error {e.status_code}: {e}")
except YodError as e:
    print(f"SDK error: {e}")

Models

Response Models

from yod import (
    ChatResponse,
    Citation,
    Contradiction,    # A-MEM: detected conflicts between memories
    IngestResponse,
    MemoryItem,
    MemoryLink,       # A-MEM: semantic link between memories
    MemoryListResponse,
    MemorySupport,
    HealthResponse,
    ReadyResponse,
)

Enums

from yod import MemoryKind, MemoryStatus, EntityType

# Memory kinds
MemoryKind.PREFERENCE   # User preferences
MemoryKind.FACT         # General facts
MemoryKind.EVENT        # Events and activities
MemoryKind.RELATIONSHIP # Relationships between entities
MemoryKind.GOAL         # Goals and aspirations
MemoryKind.OPINION      # Opinions and beliefs

Configuration

Custom Base URL

# Self-hosted instance
client = YodClient(
    api_key="sk-yod-...",
    base_url="https://yod.yourcompany.com"
)

# Local development
client = YodClient(
    base_url="http://localhost:8000",
    user_id="dev-user"
)

Timeouts

client = YodClient(
    api_key="sk-yod-...",
    timeout=60.0,        # Request timeout
    connect_timeout=10.0 # Connection timeout
)

Retry Configuration

The SDK automatically retries failed requests with exponential backoff:

client = YodClient(
    api_key="sk-yod-...",
    max_retries=5  # Default: 3
)

Retries are performed for:

  • 429 Too Many Requests (respects Retry-After header)
  • 500, 502, 503, 504 Server Errors
  • Connection errors

Development

Install Development Dependencies

pip install -e ".[dev]"

Run Tests

pytest

Type Checking

mypy src/yod

License

Apache 2.0 License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yod-0.2.4.tar.gz (19.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

yod-0.2.4-py3-none-any.whl (29.0 kB view details)

Uploaded Python 3

File details

Details for the file yod-0.2.4.tar.gz.

File metadata

  • Download URL: yod-0.2.4.tar.gz
  • Upload date:
  • Size: 19.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for yod-0.2.4.tar.gz
Algorithm Hash digest
SHA256 5893553628b2eeff9e7cb68fb721480707d3ce345127349b688b7bccdfd7b950
MD5 407961a7d9c40fdb41a85d637540e2cc
BLAKE2b-256 f6975ce62b85331ca466d11b7589f3889ab3ce0fdaafab4a71e337bc4ab9255e

See more details on using hashes here.

File details

Details for the file yod-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: yod-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 29.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for yod-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 31f6d54d245328115fb688eeff63ac7fce207aa0c78620924c497ff21b651548
MD5 01f5d16a43e795b95a35216cebddd461
BLAKE2b-256 89e740dbdc16d974783f3af801bc0614bef308a3eb294955a2c7ac087fb650ec

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page