Files
openchamber/packages/ui/src/components/chat/message/partUtils.ts
T

70 lines
2.2 KiB
TypeScript
Raw Normal View History

2026-01-03 13:39:59 +02:00
import type { Part } from '@opencode-ai/sdk/v2';
2025-12-07 19:32:53 +02:00
type PartWithText = Part & { text?: string; content?: string; value?: string };
const isValidPart = (part: unknown): part is Part => {
2026-05-01 15:08:44 +03:00
return Boolean(part && typeof part === 'object' && typeof (part as { type?: unknown }).type === 'string');
};
export const normalizeParts = (parts: Part[]): Part[] => {
return parts.filter(isValidPart);
};
2025-12-07 19:32:53 +02:00
export const extractTextContent = (part: Part): string => {
const partWithText = part as PartWithText;
const rawText = partWithText.text;
if (typeof rawText === 'string') {
return rawText;
}
return partWithText.content || partWithText.value || '';
};
export const isEmptyTextPart = (part: Part): boolean => {
if (part.type !== 'text') {
return false;
}
const text = extractTextContent(part);
return !text || text.trim().length === 0;
};
type PartWithSynthetic = Part & { synthetic?: boolean };
interface VisibleFilterOptions {
includeReasoning?: boolean;
}
export const filterVisibleParts = (parts: Part[], options: VisibleFilterOptions = {}): Part[] => {
const { includeReasoning = true } = options;
2026-05-01 15:08:44 +03:00
const validParts = normalizeParts(parts);
2025-12-07 19:32:53 +02:00
// Check if there are any non-synthetic parts
2026-05-01 15:08:44 +03:00
const hasNonSynthetic = validParts.some((part) => {
const partWithSynthetic = part as PartWithSynthetic;
return !partWithSynthetic.synthetic;
});
2026-05-01 15:08:44 +03:00
return validParts.filter((part) => {
2025-12-07 19:32:53 +02:00
const partWithSynthetic = part as PartWithSynthetic;
const isSynthetic = Boolean(partWithSynthetic.synthetic);
if (isSynthetic && part.type === 'text') {
const text = extractTextContent(part);
if (text.includes('<system-reminder>')) {
return false;
}
}
// Only filter out synthetic parts if there are non-synthetic parts present
// Otherwise, show synthetic parts so the message is displayed
if (isSynthetic && hasNonSynthetic) {
2025-12-07 19:32:53 +02:00
return false;
}
if (!includeReasoning && part.type === 'reasoning') {
return false;
}
const isPatchPart = part.type === 'patch';
return !isPatchPart;
});
};