Skip to main content

cadreen-sdk

Python SDK for Cadreen — Intelligence as a Service.

⚠️ Compatibility Advisory: Version 0.7.0 has known contract mismatches with the server. Version 0.7.0 is unsupported. Upgrade to 0.7.2. See CHANGELOG for details.

Cadreen is a cognitive operating system. Send messages describing what you want done, and Cadreen reasons, connects tools, recalls knowledge, governs actions, and escalates to humans when needed. The SDK handles authentication, retries, idempotency, streaming, and error classification.

Install

pip install cadreen-sdk

Quick Start

import asyncio
from cadreen import Cadreen

cadreen = Cadreen(api_key="sk_cadreen_...")

async def main():
    # Intent — the main entry point
    result = await cadreen.ask(
        "Handle a refund request for invoice inv_123",
    )
    print(result.explain())

    # Discriminated union with match/case
    match result.type:
        case "direct":
            print(result.message.content)
        case "clarify":
            for q in result.questions:
                print(q)
        case "execution":
            async for event in cadreen.executions.stream(result.execution["id"]):
                print(event.type, event.data)
        case "blocked":
            print(result.reason_code)
        case "connect_required":
            print(result.endpoint)

asyncio.run(main())

Chat Completions

OpenAI-compatible chat completions with built-in governance. Every tool call goes through governance before execution — auto-approved calls execute silently, blocked calls become conversation.

from cadreen.resources.chat import (
    ChatCompletionRequest, ChatMessage,
    ChatToolDefinition, ChatFunctionDefinition,
)

# Basic completion
response = await cadreen.chat.completions(ChatCompletionRequest(
    messages=[ChatMessage(role="user", content="Hello!")],
))
print(response.choices[0].message.content)

# With tool calling
response = await cadreen.chat.completions(ChatCompletionRequest(
    messages=[ChatMessage(role="user", content="Refund order 456")],
    tools=[ChatToolDefinition(function=ChatFunctionDefinition(
        name="process_refund",
        description="Process a refund for an order",
        parameters={
            "type": "object",
            "properties": {"order_id": {"type": "string"}},
            "required": ["order_id"],
        },
    ))],
))

# If governance needs approval, the response contains a text message
# asking the user to confirm — no tool_calls field
msg = response.choices[0].message
if msg.tool_calls:
    for tc in msg.tool_calls:
        print(f"{tc.function.name}({tc.function.arguments})")

# Resume a conversation
follow_up = await cadreen.chat.completions(ChatCompletionRequest(
    messages=[ChatMessage(role="user", content="What about order 789?")],
    conversation_id=response.conversation_id,
))

Streaming

async for chunk in await cadreen.chat.completions_stream(ChatCompletionRequest(
    messages=[ChatMessage(role="user", content="Hello!")],
)):
    if chunk.type == "reasoning_delta":
        # Model is thinking — render in a collapsible accordion
        print(f"[thinking] {chunk.reasoning}", end="", flush=True)
    elif chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Tool Discovery

tools = await cadreen.chat.list_tools()
for tool in tools.data:
    print(f"{tool.function.name}: {tool.function.description}")

Tool Chaining

When the model proposes tool calls, send results back for follow-up:

response = await cadreen.chat.completions(ChatCompletionRequest(
    messages=[
        ChatMessage(role="user", content="What's the weather in NYC?"),
        ChatMessage(role="assistant", tool_calls=[ChatToolCall(
            id="tc_1",
            function=ChatFunctionCall(name="get_weather", arguments='{"city":"NYC"}'),
        )]),
        ChatMessage(role="tool", tool_call_id="tc_1", content='{"temp": 72, "condition": "sunny"}'),
    ],
))
# Model may propose more tools or return a final text response

Configuration

cadreen = Cadreen(
    api_key="sk_cadreen_...",
    base_url="https://accomplishanything.today",  # default
    max_retries=3,      # default 3
    timeout=30,          # default 30s
    profile="lean",     # optional: "lean" | "audit" | "full" (default "full")
)

Response Profiles

