Skip to main content

Arcana

Agent runtime that lets LLMs think, not just execute.

PyPI Python License CI Coverage


The Problem

Most agent frameworks treat LLMs as unreliable workers that need a manager watching every step. They force rigid formats -- ReAct loops, JSON command schemas, mechanical retries -- and dump entire tool catalogs into every prompt. The result is high ceremony, low capability. The framework spends its complexity constraining the LLM instead of releasing it.

The Arcana Approach

Arcana is an operating system for LLM agents, not a pipeline. The LLM decides strategy; the runtime provides services -- budget enforcement, tool dispatch, trace recording, context management. The framework never interprets LLM output: raw facts (TurnFacts) and runtime assessment (TurnAssessment) are kept visibly separate. Nine design principles and four prohibitions, codified in a Constitution, govern every line of code.


Quick Start

pip install arcana-agent
import asyncio
import arcana

async def main():
    result = await arcana.run("Summarize this article", api_key="sk-xxx")
    print(result.output)
    print(f"Cost: ${result.cost_usd:.4f} | Tokens: {result.tokens_used}")

asyncio.run(main())

Use a different provider:

import asyncio, arcana

# OpenAI
result = asyncio.run(arcana.run("Hello", provider="openai", api_key="sk-proj-xxx"))

# Anthropic (pip install arcana-agent[anthropic])
result = asyncio.run(arcana.run("Hello", provider="anthropic", model="claude-sonnet-4-20250514", api_key="sk-ant-xxx"))

Core Features

Tools with Affordances

Tools declare when and why, not just how. The LLM reasons about whether to call a tool, not just how.

@arcana.tool(
    when_to_use="When you need to do math calculations",
    what_to_expect="Returns the numeric result as a string",
    failure_meaning="The expression was malformed",
)
def calc(expression: str) -> str:
    return str(eval(expression))

result = await arcana.run("What is 15 * 37 + 89?", tools=[calc], api_key="sk-xxx")

Runtime

Create once at startup, use across your entire application. Holds providers, tools, budget, and trace as long-lived resources.

runtime = arcana.Runtime(
    providers={"deepseek": "sk-xxx", "openai": "sk-proj-xxx"},
    tools=[calc, web_search],
    budget=arcana.Budget(max_cost_usd=5.0),
    trace=True,
)

result = await runtime.run("Analyze recent trends in quantum computing")

Interactive Chat

Multi-turn sessions with persistent history, shared budget, and context compression.

async with runtime.chat() as c:
    r = await c.send("What are the main themes in this dataset?")
    r = await c.send("Expand on the second theme")
    print(c.total_cost_usd)

Ask User

The LLM can ask clarifying questions mid-execution. If no handler is provided, it proceeds with best judgment -- interaction is a capability, not a dependency.

result = await runtime.run(
    "Book a restaurant for dinner",
    input_handler=lambda q: input(f"Agent asks: {q}\n> "),
)

Structured Output

Return validated Pydantic instances instead of raw text.

from pydantic import BaseModel

class Summary(BaseModel):
    title: str
    key_points: list[str]
    sentiment: str

result = await arcana.run(
    "Summarize this article",
    response_format=Summary,
    api_key="sk-xxx",
)
print(result.parsed.title)       # str
print(result.parsed.key_points)  # list[str]

result.parsed is always BaseModel | None -- never a raw dict. It is None when no response_format is set or when parsing fails. result.output contains the same parsed model when successful, or the raw text when parsing fails.

Multimodal

Pass images alongside text. URLs, local file paths, and data URIs all work.

result = await arcana.run(
    "Describe what you see in this image",
    images=["https://example.com/photo.jpg"],
    provider="openai",
    api_key="sk-proj-xxx",
)

Pipeline

Sequential steps with optional parallel branches. Each step's output flows as context to the next.

result = await runtime.chain([
    arcana.ChainStep(name="research", goal="Find key facts about quantum computing"),
    [  # parallel branch
        arcana.ChainStep(name="summary", goal="Write a concise summary"),
        arcana.ChainStep(name="critique", goal="Identify gaps and biases",
                         budget=arcana.Budget(max_cost_usd=0.50)),
    ],
    arcana.ChainStep(name="final", goal="Integrate summary and critique into a report"),
])
print(result.steps["final"])

Batch Processing

Process many independent tasks concurrently with automatic throttling.

results = await runtime.run_batch([
    {"goal": "Summarize article 1", "response_format": Summary},
    {"goal": "Summarize article 2", "response_format": Summary},
    {"goal": "Summarize article 3", "response_format": Summary},
], concurrency=10)

