> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zespan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CrewAI

> Trace CrewAI crew executions with Zespan. Wrap your Crew instance to capture agent runs, task outputs, latency, and guardrail checks.

<Note>
  Available for: **Python** and **TypeScript**.
</Note>

<Tabs>
  <Tab title="Python">
    ## Installation

    ```bash theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    pip install zespan crewai
    ```

    ## Usage

    Wrap your `Crew` instance with `wrap_crew` before calling `kickoff`. Both sync and async `kickoff` are supported.

    ```python theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    from crewai import Agent, Task, Crew
    from zespan.integrations.crewai_handler import wrap_crew
    import zespan

    zespan.init(api_key="zsp_your_api_key_here")

    researcher = Agent(
        role="Researcher",
        goal="Research the topic thoroughly",
        backstory="Expert researcher with broad knowledge",
        llm="gpt-4o",
    )

    task = Task(
        description="Research the impact of LLMs on software development",
        expected_output="A detailed summary",
        agent=researcher,
    )

    crew = Crew(agents=[researcher], tasks=[task])
    crew = wrap_crew(crew)

    result = crew.kickoff(inputs={"topic": "LLMs in software development"})
    print(result.raw)
    ```

    ## Async usage

    ```python theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    import asyncio

    crew = wrap_crew(crew)
    result = asyncio.run(crew.kickoff_async(inputs={"topic": "AI agents"}))
    ```

    ## With guardrails

    Pass `guardrails=True` to run pre/post content checks on crew inputs and outputs.

    ```python theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    from zespan.integrations.crewai_handler import wrap_crew
    from zespan import GuardrailBlockedError

    crew = wrap_crew(crew, guardrails=True)

    try:
        result = crew.kickoff(inputs={"topic": "..."})
    except GuardrailBlockedError as e:
        print(f"Blocked at {e.phase}:", e.results)
    ```

    For fine-grained control:

    ```python theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    crew = wrap_crew(crew, guardrails={
        "pre": True,
        "post": True,
        "fail_closed": False,
    })
    ```
  </Tab>

  <Tab title="TypeScript">
    CrewAI is a Python framework. For Node.js services that receive HTTP calls from a Python CrewAI agent, use context extraction to continue the trace across the boundary.

    ```typescript theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    import { extractAgentContext, zespan } from "@zespan/sdk";
    import { type NextRequest } from "next/server";

    zespan.init({ apiKey: process.env.ZESPAN_API_KEY! });

    export async function POST(req: NextRequest) {
      // Restore trace context injected by the upstream CrewAI agent
      extractAgentContext(Object.fromEntries(req.headers));

      // All LLM calls made here now link back to the CrewAI trace
      const result = await processRequest(req);
      return Response.json(result);
    }
    ```
  </Tab>
</Tabs>
