Catalog PyPI
PACKAGE EXPLORERView in registry

ai-effectlog

PyPI

Semantic side-effect tracking for AI agents

agentsaicrash-recoveryeffect-logside-effects
Versions collected1
Direct dependencies0From release 0.1.0
Last observed21 Oct, 10:37 UTC

README

Version 0.1.0 documentation

effect-log

Semantic side-effect tracking for AI agents.

When an AI agent crashes mid-task, what happens on restart? Without effect-log, irreversible actions (emails, payments, deployments) get repeated. With effect-log, the system knows what completed and what didn't — it returns sealed results for finished work and resumes from where it left off.

The Core Idea

Every tool declares its effect kind at registration time. This drives all recovery behavior:

EffectKindRecovery (completed)Recovery (crashed)
ReadOnlyReplay for fresh dataReplay safely
IdempotentWriteReturn sealed resultReplay with same key
CompensatableReturn sealed resultCompensate, then replay
IrreversibleWriteReturn sealed resultEscalate to human
ReadThenWriteReturn sealed resultEscalate to human

Quick Start

from effect_log import EffectKind, EffectLog, ToolDef

def send_email(args):
    return smtp.send(args["to"], args["subject"], args["body"])

tools = [
    ToolDef("read_file",  EffectKind.ReadOnly,         read_file),
    ToolDef("send_email", EffectKind.IrreversibleWrite, send_email),
    ToolDef("upsert",     EffectKind.IdempotentWrite,   upsert_record),
]

log = EffectLog(execution_id="task-001", tools=tools, storage="sqlite:///effects.db")
log.execute("read_file",  {"path": "/tmp/report.csv"})
log.execute("send_email", {"to": "ceo@co.com", "subject": "Report", "body": "..."})
log.execute("upsert",     {"id": "report-001", "data": data})

Recovery — just add recover=True, re-run the same steps:

log = EffectLog(execution_id="task-001", tools=tools, storage="sqlite:///effects.db", recover=True)
log.execute("read_file",  {"path": "/tmp/report.csv"})  # Replayed (fresh data)
log.execute("send_email", {"to": "ceo@co.com", ...})    # Sealed — NOT re-sent
log.execute("upsert",     {"id": "report-001", ...})    # Replayed (idempotent)

Framework Integration

Built-in middleware for major agent frameworks:

FrameworkMiddlewareEntry Point
LangGrapheffect_log.middleware.langgraphEffectLogToolNode, effect_logged_tools
OpenAI Agents SDKeffect_log.middleware.openai_agentseffect_logged_agent, wrap_function_tool
CrewAIeffect_log.middleware.crewaieffect_logged_crew, effect_logged_tool

See examples/ for runnable demos:

How It Works

A write-ahead log with two record types:

  1. Intent — written before execution (tool name, effect kind, input, cursor)
  2. Completion — written after execution (outcome, sealed response)

Intent without completion = crash detected. The recovery engine uses the effect kind to decide: replay, return sealed, compensate, or escalate.

Building from Source

# Rust
cargo build --release
cargo test --workspace --all-features

# Python
cd bindings/python
pip install maturin
maturin develop --all-features
pytest tests/ -v

Roadmap

  • Core library — WAL engine, recovery engine, SQLite + in-memory backends
  • Python bindings — PyO3 + maturin
  • Framework middleware — LangGraph, OpenAI Agents SDK, CrewAI
  • TypeScript bindings — napi-rs, Vercel AI SDK
  • Additional backends — RocksDB, S3, Restate journal
  • Auto-classification — infer effect kind from HTTP methods / API metadata

Inspiration

The idea behind this project was inspired by a blog post from Guanlan Dai. He introduced the concepts of effect log and semantic correctness.

License

Apache-2.0

Downloads & popularity

Awaiting observations

No metric observations yet

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

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.015 Mar 20260

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
xudong963/effect-log

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 21 Oct, 10:37 UTC

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

Record identity

package:e2306bcdf838444b52039a99df54e045e7762b6e708828edd1ef81c6b15fc2e6