print(f"{results.succeeded}/{len(results.results)} succeeded")
print(f"Total cost: ${results.total_cost_usd:.4f}")

Multi-Agent Teams

Runtime provides communication and budget. Agents decide strategy -- no forced hierarchy. Two modes: "shared" (all agents see everything) and "session" (independent contexts, messages arrive as user messages).

result = await runtime.team(
    "Design a landing page for an AI product",
    agents=[
        arcana.AgentConfig(name="designer", prompt="You are a senior UX designer."),
        arcana.AgentConfig(name="copywriter", prompt="You are a conversion copywriter."),
        arcana.AgentConfig(name="critic", prompt="You find weaknesses and suggest improvements."),
    ],
    max_rounds=3,
    mode="shared",  # or "session" for independent contexts
)

Budget Scoping

Isolate budget for a subset of runs without affecting the global runtime budget.

async with runtime.budget_scope(max_cost_usd=0.50) as scoped:
    r1 = await scoped.run("Classify this document")
    r2 = await scoped.run("Extract key entities")
    print(f"Scoped cost: ${scoped.budget_used_usd:.4f}")

Graph Orchestration

For workflows that need explicit state machines. Available when you need it, never forced.

from arcana import StateGraph, START, END

graph = runtime.graph(state_schema=MyState)
graph.add_node("research", research_fn)
graph.add_node("write", write_fn)
graph.add_edge(START, "research")
graph.add_edge("research", "write")
graph.add_edge("write", END)

app = graph.compile()
result = await app.ainvoke(initial_state)

What Makes Arcana Different

LangChain CrewAI AutoGPT Arcana
LLM autonomy Framework-driven chains Role-locked agents Fully autonomous, no guardrails LLM decides strategy within runtime boundaries
Token efficiency Full context every call Full prompt per agent Unbounded context growth Working-set discipline -- only what this step needs
Thinking signals Ignored Ignored Ignored Runtime listens to thinking for confidence, never constrains
Tool management All tools in every prompt Per-agent tool sets All tools always Dynamic per-turn exposure with affordances
User interaction Not built in Not built in Not built in ask_user built-in, graceful fallback if no handler
Pipelines Chain + glue code Sequential tasks No pipelines chain() with auto context passing + parallel branches
Default path Chain/graph required Crew required Agent loop always Direct answer when possible, agent loop when needed

Providers

DeepSeek | OpenAI | Anthropic | Google Gemini | Kimi (Moonshot) | GLM (Zhipu) | MiniMax | Ollama

All providers use a single OpenAI-compatible adapter. Adding a new provider is one function call.


Documentation

Guide Description
Quick Start Installation through deployment
Configuration Full configuration reference
Providers Provider setup and fallback chains
API Reference Public API documentation
Architecture System design and internals
Constitution Design principles and prohibitions
Examples Runnable code examples
Changelog Release history

Installation

pip install arcana-agent                   # Core (DeepSeek, OpenAI)
pip install arcana-agent[anthropic]        # + Claude support
pip install arcana-agent[gemini]           # + Gemini support
pip install arcana-agent[all-providers]    # All providers
pip install arcana-agent[ui]              # + Trace Web UI

Or with uv:

uv add arcana-agent
uv add arcana-agent --extra all-providers

Requires Python 3.11+.


License

MIT

Metadata

Release files for arcana-agent 1.2.0

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

Source distribution (sdist)

Source distribution for arcana-agent 1.2.0
File Size Uploaded
arcana_agent-1.2.0.tar.gz 1.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for arcana-agent 1.2.0
File Interpreter ABI Platform
arcana_agent-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.4 MB

Release files / arcana_agent-1.2.0.tar.gz

Download URL arcana_agent-1.2.0.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
99ed4f808c6d342c578e12268d9e3083a0cd1af0d26a31ccd7901796d82ddfd8
BLAKE2b-256 checksum
How to use checksums
0facc0a9bd3c22245a939afe9a6df0fed24f240887d5586ebdfd87674cbcfaa7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release files / arcana_agent-1.2.0-py3-none-any.whl

Download URL arcana_agent-1.2.0-py3-none-any.whl
Size 359.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
590a7d40a427cf7f7790a74a51181f80afe4025a3ac152b5b8ea2ee15f8b4fb2
BLAKE2b-256 checksum
How to use checksums
c1904c5051f18ff793e97699e2f02a6f41c098f2e13ddd0d06cf5d9c1b13a237
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log
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