Skip to Content

CrewAI

CrewAI gets a governed native LLM object pointed at the Agent Fabric LLM proxy. The adapter translates the governed connection into CrewAI’s own model-string and kwarg conventions for you.

What you get

  • A native crewai.BaseLLM — concretely OpenAICompletion, CrewAI’s native OpenAI provider. crewai.LLM’s own __new__ factory routes an openai/-prefixed model with an explicit base_url to that provider rather than returning an LLM instance itself. The proxy auth and attribution headers are set.
  • The openai/ model prefix and CrewAI’s kwarg names handled automatically.
  • Supported at connection_kwargs(). CrewAI’s native provider builds its own HTTP client rather than using the SDK’s, so there is no run correlation ID and donkey.last_call is not populated (see Notes).

Install

pip install "donkey-kit[crewai]"

Quickstart

from donkey_kit.integrations.crewai import llm model = llm("gpt-4o")

model is a real crewai.BaseLLM instance (OpenAICompletion). The adapter prefixes the model string with openai/ (openai/gpt-4o) — you don’t add it yourself. That prefix, together with the proxy base_url, is what routes crewai.LLM’s factory to its native OpenAI provider; the provider strips the prefix again, so the proxy receives the bare model id (gpt-4o).

Three ways to construct

1. Off a shared Donkey instance:

from donkey_kit import Donkey async with Donkey.from_env() as donkey: model = donkey.crewai.llm("gpt-4o")

2. Module-level factory (shortest):

from donkey_kit.integrations.crewai import llm model = llm("gpt-4o")

3. Governed kwargs, native constructor:

from donkey_kit import Donkey from crewai import LLM async with Donkey.from_env() as donkey: model = LLM(model="openai/gpt-4o", **donkey.crewai.connection_kwargs())

Manual equivalent

from crewai import LLM model = LLM( model="openai/gpt-4o", base_url=..., # from DONKEY_LLM_PROXY_URL, no /v1 suffix api_key=..., extra_headers=..., # client_id / client_secret header pair max_retries=0, # don't let the OpenAI client retry a refusal )

connection_kwargs() fills in base_url, api_key, extra_headers (the client_id / client_secret header pair), and max_retries=0 for you. When CrewAI is installed it also adds an interceptor: with one set, CrewAI’s provider builds HTTP clients that don’t follow redirects, and the interceptor removes the credential headers from any request to an origin other than the proxy (see Credentials go only to checked endpoints). A base_url / api_base passed to llm() must pass the https:// rule.

Notes

  • No run correlation ID. CrewAI sends requests through its native OpenAI provider’s own HTTP client rather than the SDK’s shared one, so the correlation ID bound by donkey.run() doesn’t reach the request. The auth and attribution headers are still sent on every request. The conformance suite checks this as a documented behaviour.
  • jwt mode isn’t supported. The JWT is added only by the SDK’s shared client, which CrewAI’s provider doesn’t use, so donkey.crewai.llm() and connection_kwargs() raise ConfigError in jwt mode. Use client-id auth with CrewAI; see the jwt mode note.
  • A budget refusal is sent 3 times. CrewAI wraps every LLM call in its own rate-limit retry (3 attempts, with a 1s then 2s wait) and treats any 429 as a rate limit. On the proxy a 429 is a budget refusal, so CrewAI re-sends it twice before raising. CrewAI has no setting to turn this retry off. The OpenAI client underneath has max_retries=0, and transient 5xx errors are not retried at all, because the SDK’s transport isn’t used.
  • Printing the model shows the API key. OpenAICompletion’s own repr() / str() include api_key. Don’t print or log it.
  • donkey.last_call is unavailable. Because the response is handled by CrewAI’s own client, gateway identity, routing, and usage fields can’t be observed. When every adapter resolved on a Donkey is like this one, donkey.last_call reports status == LastCallStatus.UNAVAILABLE and available == False, and names the resolved adapters in surface.

See the error taxonomy for how proxy rejections surface through CrewAI.

Last updated on