Skip to main content

Sovant Python SDK

Sovant is a governed AI memory layer for AI agents and applications. Use it to store, search, and recall memories with profile awareness and enterprise-grade control over how memory is captured and used.

PyPI version License: MIT

Installation

pip install sovant

Quick Start

import os
from sovant import Sovant, MemoryCreate, SearchQuery

client = Sovant(api_key=os.environ["SOVANT_API_KEY"])

# Create a memory
mem = client.memory_create(MemoryCreate(
    data="User prefers dark mode",
    type="preference",
    tags=["ui", "settings"],
))

# Search memories
results = client.memory_search(SearchQuery(
    query="user preferences",
    limit=10,
))

# Update a memory
updated = client.memory_update(mem["id"], {
    "tags": ["ui", "settings", "theme"],
})

# Delete a memory
client.memory_delete(mem["id"])

Recall vs Search

Sovant provides two ways to query memories:

  • memory_recall() -- Hybrid recall, profile-aware. Use for conversational queries: "What do you know about me?", "What happened on Project X?". Uses Sovant's hybrid pipeline (profile fast-path + thread-scoped lexical + vector semantic search) and prioritizes profile facts (name/age/location) when available.

  • memory_search() -- Semantic search. Use for topic lookup and discovery. Pure vector similarity search without profile logic.

# Recall for conversational queries (returns { "results": [...], "total": N })
recall = client.memory_recall(
    query="what do you know about me?",
    limit=10,
)
for mem in recall.get("results", []):
    print(mem["content"])

# Search for topic discovery
topics = client.memory_search(SearchQuery(
    query="project updates",
    limit=5,
))

Working with Threads

Threads let you organize related memories into conversations or sessions. Each thread has a title and can contain multiple memories.

import os
from sovant import Sovant, MemoryCreate

client = Sovant(api_key=os.environ["SOVANT_API_KEY"])

# Create a new thread
thread = client.threads_create(
    title="Project Alpha Discussion",
    description="Q1 planning meeting notes",
    metadata={"project": "alpha", "quarter": "Q1"},
)

# Store memories in the thread
mem1 = client.memory_create(MemoryCreate(
    data="Decided to launch in March",
    type="journal",
    thread_id=thread["id"],
))

mem2 = client.memory_create(MemoryCreate(
    data="Budget approved: $50k",
    type="insight",
    thread_id=thread["id"],
))

# Recall memories from this specific thread
thread_recall = client.memory_recall(
    query="launch date",
    thread_id=thread["id"],
    limit=10,
)
# thread_recall["results"] contains the matching memories

# Get thread with all its memories
thread_with_memories = client.threads_get(
    thread["id"],
    include_memories=True,
    limit=50,
)

# List all threads
threads = client.threads_list(limit=20, offset=0)

# Update thread
updated = client.threads_update(
    thread["id"],
    title="Project Alpha - Q1 Launch",
    status="completed",
)

# Delete thread (keeps memories by default)
client.threads_delete(thread["id"])

# Delete thread AND all its memories
client.threads_delete(thread["id"], delete_memories=True)

Configuration

from sovant import Sovant

client = Sovant(
    api_key="sk_live_...",           # Required (or set SOVANT_API_KEY env var)
    base_url="https://sovant.ai",    # Optional, defaults to https://sovant.ai
    timeout=30.0,                    # Optional, request timeout in seconds (default: 30.0)
    max_retries=3,                   # Optional, max retry attempts (default: 3)
)

The SDK handles authentication via the Authorization: Bearer header.

API Reference

Memory Operations

Create Memory

from sovant import MemoryCreate

memory = client.memory_create(MemoryCreate(
    data="Customer contacted support about billing",
    type="observation",          # 'journal' | 'insight' | 'observation' | 'task' | 'preference'
    tags=["support", "billing"],
    metadata={"ticket_id": "12345"},
    thread_id="thread_abc123",   # Optional thread association
))

Get Memory by ID

memory = client.memory_get("mem_123abc")

Update Memory

updated = client.memory_update("mem_123abc", {
    "tags": ["support", "billing", "resolved"],
})

Delete Memory

client.memory_delete("mem_123abc")

Search Memories

from sovant import SearchQuery

# Semantic search
results = client.memory_search(SearchQuery(
    query="customer preferences about notifications",
    limit=10,
    type="preference",
))

# Filter-based search
results = client.memory_search(SearchQuery(
    tags=["settings", "notifications"],
    from_date="2024-01-01",
    to_date="2024-12-31",
    limit=20,
))

Recall Memories

Recall returns { "results": [...], "total": N, "query_type": "hybrid" }.

# Hybrid recall with profile awareness
recall = client.memory_recall(
    query="what do you know about me?",
    limit=10,
)
for mem in recall.get("results", []):
    print(mem["content"], mem.get("relevance"))

# Thread-scoped recall
recall = client.memory_recall(
    query="launch timeline",
    thread_id="thread_abc123",
    limit=5,
)

Batch Create

results = client.memory_create_batch([
    {"data": "First memory", "type": "journal"},
    {"data": "Second memory", "type": "insight", "tags": ["important"]},
])

