Skip to content
Back to integrations

§ INTEGRATION · CREWAI

CrewAI instrumentation

One call wires Execlave into step and task callbacks, preserves your existing callbacks, and enforces tool-allowlist policies before each tool call.

§ 01

Prerequisites

  • Execlave account with an active API key — Settings → API keys.
  • A registered agent / crew in Execlave. Use the crew's lowercase-kebab agent_id when calling instrument_crew.
  • Python >=3.10 and crewai >=0.80,<1.
  • JavaScript is not supported — CrewAI is Python-only.
§ 02

Install

CrewAI ships as an optional extra so the default SDK install does not pull crewai as a transitive dependency.

Python

pip install 'execlave-sdk[crewai]'
§ 03

Instant setup with a copilot

Paste this prompt into your AI coding assistant. It will add one call before kickoff() without touching any Agent, Task, or tool definition.

§ Copy prompt · paste into your AI coding assistant
You are adding Execlave (an AI agent governance platform) to an existing Python project that uses CrewAI. Do not rewrite existing Agents, Tasks, or Crews — only attach instrumentation. Rules you MUST follow:1. Install the correct extra: `pip install 'execlave-sdk[crewai]'`. Add it to requirements.txt / pyproject.toml.2. Read `EXECLAVE_API_KEY` from environment variables. Never hardcode keys. Add it to `.env.example`.3. Create exactly ONE Execlave client per process and reuse it: `exe = Execlave(api_key=os.environ["EXECLAVE_API_KEY"])`.4. Call `instrument_crew(crew, exe, agent_id="<stable-kebab-id>")` immediately before `crew.kickoff()`. The import is `from execlave.integrations.crewai import instrument_crew`. The `agent_id` is a stable kebab-case string identifying this crew in the Execlave dashboard — NOT a CrewAI role name.5. `instrument_crew` CHAINS onto any existing `step_callback` / `task_callback`. It never overwrites user callbacks. Do NOT remove or replace callbacks the project already has set.6. `instrument_crew` is IDEMPOTENT — a `_execlave_instrumented` marker is set on the crew so calling it twice is a no-op. Do not guard it with your own "already instrumented" check.7. Wrap `crew.kickoff()` in try/except for `execlave.errors.PolicyBlockedError`. On block, return a structured 4xx payload containing `exc.violations`. Do NOT swallow the error silently.8. Do NOT manually call `exe.enforce_policy` for tool calls — the wrapped `step_callback` enforces before each tool step. Enforcement runs only for steps with a non-empty `tool` attribute; pure-reasoning steps are recorded but not enforced.9. Each `Agent` inside the crew is instrumented in addition to the crew itself, so sub-agent tool calls are captured. You do NOT need to pass each agent separately.10. On process shutdown (ASGI lifespan / SIGTERM handler), call `exe.flush()` so in-flight spans are not dropped.11. JavaScript is NOT supported — CrewAI is Python-only. If the project is Node/TS, stop and tell me. Deliverables:- Edit only the file that builds and kicks off the Crew. One diff per file.- Do not touch Agent, Task, or tool definitions.- Add `EXECLAVE_API_KEY` and optional `EXECLAVE_BASE_URL` to `.env.example`. Reference: https://www.execlave.com/docs/integrations/crewaiAPI reference: https://www.execlave.com/docs/sdk-reference
§ 04

Quick start

Build the crew as usual, call instrument_crew() once, then kickoff(). Every agent step, tool call, and task completion lands in the dashboard under one trace id.

Python

from crewai import Agent, Crew, Taskfrom execlave import Execlavefrom execlave.integrations.crewai import instrument_crew exe = Execlave(api_key="exe_live_...") researcher = Agent(role="Researcher", goal="Find Q3 pipeline facts", backstory="…")writer     = Agent(role="Writer",     goal="Summarise for leadership",  backstory="…") task1 = Task(description="Pull pipeline from Salesforce", agent=researcher, expected_output="csv")task2 = Task(description="Write 5-bullet summary",        agent=writer,     expected_output="md") crew = Crew(agents=[researcher, writer], tasks=[task1, task2]) # Idempotent — safe to call repeatedly. Chains onto any existing# step_callback / task_callback rather than replacing it.instrument_crew(crew, exe, agent_id="q3-review-crew") result = crew.kickoff()
§ 05

Callback chaining (not replacement)

If a crew or agent already has step_callback or task_callback set, Execlave wraps the existing callback rather than overwriting it — your hooks still fire.

Chaining semantics

  • Execlave's callback runs first; if it raises a policy block, the crew run aborts before your callback sees the step.
  • If Execlave's callback succeeds, your pre-existing callback is invoked with the same payload.
  • A _execlave_instrumented marker on the crew makes repeated calls to instrument_crew() a no-op — safe to call from hot paths or auto-reloaders.
  • Attribute detection only — no structural assumptions about CrewAI step objects. Minor upgrades of CrewAI do not require an Execlave release.
§ 06

Tool enforcement

CrewAI step objects expose tool and tool_input attributes. Execlave detects tool steps and runs enforce_policy before the tool executes, so block-mode policies halt the crew before the tool is called.

Catching a block

from execlave.errors import PolicyBlockedError try:    result = crew.kickoff()except PolicyBlockedError as exc:    # A block-mode policy matched a tool call inside the crew; kickoff aborts    # BEFORE the tool was executed. exc.violations holds the matches.    return {"error": "blocked", "violations": exc.violations}
§ 07

Operational guarantees

Guarantees

  • Enforcement exceptions re-raise so block-mode policies halt the crew; all other exceptions inside Execlave's callbacks are logged and swallowed.
  • Each agent inside the crew is instrumented in addition to the crew itself, so sub-agent tool calls are captured without extra calls.
  • If pydantic freezes prevent the marker from being set, the double-wrap guard degrades gracefully (logged, not fatal).
§ 08

What's next