Profile What you get Use when
"full" (default) Full response metadata You want full transparency
"audit" Only governance decision + confidence + blocking gaps You need to react to gates
"lean" No envelope. Just trace_id Hot-looping, minimal payload

Marketplace

Browse and install integrations without knowing which provider powers them:

# Browse available integrations
catalog = await cadreen.connections.catalog()
for category in catalog.categories:
    print(f"{category.name}: {len(category.integrations)} integrations")

# One-click install (returns OAuth URL)
install = await cadreen.connections.install("slack")
if install.status == "pending_auth":
    print(f"Authenticate at: {install.auth_url}")

# Check what's installed
print(catalog.installed)  # ["stripe", "github"]

Memory

# Store knowledge
await cadreen.memory.remember(
    type="reference",
    content={"text": "GDPR Article 17: Right to erasure", "title": "GDPR Art. 17"},
    authority=10,
)

# Search
results = await cadreen.memory.search("data deletion rules")

# Get by ID
item = await cadreen.memory.get("mem_abc123")

Policies

# Create a policy
await cadreen.policies.create(
    name="refund_threshold",
    rules=[{"condition": "refund_amount > 500", "action": "require_approval"}],
)

# Evaluate an action
evaluation = await cadreen.policies.evaluate(
    action="Process $750 refund for order 456"
)

Connections

# Register from OpenAPI spec
await cadreen.connections.register_openapi(
    name="internal-erp",
    spec_url="https://erp.example.com/openapi.json",
)

# Register MCP server
await cadreen.connections.register_mcp(
    name="my-mcp-server",
    url="https://mcp.example.com/sse",
    transport="sse",
)

# List installed
connections = await cadreen.connections.list()

Traces

trace = await cadreen.traces.get(result.trace_id)
print(trace.explain())

recent = await cadreen.traces.list(limit=10)
stats = await cadreen.traces.stats()

Documents

# List documents
docs = await cadreen.documents.list()
for doc in docs.documents:
    print(f"{doc.name} ({doc.content_type})")

# Upload a document from file path
result = await cadreen.documents.upload("/path/to/report.pdf")
print(f"Uploaded: {result.name} (ID: {result.id})")

# Upload from bytes
result = await cadreen.documents.upload_bytes(b"file contents", "data.txt")
print(f"Uploaded: {result.name} (ID: {result.id})")

# Get document details
doc = await cadreen.documents.get(result.id)
print(f"Status: {doc.status}, Size: {doc.size} bytes")

Proposals

Cadreen watches your usage and suggests improvements — actions to automate, schedules to set, rules to relax. You decide what runs.

# List proposals waiting for your decision
proposals = await cadreen.proposals.list()
for p in proposals.proposals:
    print(f"[{p.status}] {p.title} ({p.confidence:.0%} confidence)")

# Get a specific proposal
proposal = await cadreen.proposals.get("550e8400-...")

# Accept — executes via the intent engine
result = await cadreen.proposals.accept("550e8400-...")
print(f"Execution: {result.execution_id}, Action: {result.action}")

# Dismiss — teaches Cadreen what you don't want
await cadreen.proposals.dismiss("550e8400-...", reason="We handle this manually")

# See counts by status
stats = await cadreen.proposals.stats()
print(f"Waiting: {stats.proposed}, Accepted: {stats.accepted}")

Agents

Agents are autonomous workers that handle tasks, follow rules, and learn from outcomes.

# Create an agent
agent = await cadreen.agents.create(CreateAgentRequest(
    name="Support Agent",
    description="Handles customer support requests",
))
print(f"Agent created: {agent.id}")

# List agents
result = await cadreen.agents.list()
for a in result.agents:
    print(f"{a.name} ({a.status})")

# Get agent details
agent = await cadreen.agents.get("agent_123")

# Deploy an agent (creates immutable version)
await cadreen.agents.deploy("agent_123")

# Send a message to an agent
msg = await cadreen.agents.send_message("agent_123", SendMessageRequest(
    content="What's the refund policy?",
    from_agent_id="agent_456",
))

# Create an execution
exec = await cadreen.agents.create_execution("agent_123", CreateExecutionRequest(
    task="Process refund for order #1234",
))

# Knowledge — teach the agent
await cadreen.agents.create_knowledge("agent_123", CreateAgentKnowledgeRequest(
    type="reference",
    content="Refunds require manager approval for amounts over $100",
))

# Search knowledge
results = await cadreen.agents.search_knowledge("agent_123", SearchAgentKnowledgeRequest(
    query="refund policy",
))

# Governance — set rules
await cadreen.agents.create_governance("agent_123", CreateAgentGovernanceRequest(
    name="Refund Approval",
    rules=[{"action": "refund", "condition": "amount > 100", "decision": "handoff"}],
))

# Negotiations — agent-to-agent
negotiation = await cadreen.agents.start_negotiation("agent_123", StartNegotiationRequest(
    target_agent_id="agent_456",
    topic="Resource allocation",
    proposal={"resource": "GPU-1", "duration": "2h"},
))

Federation

Federation lets workspaces share agents and knowledge across boundaries.

# Create a federation link
link = await cadreen.federation.create(CreateFederationRequest(
    target_workspace_id="ws_456",
))
print(f"Link created: {link.id} (status: {link.status})")

# List federation links
result = await cadreen.federation.list()
for link in result.federations:
    print(f"{link.name} → {link.status}")

# Approve a pending link (target workspace only)
await cadreen.federation.approve("link_123")

# Link agents across workspaces
await cadreen.federation.link_agent("link_123", LinkFederationAgentRequest(
    local_agent_id="agent_123",
    remote_agent_id="agent_456",
))

# Update permissions
await cadreen.federation.update_permissions("link_123", FederationPermissions(
    share_knowledge=True,
    share_capabilities=True,
))

External Agents (A2A)

Connect to agents from other systems (LangChain, CrewAI, etc.) using the A2A protocol.

# Enable external agents (workspace setting)
await cadreen.external_agents.update_settings(enabled=True)

# Connect to an external agent
connection = await cadreen.external_agents.connect("agent_123", "https://example.com/.well-known/agent.json")
print(f"Connection: {connection.id} (status: {connection.status})")

# List connections
result = await cadreen.external_agents.list("agent_123")
for c in result.connections:
    print(f"{c.agent_name} → {c.status} ({c.health})")

# Approve a pending connection
await cadreen.external_agents.approve("agent_123", "conn_456")

# List interactions
interactions = await cadreen.external_agents.list_interactions("agent_123", "conn_456")
for i in interactions.interactions:
    print(f"{i.direction} {i.operation}: {i.status}")

# List all connections across workspace
all_conns = await cadreen.external_agents.list_all()

Responses API

OpenAI-compatible responses API with built-in governance and memory.

# Create a response
response = await cadreen.responses.create(ResponseRequest(
    model="cadreen",
    input="What tools do I have?",
))
print(response.output_text)

# Conversation state (server-managed)
response2 = await cadreen.responses.create(ResponseRequest(
    model="cadreen",
    input="What about refund tools?",
    previous_response_id=response.id,
))

# Streaming
async for event in cadreen.responses.stream(ResponseRequest(
    model="cadreen",
    input="Explain quantum computing",
)):
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)

Requirements

  • Python 3.10+
  • httpx >= 0.25
  • httpx-sse >= 0.4

Changelog

v0.7.2

  • Added DevicesResource — full device lifecycle (list, create, get, delete, status, state, map, tasks, collisions, avoidance, diagnose, ask, sync, blackboard)
  • Fixed DiagnoseRequest type shadowing — renamed to DeviceDiagnoseRequest for device-specific diagnosis
  • Fixed missing AsyncIterator import in resources/intent.py
  • Fixed connection pooling — HttpClient now reuses a persistent httpx.AsyncClient; added async context manager support

v0.7.1

  • Fix: sandbox mode now raises CadreenError(404) for post_stream and stream instead of making network requests
  • Fix: release workflow Homebrew formula update ordering
  • Documented new server-side execution events: execution_steps_complete, mission_completed_with_gaps

