Skip to content

Commit 4f9bc49

Browse files
committed
refactor: extract processToolCalls helper to reduce duplication
Consolidates the duplicated tool call processing logic from createMessage() and handleStreamResponse() into a single private helper method. This improves maintainability and ensures consistent behavior across both code paths.
1 parent ae85d1b commit 4f9bc49

File tree

1 file changed

+42
-47
lines changed

1 file changed

+42
-47
lines changed

src/api/providers/openai.ts

Lines changed: 42 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -213,29 +213,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
213213
}
214214
}
215215

216-
if (delta.tool_calls) {
217-
for (const toolCall of delta.tool_calls) {
218-
if (toolCall.id) {
219-
activeToolCallIds.add(toolCall.id)
220-
}
221-
yield {
222-
type: "tool_call_partial",
223-
index: toolCall.index,
224-
id: toolCall.id,
225-
name: toolCall.function?.name,
226-
arguments: toolCall.function?.arguments,
227-
}
228-
}
229-
}
230-
231-
// Emit tool_call_end events when finish_reason is "tool_calls"
232-
// This ensures tool calls are finalized even if the stream doesn't properly close
233-
if (finishReason === "tool_calls" && activeToolCallIds.size > 0) {
234-
for (const id of activeToolCallIds) {
235-
yield { type: "tool_call_end", id }
236-
}
237-
activeToolCallIds.clear()
238-
}
216+
yield* this.processToolCalls(delta, finishReason, activeToolCallIds)
239217

240218
if (chunk.usage) {
241219
lastUsage = chunk.usage
@@ -471,30 +449,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
471449
}
472450
}
473451

474-
// Emit raw tool call chunks - NativeToolCallParser handles state management
475-
if (delta.tool_calls) {
476-
for (const toolCall of delta.tool_calls) {
477-
if (toolCall.id) {
478-
activeToolCallIds.add(toolCall.id)
479-
}
480-
yield {
481-
type: "tool_call_partial",
482-
index: toolCall.index,
483-
id: toolCall.id,
484-
name: toolCall.function?.name,
485-
arguments: toolCall.function?.arguments,
486-
}
487-
}
488-
}
489-
}
490-
491-
// Emit tool_call_end events when finish_reason is "tool_calls"
492-
// This ensures tool calls are finalized even if the stream doesn't properly close
493-
if (finishReason === "tool_calls" && activeToolCallIds.size > 0) {
494-
for (const id of activeToolCallIds) {
495-
yield { type: "tool_call_end", id }
496-
}
497-
activeToolCallIds.clear()
452+
yield* this.processToolCalls(delta, finishReason, activeToolCallIds)
498453
}
499454

500455
if (chunk.usage) {
@@ -507,6 +462,46 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
507462
}
508463
}
509464

465+
/**
466+
* Helper generator to process tool calls from a stream chunk.
467+
* Tracks active tool call IDs and yields tool_call_partial and tool_call_end events.
468+
* @param delta - The delta object from the stream chunk
469+
* @param finishReason - The finish_reason from the stream chunk
470+
* @param activeToolCallIds - Set to track active tool call IDs (mutated in place)
471+
*/
472+
private *processToolCalls(
473+
delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta | undefined,
474+
finishReason: string | null | undefined,
475+
activeToolCallIds: Set<string>,
476+
): Generator<
477+
| { type: "tool_call_partial"; index: number; id?: string; name?: string; arguments?: string }
478+
| { type: "tool_call_end"; id: string }
479+
> {
480+
if (delta?.tool_calls) {
481+
for (const toolCall of delta.tool_calls) {
482+
if (toolCall.id) {
483+
activeToolCallIds.add(toolCall.id)
484+
}
485+
yield {
486+
type: "tool_call_partial",
487+
index: toolCall.index,
488+
id: toolCall.id,
489+
name: toolCall.function?.name,
490+
arguments: toolCall.function?.arguments,
491+
}
492+
}
493+
}
494+
495+
// Emit tool_call_end events when finish_reason is "tool_calls"
496+
// This ensures tool calls are finalized even if the stream doesn't properly close
497+
if (finishReason === "tool_calls" && activeToolCallIds.size > 0) {
498+
for (const id of activeToolCallIds) {
499+
yield { type: "tool_call_end", id }
500+
}
501+
activeToolCallIds.clear()
502+
}
503+
}
504+
510505
protected _getUrlHost(baseUrl?: string): string {
511506
try {
512507
return new URL(baseUrl ?? "").host

0 commit comments

Comments
 (0)