Python SDK for TraceMem - Decision tracking and traceability for AI agents and automation systems.
import asyncio
import os
from tracemem import TraceMemClient
async def main():
# Create client (only api_key required)
client = TraceMemClient(api_key=os.getenv("TRACEMEM_API_KEY"))
# Open a decision from an action
decision = await client.open("refactor", {
"automation_mode": "propose",
})
# Add context
await decision.note({
"kind": "info",
"message": "Starting refactoring work",
})
# Close the decision
await decision.close({
"outcome": "commit",
"reason": "Refactoring completed successfully",
})
# Clean up
await client.close_session()
asyncio.run(main())pip install tracememThe SDK requires only an API key to get started:
from tracemem import TraceMemClient
client = TraceMemClient(api_key="your-api-key-here")client = TraceMemClient(
api_key="your-api-key-here",
mcp_url="https://mcp.tracemem.com", # Default
timeout_ms=30000, # Default: 30 seconds
sanitize=True, # Default: true (redacts secrets, truncates large data)
default_actor="my-agent", # Default: "tracemem-py"
default_automation_mode="propose", # Default: "propose"
action_intent_map={ # Extend default action->intent mapping
"custom_action": "custom.intent.execute",
},
)Use open() to create a decision from a common action (automatically maps to intent):
decision = await client.open("edit_files", {
"automation_mode": "propose",
"actor": "my-agent",
"metadata": {
"project": "my-project",
"branch": "main",
},
})Use create_decision() for explicit intent control:
decision = await client.create_decision("code.change.apply", {
"automation_mode": "execute",
"actor": "my-agent",
"instance": "instance-123",
"version": "1.0.0",
"metadata": {
"custom": "data",
},
})await decision.note({
"kind": "info",
"message": "Starting work",
"data": {
"files": ["file1.py", "file2.py"],
},
})result = await decision.read("pg_customers_v1", "order_validation", {
"query": {
"customer_id": "12345",
},
"result_mode": "single", # or "multiple"
})evaluation = await decision.evaluate("discount_cap_v1", {
"inputs": {
"proposed_discount": 0.15,
"customer_tier": "premium",
},
})await decision.request_approval({
"kind": "discount_approval",
"message": "Customer requesting 25% discount, exceeds policy limit",
})await decision.write("pg_orders_v1", "order_creation", {
"operation": "insert",
"records": [
{
"order_id": "ord_123",
"customer_id": "cust_456",
"amount": 99.99,
},
],
}, {
"idempotency_key": "order_123_unique",
})# Get full trace of decision activities
trace = await decision.trace()
# Get receipt (summary)
receipt = await decision.receipt()await decision.close({
"outcome": "commit", # or "abort"
"reason": "Order successfully processed",
})decision = await client.open("secrets", {
"automation_mode": "propose",
})
# Evaluate policy
evaluation = await decision.evaluate("secrets_change_policy", {
"inputs": {
"secret_name": "DATABASE_PASSWORD",
"change_type": "update",
},
})
# Request approval if needed
if evaluation.get("requiresApproval"):
await decision.request_approval({
"kind": "secrets_change",
"message": "Updating production database password",
})
# Wait for approval (poll or webhook)
# ... approval logic ...
# Proceed with change
await decision.write("secrets_v1", "secret_update", {
"operation": "update",
"name": "DATABASE_PASSWORD",
"value": "new-secure-password",
})
await decision.close({
"outcome": "commit",
"reason": "Secret updated after approval",
})# List all products
products_text = await client.products.list()
# Parse JSON if needed
import json
products = json.loads(products_text)
# Get specific product
product_text = await client.products.get("pg_customers_v1")
product = json.loads(product_text)You can also use client methods directly (useful when working with multiple decisions):
decision_id = "dec_abc123"
await client.note(decision_id, {
"kind": "info",
"message": "Note",
})
result = await client.read(decision_id, {
"product": "pg_customers_v1",
"purpose": "order_validation",
"query": {"customer_id": "123"},
})By default, the SDK automatically sanitizes data before sending to TraceMem:
- Secret Redaction: Keys matching patterns like
password,api_key,token,secret, etc. are redacted - String Truncation: Strings longer than 1000 characters are truncated
- Array Truncation: Arrays longer than 100 items are truncated
- Object Key Limits: Objects with more than 100 keys are truncated
- Depth Limits: Nested structures deeper than 10 levels are truncated
To disable sanitization:
client = TraceMemClient(
api_key="your-key",
sanitize=False, # Disable sanitization
)Note: Disabling sanitization may expose sensitive data. Use with caution.
The SDK provides typed error classes:
from tracemem import (
TraceMemError,
TraceMemNetworkError,
TraceMemValidationError,
TraceMemTimeoutError,
)
try:
await client.create_decision("code.change.apply")
except TraceMemNetworkError as e:
# Handle network error
print(f"Network error: {e.message}")
except TraceMemValidationError as e:
# Handle validation error
print(f"Validation error: {e.message}")
except TraceMemTimeoutError as e:
# Handle timeout
print(f"Request timed out: {e.message}")
except TraceMemError as e:
# Handle other TraceMem errors
print(f"TraceMem error: {e.code} - {e.message}")The SDK automatically maps common actions to intents:
| Action | Intent |
|---|---|
edit_files |
code.change.apply |
refactor |
code.refactor.execute |
run_command |
ops.command.execute |
deploy |
deploy.release.execute |
secrets |
secrets.change.propose |
db_change |
data.change.apply |
review |
code.review.assist |
Unknown actions are used as-is (no mapping).
The client supports async context managers for automatic cleanup:
async with TraceMemClient(api_key="your-key") as client:
decision = await client.open("refactor")
# ... work with decision ...
await decision.close()
# Session automatically closedThe SDK is fully typed and includes type hints for all public APIs. It supports Python 3.8+ type hints with the typing module.
- Python >= 3.8
- aiohttp >= 3.8.0
- typing-extensions >= 4.0.0 (for Python < 3.11)
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=tracemem --cov-report=html
# Run integration tests (requires API key)
export TRACEMEM_API_KEY="your-api-key"
pytest tests/integration/# Format code
black tracemem tests
# Lint code
ruff check tracemem tests
# Type check
mypy tracememApache-2.0