v0.7.0

  • BREAKING: Removed pathways and total_pathways from connection responses. ConnectionGroup now returns only capability and status.
  • BREAKING: Removed Pathway type. Internal routing details (connector, transport, tool_id) are no longer exposed.
  • BREAKING: Changed ConnectManualDetail from {pathways: [...]} to {capability, available, health}.
  • BREAKING: Removed workspace_id from response types: SetupResult, SetupSession, WebhookSubscription, WebhookPayload. (Still accepted on request types.)
  • BREAKING: Removed authScheme from ExternalAgentConnection responses.
  • BREAKING: Removed atoms_consulted, episodes_matched, precedents_applied from memory trace in intelligence metadata.
  • BREAKING: sources_consulted renamed to knowledge_queried in MemoryTrace.
  • BREAKING: All entity responses (Agent, Knowledge, Governance, Federation, Negotiation, ExternalAgentConnection) no longer include workspace_id or workspaceId.
  • New MCP SSE endpoint: GET /api/v1/cadreen/mcp/sse + POST /api/v1/cadreen/mcp/message. Connect Cadreen as an MCP server without installing the npm package.
  • Added cadreen.agents — full agent lifecycle (create, list, get, update, delete, deploy, get_config, get_capabilities)
  • Added agent messaging (send_message, list_messages)
  • Added agent executions (create_execution, list_executions)
  • Added agent knowledge (create_knowledge, list_knowledge, search_knowledge, delete_knowledge)
  • Added agent governance (create_governance, list_governance, update_governance, delete_governance)
  • Added agent audit trail (list_audit)
  • Added agent negotiations (start_negotiation, list_negotiations, get_negotiation, respond_to_negotiation)
  • Added cadreen.federation — cross-workspace federation (create, list, get, approve, suspend, revoke)
  • Added federation permissions (get_permissions, update_permissions)
  • Added federation agent linking (link_agent, list_agents, unlink_agent)
  • Added cadreen.external_agents — A2A external agent connections (connect, list, get, approve, suspend, revoke, delete)
  • Added external agent interactions (list_interactions)
  • Added external agent settings (get_settings, update_settings, list_all)
  • Added cadreen.responses — OpenAI-compatible responses API (create, retrieve, stream)
  • Added 37 new types: Agent, AgentKnowledge, AgentGovernancePolicy, AgentNegotiation, FederationLink, FederationAgent, ExternalAgentConnection, ExternalAgentInteraction, ExternalAgentSettings, ExternalAgentSkill, ExternalAgentCapabilities, etc.

v0.6.3

  • Fix: invoke_stream() crash — was using nonexistent _client._session, now uses httpx-sse
  • Fix: chat.completions() and completions_stream() silently dropping user_id from request body

v0.6.2

  • Added intelligence field to ChatCompletionResponse — full intelligence metadata
  • Added conversation_id field to ChatCompletionResponse — conversation continuity
  • Added reasoning field to ChatDelta — streaming reasoning from thinking models
  • Added reasoning_tokens, cache_write_tokens, prompt_tokens_details to ChatUsage
  • Added BlueprintsResource: list, get, create, update, delete, run, get_runs
  • Added SchedulesResource: list, get, create, update, delete, pause, resume, get_runs
  • Added 16 new types: Blueprint, BlueprintRun, Schedule, ScheduleRun, etc.
  • Document reasoning_delta streaming event in README
  • IntelligenceMeta shape aligned with server

v0.6.1

  • Added user_id optional field to IntentRequest and ChatCompletionRequest — pass end-user identity for per-user context and memory filtering
  • Added WorkspaceUsersResource: list, invite, update_role, remove — manage workspace team members
  • Added WorkspaceUser, WorkspaceRole, InviteUserRequest, UpdateRoleRequest types
  • Added HttpClient.patch() method for PATCH requests

v0.6.0 (BREAKING)

  • BREAKING: ResolveEscalationRequest.resolution renamed to decision — aligns SDK with API contract
  • BREAKING: DiagnoseRequest.error renamed to error_message — aligns SDK with API contract
  • Retry default increased from 2 to 3

v0.5.5

  • Added cadreen.setup_sessions — stateful setup sessions (create, list, get, add_resources, apply)
  • Added SetupSession, SetupSessionCreateRequest, SetupSessionAddRequest, SetupSessionApplyRequest, SetupSessionApplyResult types

v0.5.4

  • Added cadreen.proposals — task proposals (list, get, accept, dismiss, stats)
  • Added TaskProposal, ProposalEvidence, ListProposalsResponse, AcceptProposalResponse, DismissProposalResponse, ProposalStatsResponse types

v0.5.3

  • Added dry_run field to IntentRequest — preview intent classification, governance, and capability assessment without creating a mission or persisting conversation
  • Fixed Go SDK Version constant (was stuck at 0.5.0)

v0.5.2

  • Added dry_run mode to setup() — preview what would be created without persisting
  • Added notice and dry_run fields to SetupResult
  • Added cadreen.list_blueprints(), cadreen.get_blueprint(), cadreen.create_blueprint(), cadreen.delete_blueprint(), cadreen.run_blueprint(), cadreen.list_blueprint_runs()
  • Added cadreen.list_schedules(), cadreen.get_schedule(), cadreen.create_schedule(), cadreen.pause_schedule(), cadreen.resume_schedule()

v0.5.1

  • Added cadreen.documents.upload(file_path) and cadreen.documents.upload_bytes(content, filename) — upload documents
  • Added cadreen.documents — document management (list, get)
  • Added cadreen.escalations — escalation management (list, get, resolve)
  • Added cadreen.healing — self-healing (stats, precedents, diagnose)
  • Added cadreen.webhooks — webhook CRUD (create, list, delete)
  • Added cadreen.learning — learning insights (patterns, episodes, suggestions)
  • Added cadreen.credentials — credential management (list, create, delete)
  • Added cadreen.list_capabilities() — list available capabilities
  • Added cadreen.assess(task, domain=) — assess task readiness

v0.5.0 (BREAKING)

  • BREAKING: API endpoints moved to Cadreen surface (/api/v1/cadreen/):
    • /api/v1/chat/completions → /api/v1/cadreen/chat/completions
    • /api/v1/tools → /api/v1/cadreen/tools
  • All external API calls now route through the Cadreen surface
  • Renamed response profile levels for clarity

v0.4.0

  • Added cadreen.chat.completions() — OpenAI-compatible chat completions with governance
  • Added cadreen.chat.completions_stream() — streaming chat completions via SSE
  • Added cadreen.chat.list_tools() — discover available tools as OpenAI function definitions
  • Added tool calling support: tools param, tool_calls in responses, tool chaining
  • Added conversation_id for persistent conversations across requests
  • Added ChatCompletionRequest, ChatCompletionResponse, ChatToolDefinition and related types

v0.3.0

  • Added catalog() — browse the unified integration marketplace
  • Added install(integration_id) — one-click install with OAuth flow
  • Added CatalogResponse, InstallResponse types

v0.2.1

  • Initial public release

License

MIT

Metadata

Release files for cadreen-sdk 0.7.2

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

Source distribution (sdist)

Source distribution for cadreen-sdk 0.7.2
File Size Uploaded Provenance
cadreen_sdk-0.7.2.tar.gz 69.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for cadreen-sdk 0.7.2
File Interpreter ABI Platform
cadreen_sdk-0.7.2-py3-none-any.whl Python 3 none any Details

Total release size: 129.8 kB

Release files / cadreen_sdk-0.7.2.tar.gz

Download URL cadreen_sdk-0.7.2.tar.gz
Size 69.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8f6b44265cf4aa62742cbc97344900134424d502ffc1728d79a20e4f0ea45136
BLAKE2b-256 checksum
How to use checksums
79b53d18505c88e9c46772288cb2c890ea4482a69e4279fa0e2fc964efafbf47
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release files / cadreen_sdk-0.7.2-py3-none-any.whl

Download URL cadreen_sdk-0.7.2-py3-none-any.whl
Size 60.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d262a5beee732c98676851ebca9c853905ae8b38c7d1e0e6e8ea9099579fd7a3
BLAKE2b-256 checksum
How to use checksums
58d3d43b4cce336d4abc0385ae8129f25d45a5f6bc2c8cd23fd5e756465fc5ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Security for cadreen-sdk 0.7.2

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.

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