Skip to content

Commit 2f84ea9

Browse files
mxmzbclaude
andcommitted
fix(sdk-python): harden crewai tool_call dict access and normalize content handling
Use defensive .get() for tool_call id/name/arguments to prevent KeyError on malformed input. Standardize content null-handling to `is not None` (matching langgraph.py) instead of `or ""` which silently coerces falsy values. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 25cc48b commit 2f84ea9

1 file changed

Lines changed: 14 additions & 8 deletions

File tree

sdk-python/copilotkit/crewai/crewai_sdk.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -552,10 +552,13 @@ def crewai_flow_messages_to_copilotkit(messages: List[Dict]) -> List[Message]: #
552552
if "content" in message and message.get("role") == "assistant":
553553
if message.get("tool_calls"):
554554
for tool_call in message["tool_calls"]:
555+
tc_id = tool_call.get("id")
556+
if tc_id is None:
557+
continue
555558
if tool_call.get("function"):
556-
tool_call_names[tool_call["id"]] = tool_call["function"]["name"]
559+
tool_call_names[tc_id] = tool_call["function"].get("name", "")
557560
else:
558-
tool_call_names[tool_call["id"]] = tool_call.get("name", "")
561+
tool_call_names[tc_id] = tool_call.get("name", "")
559562

560563
for message in messages:
561564
message_id = message_ids[id(message)]
@@ -573,22 +576,25 @@ def crewai_flow_messages_to_copilotkit(messages: List[Dict]) -> List[Message]: #
573576
# orphans tool calls and breaks frontend thread reconstruction.
574577
result.append({
575578
"role": message["role"],
576-
"content": message.get("content") or "",
579+
"content": message.get("content") if message.get("content") is not None else "",
577580
"id": message_id,
578581
})
579582
for tool_call in message["tool_calls"]:
583+
tc_id = tool_call.get("id")
584+
if tc_id is None:
585+
continue
580586
if tool_call.get("function"):
581587
result.append({
582-
"id": tool_call["id"],
583-
"name": tool_call["function"]["name"],
588+
"id": tc_id,
589+
"name": tool_call["function"].get("name", ""),
584590
"arguments": json.loads(tool_call["function"]["arguments"]),
585591
"parentMessageId": message_id,
586592
})
587593
else:
588594
result.append({
589-
"id": tool_call["id"],
590-
"name": tool_call["name"],
591-
"arguments": tool_call["arguments"],
595+
"id": tc_id,
596+
"name": tool_call.get("name", ""),
597+
"arguments": tool_call.get("arguments", {}),
592598
"parentMessageId": message_id,
593599
})
594600
elif message.get("content"):

0 commit comments

Comments
 (0)