Skip to content

AxmeAI/crewai-durable-human-approval

Repository files navigation

CrewAI Durable Human Approval

CrewAI agents lose state on crash and have no real human approval. AXME adds both - durable state and async HITL.

CrewAI gives you multi-agent crews that research, analyze, and produce reports. But when your research agent finishes a market analysis and needs a senior analyst to approve it before publication - CrewAI has no built-in way to pause, notify the analyst, wait hours, remind, and resume. AXME adds that.

Alpha - Built with AXME (AXP Intent Protocol). cloud.axme.ai - contact@axme.ai


The Problem

CrewAI has limited state management, failures typically require restart. There is no built-in human-in-the-loop that survives disconnects.

CrewAI crew runs market research
  -> Agent gathers data, analyzes competitors, drafts report
  -> Now what? Who approves this before it goes to stakeholders?

Options:
  1. print() and input()? (blocks the process, dies on disconnect)
  2. Send a Slack message manually? (no tracking, no reminder, no timeout)
  3. Build webhook + DB + polling? (200+ lines of infrastructure)

And if the agent crashes mid-research?
  -> CrewAI: start over from scratch

The Solution

CrewAI does the research. AXME handles durability and human approval.

# CrewAI does the thinking
crew = Crew(agents=[researcher], tasks=[research_task])
result = crew.kickoff()

# AXME handles the human gate
intent_id = client.send_intent({
    "intent_type": "intent.research.market_report.v1",
    "to_agent": "agent://myorg/production/crewai-researcher",
    "payload": {"report_id": "MR-2026-Q1", "draft": str(result)},
})
approval = client.wait_for(intent_id)  # reminder in 5 min, timeout in 1h

CrewAI does the reasoning. AXME does the waiting.


Quick Start

pip install axme crewai
export AXME_API_KEY="your-key"   # Get one: axme login
export OPENAI_API_KEY="sk-..."   # For CrewAI LLM calls
from crewai import Agent, Task, Crew
from axme import AxmeClient, AxmeClientConfig
import os

# 1. CrewAI: research agent
researcher = Agent(
    role="Market Research Analyst",
    goal="Produce comprehensive market research reports",
    backstory="Senior analyst at a top consulting firm.",
)

task = Task(
    description="Research the enterprise SaaS AI infrastructure market.",
    expected_output="Market size, growth rate, top players, key trends.",
    agent=researcher,
)

crew = Crew(agents=[researcher], tasks=[task])
result = crew.kickoff()

# 2. AXME: human approval before publishing
client = AxmeClient(AxmeClientConfig(api_key=os.environ["AXME_API_KEY"]))
intent_id = client.send_intent({
    "intent_type": "intent.research.market_report.v1",
    "to_agent": "agent://myorg/production/crewai-researcher",
    "payload": {
        "report_id": "MR-2026-Q1",
        "draft_summary": str(result),
    },
})

# Agent suspends. Reminder in 5 min. Timeout in 1 hour.
approval = client.wait_for(intent_id)
print(f"Decision: {approval['status']}")

Before / After

Before: CrewAI with Manual Approval

crew = Crew(agents=[researcher], tasks=[research_task])
result = crew.kickoff()

# ...and now?
print(result)                     # Print to console?
input("Press Enter to publish...")  # Block the process?

# No reminders. No timeout. No audit trail.
# If the human walks away, the agent is stuck forever.
# If the process crashes, the research is lost.

After: AXME Adds Durability + Approval

crew = Crew(agents=[researcher], tasks=[research_task])
result = crew.kickoff()

intent_id = client.send_intent({
    "intent_type": "intent.research.market_report.v1",
    "to_agent": "agent://myorg/production/crewai-researcher",
    "payload": {"draft": str(result)},
})
approval = client.wait_for(intent_id)
# Reminder in 5 min. Timeout in 1h. Audit trail included.
# Agent crash? Restart it. AXME kept the state.

What Each Component Does

Component Role Framework
agent_crewai.py Full CrewAI Agent + Task + Crew research pipeline CrewAI
agent.py Simplified agent (no LLM, tests AXME flow) AXME SDK
initiator.py Send research intent, observe lifecycle AXME SDK
scenario.json Scenario definition (agent + human approval) AXME CLI

CrewAI does the research. AXME does the infrastructure.


How It Works

+-----------+  send_intent()   +----------------+  research   +-----------+
|           | ---------------> |                | ----------> |           |
| Initiator |                  |   AXME Cloud   |             |  CrewAI   |
|           | <- wait_for() -- |   (platform)   | <- result   |  Agent    |
|           |                  |                |             |           |
|           |                  |  WAITING for   |             +-----------+
|           |                  |  human approval|
|           |                  |                |  approve    +-----------+
|           |                  |                | <---------- |           |
|           | <- COMPLETED --- |  - remind 5m   |             |   Lead    |
|           |                  |  - timeout 1h  |             |  Analyst  |
+-----------+                  +----------------+             +-----------+
  1. Initiator sends a research intent with report parameters
  2. AXME delivers intent to the CrewAI agent via SSE
  3. CrewAI agent runs research (Agent + Task + Crew pattern)
  4. Agent completes and resumes the intent with market data
  5. Workflow moves to human approval step - analyst is notified
  6. Analyst approves or rejects via CLI, email, or form
  7. Initiator receives the final result with full audit trail

Run the Full Example

Prerequisites

curl -fsSL https://raw.githubusercontent.com/AxmeAI/axme-cli/main/install.sh | sh
axme login
pip install -r requirements.txt

Terminal 1 - submit the scenario

axme scenarios apply scenario.json

Terminal 2 - start the agent

# macOS
cat ~/Library/Application\ Support/axme/scenario-agents.json | grep -A2 crewai-researcher-demo

# Linux
cat ~/.config/axme/scenario-agents.json | grep -A2 crewai-researcher-demo
# Simplified agent (no LLM required)
AXME_API_KEY=<agent-key> python agent.py

# Full CrewAI agent (requires OPENAI_API_KEY)
AXME_API_KEY=<agent-key> OPENAI_API_KEY=sk-... python agent_crewai.py

Terminal 1 - approve (after agent completes its step)

axme tasks approve <intent_id>

Verify

axme intents get <intent_id>
# lifecycle_status: COMPLETED

Related


Built with AXME (AXP Intent Protocol).

About

CrewAI agents lose state on crash and have no real human approval. AXME adds both - durable state and async HITL.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages