Skip to main content

Python SDK for Norns — durable agent runtime on BEAM

Project description

norns-sdk

CI Python 3.10+ License: MIT

Python SDK for Norns — durable agent runtime on BEAM.

Two classes, two roles:

  • Norns — worker. Registers agents and tools, handles dispatched LLM/tool tasks. Blocks forever, like a Temporal worker.
  • NornsClient — client. Sends messages, polls for results, streams events. For your Slack bot, web backend, CLI, etc.
pip install norns-sdk

Worker

import os
from norns import Norns, Agent, tool

@tool
def search_docs(query: str) -> str:
    """Search product documentation."""
    return db.vector_search(query)

@tool(side_effect=True)
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email to a customer."""
    smtp.send(to=to, subject=subject, body=body)
    return f"Email sent to {to}"

agent = Agent(
    name="support-bot",
    model="claude-sonnet-4-20250514",
    system_prompt="You are a customer support agent. Look up docs and help customers.",
    tools=[search_docs, send_email],
    mode="conversation",
    on_failure="retry_last_step",
)

norns = Norns("http://localhost:4000", api_key=os.environ["NORNS_API_KEY"])
norns.run(agent, llm_api_key=os.environ["ANTHROPIC_API_KEY"])

This connects to Norns via WebSocket, registers the agent, and sits in a loop handling llm_task and tool_task dispatches. Norns never sees your API keys — your worker makes all external calls.

Norns Orchestrator                    Your Python Worker
  │  (pure state machine)                │  (this SDK)
  │                                      │
  │  dispatches llm_task ──────────────► │  calls Anthropic API
  │  ◄── llm_response ─────────────────  │
  │  dispatches tool_task ─────────────► │  calls search_docs()
  │  ◄── tool_result ──────────────────  │
  │  logs events, checkpoints            │

Client

import os
from norns import NornsClient

client = NornsClient("http://localhost:4000", api_key=os.environ["NORNS_API_KEY"])

# Fire-and-forget
run = client.send_message("support-bot", "Where's my order?")
# run.run_id, run.status == "accepted"

# Wait for completion
result = client.send_message("support-bot", "Where's my order?", wait=True, timeout=30)
print(result.output)

# Multi-turn with a conversation key
result = client.send_message("support-bot", "And the tracking number?",
                             conversation_key="slack:U01ABC", wait=True)

# Inspect a run
run = client.get_run(42)
events = client.get_events(42)

# Stream events as they happen
for event in client.stream("support-bot", "Research quantum computing"):
    if event.type == "completed":
        print(event.data.get("output", "")[:80])
        break

Tools

The @tool decorator infers JSON Schema from type hints:

@tool
def lookup_customer(email: str) -> str:
    """Look up a customer by email."""
    customer = db.query("SELECT * FROM customers WHERE email = ?", email)
    return f"Found: {customer['name']} ({customer['plan']})"

Mark side-effecting tools so Norns can enforce idempotency:

@tool(side_effect=True)
def charge_card(customer_id: str, amount: float) -> str:
    """Charge a credit card."""
    result = stripe.charges.create(customer=customer_id, amount=int(amount * 100))
    return f"Charged ${amount}: {result['id']}"

Async handlers work too:

@tool
async def fetch_page(url: str) -> str:
    """Fetch a web page."""
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            return await resp.text()

Agent options

agent = Agent(
    name="my-agent",
    model="claude-sonnet-4-20250514",
    system_prompt="You are helpful.",
    tools=[search, send_email],
    mode="conversation",             # "task" or "conversation"
    checkpoint_policy="on_tool_call",  # "every_step", "on_tool_call", "manual"
    context_window=20,
    max_steps=50,
    on_failure="retry_last_step",    # "stop" or "retry_last_step"
)

Docs

License

MIT

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

norns_sdk-0.1.0.tar.gz (55.1 kB view details)

Uploaded Source

Built Distribution

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

norns_sdk-0.1.0-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file norns_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: norns_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 55.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for norns_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3694ac7426a05161b8685b9c45de85ded10bb6e34b9a8596e812ad05d5791404
MD5 92eedc997f07d601d949e0c39f9fe58b
BLAKE2b-256 a23f822b1c3fe768110ed2dcd14211bedba379a19165855ee9fd8bae2e6ba6ac

See more details on using hashes here.

Provenance

The following attestation bundles were made for norns_sdk-0.1.0.tar.gz:

Publisher: release.yml on amackera/norns-sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file norns_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: norns_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for norns_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cbafa576d2ec3065afe54decac671f9ab0a7153b9445b40425621b48556bc090
MD5 8d6b4d6cf0511ba590521fb6c77752f2
BLAKE2b-256 0b27481a1762f2a4b0c0ec09e1ca31c6cc5917d7ff28532f780411a84dae80c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for norns_sdk-0.1.0-py3-none-any.whl:

Publisher: release.yml on amackera/norns-sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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