Skip to main content

Python client for SmartMemory Service API

Project description

SmartMemory Python Client

Official Python client for the SmartMemory Service API.

PyPI version Python 3.11+ License: MIT

Features

  • Type-safe API with Pydantic models
  • Automatic JWT authentication with token handling
  • Full API coverage (CRUD, ingestion, search, links, temporal, etc.)
  • Comprehensive error handling
  • Clean, manually-maintained code (no code generation complexity)
  • Automatic scoping - tenant/workspace/user derived from JWT token

Installation

pip install smartmemory-client

Development Installation

git clone https://github.com/smartmemory/smart-memory-client.git
cd smart-memory-client
pip install -e ".[dev]"

Quick Start

from smartmemory_client import SmartMemoryClient

# Initialize client with authentication
client = SmartMemoryClient(
    base_url="http://localhost:9001",
    api_key="your_jwt_token"  # Or set SMARTMEMORY_API_KEY env var
)

# Add a memory
item_id = client.add("This is a test memory")
print(f"Added memory: {item_id}")

# Search memories
results = client.search("test", top_k=5)
for memory in results:
    print(f"{memory.item_id}: {memory.content}")

# Ingest with full pipeline
result = client.ingest(
    content="Complex content to process",
    extractor_name="llm",
    context={"source": "user", "timestamp": "2025-11-10"}
)
print(f"Ingested: {result['item_id']}")

Authentication

The client requires a JWT token for authentication. You can provide it in two ways:

1. Pass as parameter

client = SmartMemoryClient(
    base_url="http://localhost:9001",
    api_key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
)

2. Set environment variable

export SMARTMEMORY_API_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
import os
client = SmartMemoryClient(
    base_url="http://localhost:9001",
    api_key=os.getenv("SMARTMEMORY_API_KEY")
)

Getting a JWT Token

SmartMemory uses Clerk for authentication (PLAT-SSO-IDP-1). /auth/signup and /auth/login have been removed. Tokens are obtained via the Clerk-hosted login flow or, for programmatic/service access, via the Clerk session exchange endpoint:

# Exchange a Clerk session token for a SmartMemory JWT + cookies
curl -X POST "http://localhost:9001/auth/clerk/session" \
  -H "Authorization: Bearer <clerk_session_token>"
# Response sets sm_access_token cookie and returns {"access_token": "eyJ..."}

# Verify / inspect the token
curl "http://localhost:9001/auth/me" \
  -H "Authorization: Bearer <sm_access_token>"
# Response: {"id": "...", "email": "...", "default_team_id": "..."}

For local E2E / integration tests, set SM_E2E_TOKEN and SM_E2E_TEAM_ID env vars (captured from a real Clerk login or the sm_access_token cookie) and the test fixtures will inject them automatically.

API Reference

Memory Operations

Add Memory

# Simple add
item_id = client.add("Remember this")

# With metadata
item_id = client.add(
    "Important fact",
    metadata={"source": "user", "priority": "high"},
    use_pipeline=True  # Run full extraction pipeline
)

# Fast add (no pipeline)
item_id = client.add("Quick note", use_pipeline=False)

Search Memories

# Simple search
results = client.search("AI concepts", top_k=10)

# Search with SSG for better multi-hop reasoning
results = client.search("AI concepts", top_k=10, use_ssg=True)

# Search specific memory type
results = client.search("conversation", memory_type="episodic")

# Process results
for memory in results:
    print(f"{memory.item_id}: {memory.content}")
    print(f"Score: {memory.score}")
    print(f"Metadata: {memory.metadata}")

Advanced Search (SSG)

# Best for general queries (query_traversal algorithm)
results = client.search_advanced(
    query="What are neural networks?",
    algorithm="query_traversal",
    max_results=15
)

# Best for high precision (triangulation_fulldim algorithm)
results = client.search_advanced(
    query="Specific technical fact",
    algorithm="triangulation_fulldim",
    max_results=10
)

# Process results
for memory in results:
    print(f"{memory.item_id}: {memory.content}")

