Skip to main content

Auditable BDI (belief-desire-intention) agents with LLM deliberation — explicit beliefs, committed intentions, and a trace that answers 'why'

Project description

cetana

Auditable BDI agents — a cognitive architecture for the LLM era.

PyPI version License: MIT

Most LLM agents are a prompt loop: state lives in a transcript, "goals" are whatever the last completion implied, and nobody can say why the agent did what it did. The classical answer to exactly this problem is 30 years old: the Belief–Desire–Intention architecture (Bratman 1987; Rao & Georgeff 1995) — explicit mental state, deliberate commitment, coherent behaviour over time.

cetana is BDI rebuilt for LLMs, on one principle:

The architecture decides when to think. The LLM decides what to think.

  • Beliefs are a revisable, sourced, timestamped store — not lines in a prompt
  • Intentions are commitments: the agent does not re-deliberate every cycle, so behaviour is stable, cheap, and predictable
  • The LLM is consulted at exactly two points — option generation and planning — through a provider-agnostic (prompt) -> str callable
  • Plans may only use registered actions; a hallucinated capability is a caught error, not silent improvisation
  • Every cycle is recorded: agent.explain() answers "why did you do that?" with the actual cognitive history

Zero dependencies. Any LLM client. Fully deterministic under test (script the LLM, assert the behaviour).

cetanā (චේතනා) is the Pali term for volition — in Buddhist psychology, the mental factor that directs the mind toward action.

Installation

pip install cetana

Quick start

from cetana import ActionRegistry, BDIAgent, ok, fail

actions = ActionRegistry()

@actions.register("check_fridge", "See what ingredients are available")
def check_fridge():
    return ok({"rice": True, "eggs": 2})

@actions.register("cook", "Cook a named dish")
def cook(dish):
    return ok(f"{dish} ready")

# Any callable (prompt: str) -> str works: Anthropic, OpenAI, local, or a stub.
import anthropic
client = anthropic.Anthropic()
def llm(prompt):
    msg = client.messages.create(
        model="claude-opus-4-8", max_tokens=1024,
        messages=[{"role": "user", "content": prompt}],
    )
    return msg.content[0].text

agent = BDIAgent("Feed the household dinner", llm, actions)
agent.believe("time", "evening")

agent.run()

print(agent.explain())
# cycle 1:
#   options: cook_dinner: Cook rice for dinner; wait: ...
#   committed to: Cook rice for dinner — it's evening and rice is available
#   plan: check_fridge -> cook
#   executed: check_fridge({}) [ok] obs={'rice': True, 'eggs': 2}
# cycle 2:
#   executed: cook({'dish': 'rice'}) [ok] obs='rice ready'
#   intention: succeeded

The cycle

percepts ──> revise beliefs ──> committed? ──yes──> execute next step ──> observe
                                   │ no                                     │
                                   └─> deliberate (LLM) ─> commit intention ┘

Deterministic architecture code does perception, belief revision, commitment bookkeeping, execution, and failure accounting. The LLM fills two cognitive gaps — what is worth pursuing? and how? — and on step failure, a bounded replan (still worth it? new plan or give up?).

Why commitment matters

A prompt-loop agent reconsiders everything every turn — one odd completion and it wanders. A BDI agent deliberates, commits, and then executes until the intention succeeds, fails, or is deliberately dropped. Fewer LLM calls, stabler behaviour, and a meaningful answer to "what is the agent doing right now?": read agent.intention.

Testing your agent

The LLM port makes agents deterministic under test:

class ScriptedLLM:
    def __init__(self, *responses):
        self.responses = list(responses)
    def __call__(self, prompt):
        return self.responses.pop(0)

Script deliberation, assert on agent.trace — no API key, no flakiness. This library's own test suite works exactly this way.

Status & roadmap

Early release (0.1.0) — the core loop, belief store, commitment machinery, trace, and failure handling are complete and tested. Planned: belief decay and confidence-weighted revision, multiple concurrent intentions with priority scheduling, a structured-output deliberation mode, and provider extras. The design is discussed in my Artificial Cognitive Systems series on Medium.

License

MIT — see LICENSE.

Author

Ravindu Pabasara Karunarathna — also the author of tokscope, slnic, and sinhaladate.

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

cetana-0.1.0.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

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

cetana-0.1.0-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: cetana-0.1.0.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for cetana-0.1.0.tar.gz
Algorithm Hash digest
SHA256 144973fb13764e0e9bdb49041d225008e267afe548a4e0a34ece912f117f80b7
MD5 bab9e19e60fd75f1b427e9077404e6ef
BLAKE2b-256 4b73772500c3b5dc226c8f887c0ea73eb53614dcf521ecb7b683560c64d84bc4

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cetana-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for cetana-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1954d06f481207112b87c8e1fa040c38f890e62798e04a31f57070973776dcbe
MD5 3a6e6d73402a0911f862a32bde1677e4
BLAKE2b-256 5a6ec1666ebf13a53bca586bdea5e29646f2526e693d1a894242d08298e8f091

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