List Memories

Fetch memories with filtering and pagination. Use memory_list() to retrieve recent memories or filter by criteria — it's more efficient than memory_search() when you don't need vector similarity.

# List recent memories
result = client.memory_list(limit=20, offset=0)
for mem in result["memories"]:
    print(mem["content"])

# Filter by thread
thread_mems = client.memory_list(thread_id="thread-uuid", limit=50)

# Filter by type and tags
prefs = client.memory_list(
    type="preference",
    tags=["settings"],
    sort_by="updated_at",
    sort_order="desc",
)

# Pinned memories only
pinned = client.memory_list(is_pinned=True)

Available parameters:

  • limit — max results (default: 20, max: 100)
  • offset — pagination offset
  • thread_id — filter by thread
  • type — filter by memory type
  • tags — filter by tags (must have all)
  • is_pinned — filter by pinned status
  • is_archived — filter by archived status
  • sort_by — created_at, updated_at, importance, or type
  • sort_order — asc or desc

Thread Management

# Create a thread
thread = client.threads_create(
    title="Customer Support Session",
    metadata={"user_id": "user_123"},
)

# List threads
threads = client.threads_list(limit=10, offset=0)

# Get thread by ID (with memories)
thread = client.threads_get("thread_abc123", include_memories=True)

# Update thread
updated = client.threads_update(
    "thread_abc123",
    title="Resolved: Billing Issue",
    status="completed",
)

# Delete thread
client.threads_delete("thread_abc123")

Memory Types

  • journal -- Chronological entries and logs
  • insight -- Derived patterns and conclusions
  • observation -- Factual, observed information
  • task -- Action items and todos
  • preference -- User preferences and settings

Error Handling

The SDK raises SovantError for all API errors:

from sovant import Sovant, SovantError

try:
    memory = client.memory_get("invalid_id")
except SovantError as e:
    print(f"Error: {e}")
    print(f"Code: {e.code}")      # e.g. "NOT_FOUND", "HTTP_401"
    print(f"Status: {e.status}")  # e.g. 404, 401

    if e.status == 404:
        print("Memory not found")
    elif e.status == 401:
        print("Invalid API key")
    elif e.status == 429:
        print("Rate limited -- SDK retries automatically")

The SDK automatically retries on rate limit (429) and server errors (5xx) with exponential backoff.

Examples

Customer Support Integration

from sovant import MemoryCreate

# Track customer interaction
interaction = client.memory_create(MemoryCreate(
    data="Customer reported slow dashboard loading",
    type="observation",
    thread_id=f"ticket_{ticket_id}",
    tags=["support", "performance", "dashboard"],
    metadata={
        "ticket_id": ticket_id,
        "priority": "high",
    },
))

# Record resolution
resolution = client.memory_create(MemoryCreate(
    data="Resolved by clearing cache and upgrading plan",
    type="insight",
    thread_id=f"ticket_{ticket_id}",
    tags=["support", "resolved"],
))

User Preference Tracking

from sovant import MemoryCreate, SearchQuery

# Store preference
client.memory_create(MemoryCreate(
    data="User prefers email notifications over SMS",
    type="preference",
    tags=["notifications", "email"],
))

# Query preferences
preferences = client.memory_search(SearchQuery(
    query="notification preferences",
    type="preference",
))

Rate Limiting

The API enforces 60 requests per minute. The SDK automatically retries rate-limited requests with exponential backoff. Rate limit headers are included in responses:

  • X-RateLimit-Limit -- Request limit per window
  • X-RateLimit-Remaining -- Remaining requests
  • X-RateLimit-Reset -- Reset timestamp

Support

License & Use

  • This SDK is MIT-licensed for integration convenience.
  • The Sovant API and platform are proprietary to Sovant Technologies Sdn. Bhd.
  • You may use this SDK to integrate with Sovant's hosted API.
  • Hosting/redistributing the Sovant backend or any proprietary components is not permitted.

License

MIT -- See LICENSE file for details.

Metadata

Release files for sovant 1.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sovant 1.3.3
File Size Uploaded Provenance
sovant-1.3.3.tar.gz 18.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sovant 1.3.3
File Interpreter ABI Platform
sovant-1.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 36.0 kB

Release files / sovant-1.3.3.tar.gz

Download URL sovant-1.3.3.tar.gz
Size 18.3 kB
Tags Source
SHA-256 checksum
How to use checksums
88a8945ab3a9327b1a8b4eb3af875370b38bfb00aae547790b086f876b3ad810
BLAKE2b-256 checksum
How to use checksums
b8c301d00e9f8c6cb194cdd8c5e0b6ce38029a87e2cd4a835d9ef66ed5507df2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Release files / sovant-1.3.3-py3-none-any.whl

Download URL sovant-1.3.3-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a0bf5cb094a55fccd99143c70a700412936e67c38759250376e2949b6a272692
BLAKE2b-256 checksum
How to use checksums
a7c18a14e12e0a47429c9f2c4b80af669c2f11cac1499b7d4da24ba5449add77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Security for sovant 1.3.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page