SSG Benefits:

  • ✅ Superior multi-hop reasoning across related memories
  • ✅ Better contextual retrieval (0.91 precision/recall vs 0.88)
  • ✅ Higher faithfulness (facts vs opinions)
  • ✅ Improved conversation and knowledge graph traversal

Based on: Eric Lester. (2025). Novel Semantic Similarity Graph Traversal Algorithms for Semantic Retrieval Augmented Generation Systems.

Get Memory

memory = client.get("item_123")
if memory:
    print(f"Content: {memory.content}")
    print(f"Type: {memory.memory_type}")
    print(f"Metadata: {memory.metadata}")

Update Memory

# Update content
client.update("item_123", content="Updated content")

# Update metadata
client.update("item_123", metadata={"updated": True})

# Update both
client.update("item_123", content="New content", metadata={"version": 2})

Delete Memory

if client.delete("item_123"):
    print("Memory deleted")

Ingestion

# Ingest with full pipeline
# Note: user_id, tenant_id, workspace_id are automatically derived from JWT token
result = client.ingest(
    content="User: Hello\nAssistant: Hi there!",
    extractor_name="llm",
    context={
        "conversation_id": "123",
        "timestamp": "2025-11-10",
        "source": "chat_interface"
    }
)

print(f"Ingested: {result['item_id']}")
print(f"Queued for processing: {result['queued']}")

Links and Relationships

# Create link between memories
client.link("concept_1", "concept_2", link_type="RELATED")
client.link("cause_id", "effect_id", link_type="CAUSES")

# Get neighbors
neighbors = client.get_neighbors("item_123")
for neighbor in neighbors:
    print(f"{neighbor['id']}: {neighbor['relation']}")

Code Search

# Semantic search over indexed code entities
results = client.code_search("authentication functions", semantic=True)
for entity in results:
    print(f"{entity['name']} ({entity['entity_type']}) — {entity['file_path']}:{entity['line_number']}")
    print(f"  Score: {entity['score']}")

# Filter by entity type and repo
results = client.code_search(
    "payment handler",
    semantic=True,
    entity_type="function",
    repo="my-service"
)

# Non-semantic (Cypher substring match, default)
results = client.code_search("authenticate")

Enrichment

# Enrich a memory
result = client.enrich("item_123", routines=["sentiment", "keywords"])
print(f"Enrichment result: {result}")

Personalization

# Update user preferences
result = client.personalize(
    traits={"learning_style": "visual"},
    preferences={"language": "en", "complexity": "advanced"}
)

Feedback

# Provide feedback
result = client.provide_feedback(
    feedback={
        "item_id": "123",
        "rating": 5,
        "comment": "Very helpful"
    },
    memory_type="semantic"
)

Reasoning Traces (System 2 Memory)

# Extract reasoning from content
result = client.extract_reasoning('''
    Thought: I need to analyze this bug.
    Action: Let me search for the function.
    Observation: Found the issue in line 42.
    Conclusion: The fix is to add a null check.
''')
if result['has_reasoning']:
    print(f"Found {result['step_count']} reasoning steps")

# Store a reasoning trace
result = client.store_reasoning_trace(
    trace={
        "trace_id": "trace_123",
        "steps": [
            {"type": "thought", "content": "Analyzing the problem"},
            {"type": "conclusion", "content": "Found the solution"},
        ],
        "task_context": {"goal": "Fix bug", "domain": "python"},
    },
    artifact_ids=["code_fix_456"]  # Link to resulting artifacts
)

# Query reasoning traces ("why" queries)
result = client.query_reasoning("why did I use async/await?")
for trace in result['traces']:
    print(f"Trace {trace['trace_id']}: {trace['content'][:100]}...")

# Get specific reasoning trace
trace = client.get_reasoning_trace("trace_123")

Synthesis Evolution (Opinions & Observations)

# Form opinions from episodic patterns
result = client.synthesize_opinions()
print(f"Status: {result['status']}")

# Create entity summaries from scattered facts
result = client.synthesize_observations()
print(f"Status: {result['status']}")

# Update opinion confidence based on new evidence
result = client.reinforce_opinions()
print(f"Status: {result['status']}")

Health Check

# Check service health
health = client.health_check()
print(health)  # {'status': 'healthy'}

