Skip to content

Commit 247a594

Browse files
committed
chore(llm): only support stream true test
1 parent 091e25d commit 247a594

File tree

1 file changed

+88
-5
lines changed

1 file changed

+88
-5
lines changed

apps/agent-tars/src/main/llmProvider/providers/AzureOpenAIProvider.ts

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import OpenAI, { AzureOpenAI } from 'openai';
22
import { Message, ToolCall } from '@agent-infra/shared';
3-
import { ChatCompletionTool } from 'openai/resources';
3+
import { ChatCompletionChunk, ChatCompletionTool } from 'openai/resources';
44

55
import { BaseProvider } from './BaseProvider';
66
import { LLMConfig, LLMResponse, ToolChoice } from '../interfaces/LLMProvider';
@@ -111,6 +111,7 @@ export class AzureOpenAIProvider extends BaseProvider {
111111
{
112112
model: this.model,
113113
messages: formattedMessages,
114+
stream: true,
114115
temperature: this.config.temperature,
115116
max_tokens: this.config.maxTokens,
116117
top_p: this.config.topP,
@@ -126,7 +127,21 @@ export class AzureOpenAIProvider extends BaseProvider {
126127
throw new Error('Request aborted');
127128
}
128129
this.cleanupRequest(requestId);
129-
return response.choices[0].message.content || '';
130+
131+
let content = '';
132+
for await (const event of response) {
133+
if (event.choices[0].finish_reason) {
134+
break;
135+
}
136+
const token =
137+
event.choices[0].delta.content ||
138+
// @ts-ignore
139+
event.choices[0].delta?.reasoning_content ||
140+
'';
141+
content += token;
142+
}
143+
144+
return content || '';
130145
} catch (error: any) {
131146
this.cleanupRequest(requestId);
132147
if (error.name === 'AbortError' || error.message.includes('aborted')) {
@@ -161,6 +176,7 @@ export class AzureOpenAIProvider extends BaseProvider {
161176
messages: formattedMessages,
162177
temperature: this.config.temperature,
163178
max_tokens: this.config.maxTokens,
179+
stream: true,
164180
tools,
165181
tool_choice: toolChoice,
166182
top_p: this.config.topP,
@@ -177,9 +193,76 @@ export class AzureOpenAIProvider extends BaseProvider {
177193
}
178194

179195
this.cleanupRequest(requestId);
180-
const content = response.choices[0].message.content;
181-
const toolCalls = this.processToolCalls(response);
182-
return { content, tool_calls: toolCalls };
196+
197+
let fullContent = '';
198+
const toolCallsMap = new Map<
199+
number,
200+
{
201+
id: string;
202+
type: string;
203+
function: {
204+
name: string;
205+
arguments: string;
206+
};
207+
}
208+
>();
209+
210+
for await (const chunk of response) {
211+
console.log('chunk', JSON.stringify(chunk));
212+
const delta = chunk.choices[0]?.delta;
213+
214+
if (delta?.content) {
215+
// @ts-ignore
216+
fullContent += delta.content || delta?.reasoning_content;
217+
}
218+
219+
if (delta?.tool_calls) {
220+
for (const toolCall of delta.tool_calls) {
221+
const index = toolCall.index;
222+
const existing = toolCallsMap.get(index) || {
223+
id: '',
224+
type: 'function',
225+
function: {
226+
name: '',
227+
arguments: '',
228+
},
229+
};
230+
231+
if (toolCall.id) {
232+
existing.id = toolCall.id;
233+
}
234+
235+
if (toolCall.function?.name) {
236+
existing.function.name += toolCall.function.name;
237+
}
238+
239+
if (toolCall.function?.arguments) {
240+
existing.function.arguments += toolCall.function.arguments;
241+
}
242+
243+
toolCallsMap.set(index, existing);
244+
}
245+
}
246+
}
247+
248+
const tool_calls = Array.from(toolCallsMap.values());
249+
250+
const simulatedResponse: OpenAI.Chat.ChatCompletion = {
251+
choices: [
252+
{
253+
message: {
254+
content: fullContent,
255+
// @ts-ignore
256+
tool_calls: tool_calls.length > 0 ? tool_calls : [],
257+
},
258+
finish_reason: tool_calls.length > 0 ? 'tool_calls' : 'stop',
259+
},
260+
],
261+
};
262+
263+
const toolCalls = this.processToolCalls(simulatedResponse);
264+
console.log('toolCalls', toolCalls);
265+
return { content: fullContent, tool_calls: toolCalls };
183266
} catch (error: any) {
184267
this.cleanupRequest(requestId);
185268
if (error.name === 'AbortError' || error.message.includes('aborted')) {

0 commit comments

Comments
 (0)