Skip to content

Commit e2bc89f

Browse files
committed
Reduce finish_reason reliance
Non-auto tool choices will result in a finish_reason of "stop" rather than "tool_calls". The current code assumes "stop" means there are no tool calls to be made when this isn't true. Instead, it should simply check for any available tool calls. Alongside, the last message in a chat completion stream isn't guaranteed to have the finish_reason. Instead we should check for any reasons to stop as we collect chunks and then use that at the end.
1 parent dd43d73 commit e2bc89f

File tree

2 files changed

+12
-22
lines changed

2 files changed

+12
-22
lines changed

mcp_bridge/openai_clients/chatCompletion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ async def chat_completions(
5050
request.messages.append(msg)
5151

5252
logger.debug(f"finish reason: {response.choices[0].finish_reason}")
53-
if response.choices[0].finish_reason.value in ["stop", "length"]:
53+
if response.choices[0].finish_reason == "length" or not response.choices[0].message.tool_calls:
5454
logger.debug("no tool calls found")
5555
return response
5656

mcp_bridge/openai_clients/streamChatCompletion.py

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ async def chat_completions(request: CreateChatCompletionRequest, http_request: R
5252

5353
# logger.debug(json_data)
5454

55-
last: Optional[CreateChatCompletionStreamResponse] = None # last message
56-
55+
tool_call: bool = False
5756
tool_call_name: str = ""
5857
tool_call_json: str = ""
5958
should_forward: bool = True
@@ -113,20 +112,16 @@ async def chat_completions(request: CreateChatCompletionRequest, http_request: R
113112
content = content if content is not None else ""
114113
response_content += content
115114

116-
# handle stop reasons
117-
if len(parsed_data.choices) > 0 and parsed_data.choices[0].finish_reason is not None:
118-
if parsed_data.choices[0].finish_reason.value in [
119-
"stop",
120-
"length",
121-
]:
122-
fully_done = True
123-
else:
124-
should_forward = False
115+
# handle stopping for length
116+
if len(parsed_data.choices) > 0 and parsed_data.choices[0].finish_reason == "length":
117+
fully_done = True
125118

126119
# this manages the incoming tool call schema
127120
# most of this is assertions to please mypy
128-
if len(parsed_data.choices) > 0 and parsed_data.choices[0].delta.tool_calls is not None:
121+
if len(parsed_data.choices) > 0 and parsed_data.choices[0].delta.tool_calls:
129122
should_forward = False
123+
tool_call = True
124+
130125
assert (
131126
parsed_data.choices[0].delta.tool_calls[0].function is not None
132127
)
@@ -149,19 +144,14 @@ async def chat_completions(request: CreateChatCompletionRequest, http_request: R
149144
logger.debug("forwarding message")
150145
yield SSEData.model_validate_json(sse.data).model_dump_json()
151146

152-
# save the last message
153-
last = parsed_data
154-
155-
# ideally we should check this properly
156-
assert last is not None
157-
if len(last.choices) > 0:
158-
assert last.choices[0].finish_reason is not None
159-
160-
if len(last.choices) > 0 and last.choices[0].finish_reason.value in ["stop", "length"]:
147+
if fully_done or tool_call == False:
161148
logger.debug("no tool calls found")
162149
fully_done = True
163150
continue
164151

152+
# Tool call was found, therefore we aren't done yet
153+
fully_done = False
154+
165155
logger.debug("tool calls found")
166156
logger.debug(
167157
f"{tool_call_name=} {tool_call_json=}"

0 commit comments

Comments
 (0)