Summary Statistics

# Get memory statistics
summary = client.get_summary()
print(f"Total memories: {summary.get('total_count', 0)}")

Usage in Projects

Maya Integration

# maya/requirements.txt
smartmemory-client>=1.0.0

# maya/maya/api/memory_manager.py
import os
from smartmemory_client import SmartMemoryClient

class MemoryManager:
    def __init__(self, smartmemory_url):
        self.client = SmartMemoryClient(
            base_url=smartmemory_url,
            api_key=os.getenv("SMARTMEMORY_API_KEY")
        )
    
    def ingest_conversation(self, content, metadata):
        # user_id, tenant_id, workspace_id automatically from JWT token
        return self.client.ingest(
            content=content,
            extractor_name="llm",
            context=metadata
        )
    
    def retrieve_relevant_memories(self, query):
        return self.client.search(query=query, top_k=5)

Studio Integration

import os
from smartmemory_client import SmartMemoryClient

client = SmartMemoryClient(
    base_url=os.getenv("SMARTMEMORY_URL"),
    api_key=os.getenv("SMARTMEMORY_API_KEY")
)

# Use client for memory operations
memories = client.search("project requirements", top_k=10)

Error Handling

from smartmemory_client import SmartMemoryClient, SmartMemoryClientError

client = SmartMemoryClient("http://localhost:9001", api_key="token")

try:
    item_id = client.add("Test memory")
except SmartMemoryClientError as e:
    print(f"Error: {e}")

Configuration

Environment Variables

  • SMARTMEMORY_API_KEY - JWT token for authentication
  • SMARTMEMORY_URL - Base URL of the SmartMemory service (optional)

Client Options

client = SmartMemoryClient(
    base_url="http://localhost:9001",
    api_key="your_jwt_token",
    timeout=30.0,           # Request timeout in seconds
    verify_ssl=True         # Verify SSL certificates
)

Development

Setup

git clone https://github.com/smartmemory/smart-memory-client.git
cd smart-memory-client
pip install -e ".[dev]"

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=smartmemory_client --cov-report=html

# Run specific test
pytest tests/test_client.py::test_add_memory

Code Quality

# Format code
black smartmemory_client tests

# Sort imports
isort smartmemory_client tests

# Lint
ruff check smartmemory_client tests

# Type check
mypy smartmemory_client

Versioning

This package follows Semantic Versioning:

  • Major (1.0.0 → 2.0.0): Breaking changes
  • Minor (1.0.0 → 1.1.0): New features, backward compatible
  • Patch (1.0.0 → 1.0.1): Bug fixes

The client version is synced with the SmartMemory Service version.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Reporting Issues

Please report issues on GitHub Issues.

License

MIT License - see LICENSE file for details.

Links

Changelog

See CHANGELOG.md for version history.


Made with ❤️ by the SmartMemory Team

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

smartmemory_client-0.5.1.tar.gz (56.9 kB view details)

Uploaded Source

Built Distribution

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

smartmemory_client-0.5.1-py3-none-any.whl (35.1 kB view details)

Uploaded Python 3

File details

Details for the file smartmemory_client-0.5.1.tar.gz.

File metadata

  • Download URL: smartmemory_client-0.5.1.tar.gz
  • Upload date:
  • Size: 56.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for smartmemory_client-0.5.1.tar.gz
Algorithm Hash digest
SHA256 5461e5b28c6618ce101cf91ad24a8f214cb0dd950412567b12346a5fd3e87da2
MD5 7bbfe2877c7e681dc155bdc3d0794847
BLAKE2b-256 659689635ab8a0b3279260b4c01473bf1d89170243af7eb4090b70aea1dee525

See more details on using hashes here.

File details

Details for the file smartmemory_client-0.5.1-py3-none-any.whl.

File metadata

File hashes

Hashes for smartmemory_client-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d959c1cf3c0901952a733df90a3cb0b6563301dd9571068c6adfa7d273b9c5bd
MD5 904d959534522e8a79e45c1fd5125ba0
BLAKE2b-256 ad46eea9afa97c9cc982ec5859ab7951c975d419027119a3b4948808a2dd2db9

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