Catalog PyPI
Back to packageRELEASE DETAILS

0.5.1

PyPI

agentstate-lib

Stateful coordination layer for multi-agent AI systems

agentsllmmulti-agentorchestrationstate
Published16 Jun 2026
Direct dependencies17
Transitive dependenciesNot calculated

README

Version 0.5.1 documentation

AgentStateLib

AgentStateLib is a Python library for building reliable multi-agent workflows. It gives multiple agents a shared, typed state and a simple graph router, so you can coordinate them without passing raw strings around.

Installation

pip install agentstate-lib

Quick start

import asyncio
from agentstatelib import SharedState, AgentGraph, StatePatch

graph = AgentGraph()

@graph.node("planner", context=["goal"])
async def planner(context: dict) -> StatePatch:
    goal = context["goal"]
    return StatePatch(
        agent_id="planner",
        target="facts.planned",
        value=True,
        reason=f"planned goal: {goal!r}",
    )

@graph.node("summarizer", context=["facts.planned", "goal"])
async def summarizer(context: dict) -> StatePatch:
    planned = context.get("facts", {}).get("planned")
    goal = context.get("goal")
    summary = f"Workflow for goal {goal!r} planned={planned}"
    return StatePatch(
        agent_id="summarizer",
        target="facts.summary",
        value=summary,
        reason="add summary",
    )

graph.edge(
    "planner",
    "summarizer",
    condition=lambda s: s.get("facts", {}).get("planned") is True,
)

async def main() -> None:
    state = SharedState(goal="Write a multi-agent blog post")
    final_state = await graph.run(state, start="planner")
    print(final_state.facts)

if __name__ == "__main__":
    asyncio.run(main())

Core ideas

  • SharedState: a Pydantic model that holds the workflow’s goal, tasks, artifacts, decisions, and facts.
  • StatePatch: what agents return. A structured change like “set facts.planned = True”.
  • AgentGraph: runs agents as a directed graph. Each agent is just an async function that receives a small context dict and returns a StatePatch.
  • Context slicing: each agent declares which paths it needs (e.g. ["goal", "facts.planned"]), and only sees that subset of the state.
  • Event store: every applied patch is recorded as an event in a pluggable store (in-memory or SQLite), so you can replay or debug workflows. [file:1]

Status

Version 0.5.1 — all Phase 2E features are implemented and tested (93 tests pass, mypy strict: 0 errors).

Phase 1–2E implemented:

  • SharedState, StatePatch, AgentGraph, round-based parallel execution
  • Conflict detection with LastWriteWins, PriorityBased, RejectIncoming strategies
  • InvariantChecker framework with two built-in checkers
  • Append-only event log (16 typed events) — InMemoryStore, SQLiteStore, PostgreSQLStore
  • Checkpointing to disk with save/load/recovery
  • ReplayDebugger for step-through inspection of any past state
  • Full trace model: ContextSliced, PromptAssembled, ModelCalled, ModelReturned, ValidationFailed, RetryAttempted, ToolCalled, ToolReturned
  • LLMAgent base class with retry-with-correction loop
  • OpenTelemetry tracing (optional, graceful no-op fallback)
  • Rich terminal dashboard (optional)
  • FastAPI HTTP server with SSE streaming and web dashboard
  • Human-in-the-loop approval gates with REST API and programmatic resolution
  • WorkflowSummary analysis with anomaly detection

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 17

Native requirements
17 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
aiosqlite
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
aiosqlite>=0.19runtime
pydantic
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
pydantic>=2.0runtime
fastapi
Environment
{
  "extras": "",
  "marker": "extra == \"api\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
fastapi>=0.100; extra == "api"runtime
uvicorn
Environment
{
  "extras": "standard",
  "marker": "extra == \"api\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
uvicorn[standard]>=0.20; extra == "api"runtime
rich
Environment
{
  "extras": "",
  "marker": "extra == \"dashboard\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
rich>=13.0; extra == "dashboard"runtime
httpx
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
httpx>=0.24; extra == "dev"runtime
hypothesis
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
hypothesis>=6.0; extra == "dev"runtime
mypy
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
mypy>=1.0; extra == "dev"runtime
pytest-asyncio
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
pytest-asyncio>=0.21; extra == "dev"runtime
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
pytest>=7.0; extra == "dev"runtime
ruff
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
ruff>=0.1; extra == "dev"runtime
mike
Environment
{
  "extras": "",
  "marker": "extra == \"docs\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
mike>=2.2.0; extra == "docs"runtime
mkdocs-material
Environment
{
  "extras": "",
  "marker": "extra == \"docs\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
mkdocs-material>=9.7.6; extra == "docs"runtime
mkdocstrings
Environment
{
  "extras": "python",
  "marker": "extra == \"docs\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
mkdocstrings[python]>=1.0.4; extra == "docs"runtime
opentelemetry-api
Environment
{
  "extras": "",
  "marker": "extra == \"otel\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
opentelemetry-api; extra == "otel"runtime
opentelemetry-exporter-otlp-proto-grpc
Environment
{
  "extras": "",
  "marker": "extra == \"otel\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
opentelemetry-exporter-otlp-proto-grpc; extra == "otel"runtime
opentelemetry-sdk
Environment
{
  "extras": "",
  "marker": "extra == \"otel\"",
  "requires_python": ">=3.11",
  "evaluation": "NOT_EVALUATED"
}
opentelemetry-sdk; extra == "otel"runtime

Distribution files

2 collected
agentstate_lib-0.5.1-py3-none-any.whl

bdist_wheel · 55.61 KB · Python py3

Source file
agentstate_lib-0.5.1.tar.gz

sdist · 181.49 KB · Python source

Source file

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 23:29 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:d147302e46a05bda3f6bd71035bc9d5ed75d5b07e9b61691bf79f7c67a583ec5

Other collected versions

View all collected versions →