@@ -362,6 +362,45 @@ export function createEventHandlers(context: EventHandlerContext) {
|
362 | 362 | void loadHistory?.(); |
363 | 363 | }; |
364 | 364 | |
| 365 | +const messageHasDisplayableNonTextContent = (message: unknown): boolean => { |
| 366 | +if (!message || typeof message !== "object") { |
| 367 | +return false; |
| 368 | +} |
| 369 | +const record = message as Record<string, unknown>; |
| 370 | +if (typeof record.mediaUrl === "string" && record.mediaUrl.trim()) { |
| 371 | +return true; |
| 372 | +} |
| 373 | +if ( |
| 374 | +Array.isArray(record.mediaUrls) && |
| 375 | +record.mediaUrls.some((media) => typeof media === "string" && media.trim()) |
| 376 | +) { |
| 377 | +return true; |
| 378 | +} |
| 379 | +if (!Array.isArray(record.content)) { |
| 380 | +return false; |
| 381 | +} |
| 382 | +return record.content.some((block) => { |
| 383 | +if (!block || typeof block !== "object") { |
| 384 | +return false; |
| 385 | +} |
| 386 | +const type = (block as Record<string, unknown>).type; |
| 387 | +return typeof type === "string" && type !== "text" && type !== "thinking"; |
| 388 | +}); |
| 389 | +}; |
| 390 | + |
| 391 | +const hasDisplayableFinalEvent = (evt: ChatEvent): boolean => { |
| 392 | +if (typeof evt.errorMessage === "string" && evt.errorMessage.trim()) { |
| 393 | +return true; |
| 394 | +} |
| 395 | +if (!evt.message) { |
| 396 | +return false; |
| 397 | +} |
| 398 | +if (extractTextFromMessage(evt.message, { includeThinking: state.showThinking }).trim()) { |
| 399 | +return true; |
| 400 | +} |
| 401 | +return messageHasDisplayableNonTextContent(evt.message); |
| 402 | +}; |
| 403 | + |
365 | 404 | const isSameSessionKey = (left: string | undefined, right: string | undefined): boolean => { |
366 | 405 | const normalizedLeft = normalizeLowercaseStringOrEmpty(left); |
367 | 406 | const normalizedRight = normalizeLowercaseStringOrEmpty(right); |
@@ -400,7 +439,7 @@ export function createEventHandlers(context: EventHandlerContext) {
|
400 | 439 | } |
401 | 440 | if (evt.state === "final") { |
402 | 441 | const hasLateDisplayableFinal = |
403 | | -Boolean(evt.message) && !finalizedRunsWithDisplay.has(evt.runId); |
| 442 | +hasDisplayableFinalEvent(evt) && !finalizedRunsWithDisplay.has(evt.runId); |
404 | 443 | if (!hasLateDisplayableFinal) { |
405 | 444 | clearStaleStreamingIfNoTrackedRunRemains(); |
406 | 445 | return; |
|