Skip to main content

LIPAS — write ordinary Python agents with replay, auditing, supervision, and durable handoffs.

Project description

LIPAS

LIPAS lets you write ordinary Python agents with an explicit record of what they decided, spent, and did. It is a small Python reference implementation of a claim-based execution model for reliable AI agents.

Start with one assistant. Add only the reliability boundary the application actually needs.

Agent  = one assistant that thinks and uses tools
@tool  = an explicit capability with a declared side effect
Team   = a durable handoff between named assistants or functions

0.9.8 public beta. Ollama, injected-client Anthropic, and OpenAI Responses adapters are available, along with durable SQLite sessions, safe replay, supervision, and at-least-once Team handoffs.

The one idea underneath

LIPAS does not ask you to write a graph or a special workflow language. You write ordinary Python; an Agent calls a model and ordinary @tool functions. The runtime records the reliability-relevant parts of that work as immutable Claims.

A fold accepts each stable claim once, validates it, and updates small derived views of the same record: history answers what happened, capability enforces spend limits, and effects record intent → result | rejection.

ordinary Python Agent / Tool / Team
                 │
                 ▼
           append-only Claims
                 ├── history:    decisions and handoffs
                 ├── capability: budgets and spend
                 └── effect:     intent, result, lineage

That one record is why the pieces fit together rather than becoming unrelated features: guards and budgets decide before a call; replay substitutes a recorded result; supervision records its recommendation; a Team handoff has a stable causal id; an external write can be reconciled against its recorded intent. Your code remains natural Python because the runtime records the boundary around it instead of replacing its control flow.

For the precise guarantees and limits, read the short Execution model.

Start here

pip install 'lipas[ollama]'
ollama pull gemma4:12b
from lipas import Agent, tool


@tool(side_effect="read_only")
def lookup_customer(customer_id: str) -> str:
    """Look up a customer without changing external state."""
    return f"customer={customer_id}"


with Agent.ollama(
    tools=[lookup_customer],
    instructions="Use tools when useful; answer concisely.",
    session="runs/support.db",  # omit for in-memory use
) as agent:
    result = agent.ask("Find customer C-42")
    print(result.text)

agent.ask(...) is the normal-script API. In an async application, use await agent.run(...). The first runnable example is examples/01_first_agent.py. The numbered example course then builds from ordinary assistants to replay, supervision, durable handoffs, and external-operation recovery.

When to add more

Keep one Agent when one coherent goal shares one conversation, tool set, budget, and answer. Multiple steps or multiple tools do not require a Team.

Add a Team only when work needs a separate owner or recovery boundary: an independently restartable task, a different authority/budget, a separately audited result, or a human/external-operation handoff. A Team member is usually an Agent, but can be a plain async function. In a normal script:

from lipas import Team


async def researcher(prompt):
    return {"finding": f"researched: {prompt}"}


with Team.open("runs/team.db") as team:
    team.add("research", researcher)
    finding = team.ask_sync("research", "check release risks")

Reliability, only when you ask for it

Add LIPAS provides
@tool(side_effect="read_only") explicit replay and retry safety class
session="runs/app.db" durable trace of intent, result, spend, and decisions
budgets={...} pre-flight rejection before a known limit is exceeded
tool_guards=[...] recorded policy denial before a live call
OperationJournal idempotency-key persistence and reconciliation state for an external write
Team durable, at-least-once handoff with leases and acknowledgement

The record is not a magic memory system and LIPAS is not a graph/workflow DSL. Your application still owns its domain data, business rules, and user-facing workflow.

The high-level Agent API returns a final result. Lower-level LLMHarness.stream(...) supports normalized stream events for integrations that need them, but LIPAS does not yet offer token streaming from Agent.

Reusable Skills

A Skill is a portable SKILL.md instruction file: it captures how an Agent should approach recurring work without granting it any new authority. Tools remain the only executable capability. Start by copying one of the ready-made example skills, then point an Agent at its directory:

from lipas import Agent
from my_app.tools import search_papers

agent = Agent.ollama(
    tools=[search_papers],
    skills="skills/research-brief",
)

The research, support-triage, daily-brief, and safe-external-actions Skills are deliberately small templates: edit them for your own standards rather than treating prompt text as a permission system.

Try and inspect

The optional CLI is for trying an ordinary Python Agent and inspecting its session; it is not a second configuration language.

pip install 'lipas[ollama,cli]'
lipas init support-demo --model gemma4:12b
cd support-demo
lipas chat --factory agent:build_agent
lipas trace runs/chat.db
lipas effects runs/chat.db

From a source checkout before installation, use python -m lipas.cli instead. The session file is created automatically. Ollama is local but accessed through its local HTTP service; a timeout means the local daemon/model did not answer in time, not that LIPAS contacted the internet.

Read only what you need

  • Getting started — build a small Agent, then add replay, a Team handoff, and supervision.
  • Execution model — the exact semantics and limits of claims, effects, replay, external operations, and Teams.
  • Examples — focused, runnable scenarios from the high level API down to the lower-level harnesses.
  • Changelog — release history.

License

Apache License 2.0

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

lipas-0.9.8.tar.gz (188.2 kB view details)

Uploaded Source

Built Distribution

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

lipas-0.9.8-py3-none-any.whl (148.3 kB view details)

Uploaded Python 3

File details

Details for the file lipas-0.9.8.tar.gz.

File metadata

  • Download URL: lipas-0.9.8.tar.gz
  • Upload date:
  • Size: 188.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for lipas-0.9.8.tar.gz
Algorithm Hash digest
SHA256 86e6c682eb9134a31c4187f868c44142cfd62e34320d52f1a65a3c0686ff7e2b
MD5 826d4dfbeb26da69412d4a285e685ac7
BLAKE2b-256 b48ffa00280af3c062fd0792ba383cbb898e1785348ddafa551294d125723c62

See more details on using hashes here.

File details

Details for the file lipas-0.9.8-py3-none-any.whl.

File metadata

  • Download URL: lipas-0.9.8-py3-none-any.whl
  • Upload date:
  • Size: 148.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for lipas-0.9.8-py3-none-any.whl
Algorithm Hash digest
SHA256 f9c0b7902c796ee0bd858a66e5060802bb3a64fa9c39b47fcaf0e6a8186b1dad
MD5 f3e4714ff053f6a2b10286185df76431
BLAKE2b-256 2e3821b93ed2858fb8ecc9026340e1ce8c1ee03be2ffbec0f6c8eb75829c3f00

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