From 5642132c0c615ecd0984d5e9c45ef6076ccc69d2 Mon Sep 17 00:00:00 2001 From: Sypherd <50557586+Sypherd@users.noreply.github.com> Date: Tue, 19 Dec 2023 23:17:23 -0700 Subject: [PATCH] community[patch]: Add safe lookup to OpenAI response adapter (#14765) ## Description Similar to https://github.com/langchain-ai/langchain/issues/5861, I've experienced `KeyError`s resulting from unsafe lookups in the `convert_dict_to_message` function in [this file](https://github.com/langchain-ai/langchain/blob/master/libs/community/langchain_community/adapters/openai.py). While that issue focused on `KeyError 'content'`, I've opened another issue (#14764) about how the problem still exists in the same function but with `KeyError 'role'`. The fix for #5861 only added a safe lookup to the specific line that was giving them trouble.. This PR fixes the unsafe lookup in the rest of the function but the problem still exists across the repo. ## Issues * #14764 * #5861 ## Dependencies * None ## Checklist [x] make format [x] make lint [ ] make test - Results in `make: *** No rule to make target 'test'. Stop.` ## Maintainers * @hinthornw --------- Co-authored-by: Bagatur --- .../langchain_community/adapters/openai.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libs/community/langchain_community/adapters/openai.py b/libs/community/langchain_community/adapters/openai.py index fbdf84be65..4f03c3a9c4 100644 --- a/libs/community/langchain_community/adapters/openai.py +++ b/libs/community/langchain_community/adapters/openai.py @@ -71,34 +71,34 @@ def convert_dict_to_message(_dict: Mapping[str, Any]) -> BaseMessage: Returns: The LangChain message. """ - role = _dict["role"] + role = _dict.get("role") if role == "user": - return HumanMessage(content=_dict["content"]) + return HumanMessage(content=_dict.get("content", "")) elif role == "assistant": # Fix for azure # Also OpenAI returns None for tool invocations content = _dict.get("content", "") or "" additional_kwargs: Dict = {} - if _dict.get("function_call"): - additional_kwargs["function_call"] = dict(_dict["function_call"]) - if _dict.get("tool_calls"): - additional_kwargs["tool_calls"] = _dict["tool_calls"] + if function_call := _dict.get("function_call"): + additional_kwargs["function_call"] = dict(function_call) + if tool_calls := _dict.get("tool_calls"): + additional_kwargs["tool_calls"] = tool_calls return AIMessage(content=content, additional_kwargs=additional_kwargs) elif role == "system": - return SystemMessage(content=_dict["content"]) + return SystemMessage(content=_dict.get("content", "")) elif role == "function": - return FunctionMessage(content=_dict["content"], name=_dict["name"]) + return FunctionMessage(content=_dict.get("content", ""), name=_dict.get("name")) elif role == "tool": additional_kwargs = {} if "name" in _dict: additional_kwargs["name"] = _dict["name"] return ToolMessage( - content=_dict["content"], - tool_call_id=_dict["tool_call_id"], + content=_dict.get("content", ""), + tool_call_id=_dict.get("tool_call_id"), additional_kwargs=additional_kwargs, ) else: - return ChatMessage(content=_dict["content"], role=role) + return ChatMessage(content=_dict.get("content", ""), role=role) def convert_message_to_dict(message: BaseMessage) -> dict: