Skip to content

Commit d4dd9af

Browse files
committed
add test for responses; fix code path for default/openai to be the proper responses api one
1 parent d7849f3 commit d4dd9af

File tree

4 files changed

+877
-16
lines changed

4 files changed

+877
-16
lines changed

codex-cli/src/utils/agent/agent-loop.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
ResponseFunctionToolCall,
66
ResponseInputItem,
77
ResponseItem,
8+
ResponseCreateParams,
89
} from "openai/resources/responses/responses.mjs";
910
import type { Reasoning } from "openai/resources.mjs";
1011

@@ -521,8 +522,18 @@ export class AgentLoop {
521522
);
522523
}
523524

525+
const responseCall =
526+
!this.config.provider ||
527+
this.config.provider?.toLowerCase() === "openai"
528+
? (params: ResponseCreateParams) =>
529+
this.oai.responses.create(params)
530+
: (params: ResponseCreateParams) =>
531+
responsesCreateViaChatCompletions(
532+
this.oai,
533+
params as ResponseCreateParams & { stream: true },
534+
);
524535
// eslint-disable-next-line no-await-in-loop
525-
stream = await responsesCreateViaChatCompletions(this.oai, {
536+
stream = await responseCall({
526537
model: this.model,
527538
instructions: mergedInstructions,
528539
previous_response_id: lastResponseId || undefined,

codex-cli/src/utils/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ export const saveConfig = (
396396
const ext = extname(targetPath).toLowerCase();
397397
// Create the config object to save
398398
const configToSave: StoredConfig = {
399-
model: config.model, provider: config.provider
399+
model: config.model,
400+
provider: config.provider,
400401
};
401402

402403
// Add history settings if they exist

codex-cli/src/utils/responses.ts

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ async function nonStreamResponses(
208208
const fullMessages = getFullMessages(input);
209209
const chatTools = convertTools(input.tools);
210210
const webSearchOptions = input.tools?.some(
211-
(tool) => tool.type === "builtin" && tool.name === "web_search",
211+
(tool) => tool.type === "function" && tool.name === "web_search",
212212
)
213213
? {}
214214
: undefined;
@@ -220,7 +220,6 @@ async function nonStreamResponses(
220220
web_search_options: webSearchOptions,
221221
temperature: input.temperature,
222222
top_p: input.top_p,
223-
stream: false,
224223
store: input.store,
225224
user: input.user,
226225
metadata: input.metadata,
@@ -240,28 +239,38 @@ async function nonStreamResponses(
240239
const responseId = generateId("resp");
241240
const outputItemId = generateId("msg");
242241
const outputContent: Array<any> = [];
243-
if (assistantMessage.tool_calls) {
244-
outputContent.push(
245-
...assistantMessage.tool_calls.map((toolCall) => ({
246-
type: "function_call",
247-
call_id: toolCall.id,
248-
name: toolCall.function.name,
249-
arguments: toolCall.function.arguments,
250-
})),
251-
);
242+
243+
// Check if the response contains tool calls
244+
const hasFunctionCalls =
245+
assistantMessage.tool_calls && assistantMessage.tool_calls.length > 0;
246+
247+
if (hasFunctionCalls) {
248+
for (const toolCall of assistantMessage.tool_calls) {
249+
if (toolCall.type === "function") {
250+
outputContent.push({
251+
type: "function_call",
252+
call_id: toolCall.id,
253+
name: toolCall.function.name,
254+
arguments: toolCall.function.arguments,
255+
});
256+
}
257+
}
252258
}
259+
253260
if (assistantMessage.content) {
254261
outputContent.push({
255262
type: "output_text",
256263
text: assistantMessage.content,
257264
annotations: [],
258265
});
259266
}
260-
const responseOutput: ResponseOutput = {
267+
268+
// Create response with appropriate status and properties
269+
const responseOutput = {
261270
id: responseId,
262271
object: "response",
263272
created_at: Math.floor(Date.now() / 1000),
264-
status: "completed",
273+
status: hasFunctionCalls ? "requires_action" : "completed",
265274
error: null,
266275
incomplete_details: null,
267276
instructions: null,
@@ -297,7 +306,24 @@ async function nonStreamResponses(
297306
: null,
298307
user: input.user ?? null,
299308
metadata: input.metadata ?? {},
300-
};
309+
} as ResponseOutput;
310+
311+
// Add required_action property for tool calls
312+
if (hasFunctionCalls) {
313+
(responseOutput as any).required_action = {
314+
type: "submit_tool_outputs",
315+
submit_tool_outputs: {
316+
tool_calls: assistantMessage.tool_calls.map((toolCall) => ({
317+
id: toolCall.id,
318+
type: toolCall.type,
319+
function: {
320+
name: toolCall.function.name,
321+
arguments: toolCall.function.arguments,
322+
},
323+
})),
324+
},
325+
};
326+
}
301327

302328
// Store history
303329
const newHistory = [...fullMessages, assistantMessage];

0 commit comments

Comments
 (0)