Skip to content

Commit 7bef5a7

Browse files
ringlochidsteipete
authored andcommitted
Fix commentary/final answer phase separation
1 parent b8e2e5c commit 7bef5a7

10 files changed

Lines changed: 1568 additions & 54 deletions

src/agents/openai-ws-message-conversion.ts

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -349,18 +349,30 @@ export function convertMessagesToInputItems(
349349

350350
if (m.role === "assistant") {
351351
const content = m.content;
352-
let assistantPhase = normalizeAssistantPhase(m.phase);
352+
const assistantMessagePhase = normalizeAssistantPhase(m.phase);
353353
if (Array.isArray(content)) {
354354
const textParts: string[] = [];
355-
const pushAssistantText = () => {
355+
let currentTextPhase: OpenAIResponsesAssistantPhase | undefined;
356+
const hasExplicitBlockPhase = content.some((block) => {
357+
if (!block || typeof block !== "object") {
358+
return false;
359+
}
360+
const record = block as { type?: unknown; textSignature?: unknown };
361+
return (
362+
record.type === "text" &&
363+
Boolean(parseAssistantTextSignature(record.textSignature)?.phase)
364+
);
365+
});
366+
367+
const pushAssistantText = (phase?: OpenAIResponsesAssistantPhase) => {
356368
if (textParts.length === 0) {
357369
return;
358370
}
359371
items.push({
360372
type: "message",
361373
role: "assistant",
362374
content: textParts.join(""),
363-
...(assistantPhase ? { phase: assistantPhase } : {}),
375+
...(phase ? { phase } : {}),
364376
});
365377
textParts.length = 0;
366378
};
@@ -376,15 +388,18 @@ export function convertMessagesToInputItems(
376388
}>) {
377389
if (block.type === "text" && typeof block.text === "string") {
378390
const parsedSignature = parseAssistantTextSignature(block.textSignature);
379-
if (!assistantPhase) {
380-
assistantPhase = parsedSignature?.phase;
391+
const blockPhase =
392+
parsedSignature?.phase ?? (hasExplicitBlockPhase ? undefined : assistantMessagePhase);
393+
if (textParts.length > 0 && blockPhase !== currentTextPhase) {
394+
pushAssistantText(currentTextPhase);
381395
}
382396
textParts.push(block.text);
397+
currentTextPhase = blockPhase;
383398
continue;
384399
}
385400

386401
if (block.type === "thinking") {
387-
pushAssistantText();
402+
pushAssistantText(currentTextPhase);
388403
const reasoningItem = parseThinkingSignature(block.thinkingSignature);
389404
if (reasoningItem) {
390405
items.push(reasoningItem);
@@ -396,7 +411,7 @@ export function convertMessagesToInputItems(
396411
continue;
397412
}
398413

399-
pushAssistantText();
414+
pushAssistantText(currentTextPhase);
400415
const replayId = decodeToolCallReplayId(block.id);
401416
const toolName = toNonEmptyString(block.name);
402417
if (!replayId || !toolName) {
@@ -414,7 +429,7 @@ export function convertMessagesToInputItems(
414429
});
415430
}
416431

417-
pushAssistantText();
432+
pushAssistantText(currentTextPhase);
418433
continue;
419434
}
420435

@@ -426,7 +441,7 @@ export function convertMessagesToInputItems(
426441
type: "message",
427442
role: "assistant",
428443
content: text,
429-
...(assistantPhase ? { phase: assistantPhase } : {}),
444+
...(assistantMessagePhase ? { phase: assistantMessagePhase } : {}),
430445
});
431446
continue;
432447
}
@@ -471,16 +486,20 @@ export function buildAssistantMessageFromResponse(
471486
modelInfo: { api: string; provider: string; id: string },
472487
): AssistantMessage {
473488
const content: AssistantMessage["content"] = [];
474-
let assistantPhase: OpenAIResponsesAssistantPhase | undefined;
489+
const assistantPhases = new Set<OpenAIResponsesAssistantPhase>();
490+
let hasUnphasedAssistantText = false;
475491

476492
for (const item of response.output ?? []) {
477493
if (item.type === "message") {
478494
const itemPhase = normalizeAssistantPhase(item.phase);
479495
if (itemPhase) {
480-
assistantPhase = itemPhase;
496+
assistantPhases.add(itemPhase);
481497
}
482498
for (const part of item.content ?? []) {
483499
if (part.type === "output_text" && part.text) {
500+
if (!itemPhase) {
501+
hasUnphasedAssistantText = true;
502+
}
484503
content.push({
485504
type: "text",
486505
text: part.text,
@@ -553,7 +572,10 @@ export function buildAssistantMessageFromResponse(
553572
}),
554573
});
555574

556-
return assistantPhase
557-
? ({ ...message, phase: assistantPhase } as AssistantMessageWithPhase)
575+
const finalAssistantPhase =
576+
assistantPhases.size === 1 && !hasUnphasedAssistantText ? [...assistantPhases][0] : undefined;
577+
578+
return finalAssistantPhase
579+
? ({ ...message, phase: finalAssistantPhase } as AssistantMessageWithPhase)
558580
: message;
559581
}

0 commit comments

Comments
 (0)