feat(agentcore): add AgentCoreRuntime adapter for deploying CrewAI crews#4887
feat(agentcore): add AgentCoreRuntime adapter for deploying CrewAI crews#4887kevin-orellana wants to merge 1 commit intocrewAIInc:mainfrom
Conversation
Code reviewFound 1 issue:
crewAI/lib/crewai-tools/src/crewai_tools/aws/bedrock/runtime/base.py Lines 130 to 140 in 5233ce2 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
5233ce2 to
51bd19d
Compare
…ews to AWS Bedrock AgentCore Add runtime adapter that wraps BedrockAgentCoreApp to serve CrewAI Crew instances via POST /invocations and GET /ping endpoints. - One-liner deployment: AgentCoreRuntime.serve(crew) - Streaming support via CrewAI's StreamChunk → SSE events - Accepts both CrewAI inputs dict and simple prompt/message/input payloads - Full BedrockAgentCoreApp constructor passthrough (debug, lifespan, middleware) - Rich response with tasks_output, token_usage, and json_dict when available
51bd19d to
48d324d
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| result = await loop.run_in_executor( | ||
| None, lambda: self._crew.kickoff(inputs=inputs) | ||
| ) | ||
| return self._crew_output_to_dict(result) |
There was a problem hiding this comment.
Non-streaming handler has race condition on shared crew
High Severity
_non_streaming_handler calls self._crew.kickoff() directly on the shared Crew instance via run_in_executor, but kickoff() extensively mutates the crew — prepare_kickoff sets _inputs, _kickoff_event_id, interpolates inputs into tasks/agents in-place, resets the task output handler, and more. Under concurrent HTTP requests, multiple thread pool workers will mutate the same instance simultaneously, causing data corruption. The streaming handler correctly avoids this with self._crew.copy(), but the non-streaming handler lacks the same protection.


Summary
Add
AgentCoreRuntimeadapter tocrewai-toolsfor deploying CrewAI Crew instances to AWS Bedrock AgentCore Runtime.BedrockAgentCoreAppfrom thebedrock-agentcoreSDK, providingPOST /invocationsandGET /pingendpointsAgentCoreRuntime.serve(crew)StreamChunkevents (text + tool calls) to SSEcrew.copy()per streaming request to avoid mutating shared stateinputsdict and simpleprompt/message/inputpayloadsBedrockAgentCoreAppconstructor passthrough:debug,lifespan,middlewaretasks_output,token_usage, andjson_dictwhen availablecrewai_tools.aws.bedrockfor top-level accessTarget API
SSE Event Mapping
StreamChunk(TEXT){"event": "text"}content,agent_role,task_nameStreamChunk(TOOL_CALL){"event": "tool_call"}tool_name,arguments,agent_role,task_nameCrewOutput{"event": "done"}response,tasks_output,token_usage,json{"event": "error"}messageFiles changed
bedrock/__init__.pyAgentCoreRuntimeruntime/__init__.pyruntime/base.pyAgentCoreRuntimeclass (~245 lines)tests/tools/test_agentcore_runtime.pytests/tools/test_agentcore_runtime_e2e.pyTest plan
58 tests total — all passing.
Unit tests (49)
inputsdict,prompt/message/inputkeys, nested dict, priority order, missing/empty/whitespace/list raises 400, numeric coercion, float coercion, whitespace stripping, empty prompt falls to message, non-dict inputs falls to prompt.resultfalls back toget_full_text(), error during chunk iteration yields error event_stream_chunk_to_dict(4): text chunk, tool call chunk, TOOL_CALL with None tool_call falls to text, None tool_name defaults to empty string_crew_output_to_dict(7): basic output, json_dict included, empty json_dict excluded, empty tasks excluded, None token_usage excluded, missing task attrs default to empty, missing usage fields default to 0run()passthrough (2): port/host forwarded to app, extra kwargs forwardedcrewai_tools.aws.bedrockfrom crewai_tools.aws.bedrock import AgentCoreRuntimeASGI integration tests (9)
Full HTTP round-trip via
httpx.ASGITransport— no real server or AWS credentials needed:GET /pingreturns 200prompt,message,input,inputsdict keys all return 200 with response; missing prompt returns 400; empty payload returns 400