feat: refactor message filtering to use filterSyntheticParts for improved clarity
This commit is contained in:
@@ -5,7 +5,7 @@ import ChatMessage from './ChatMessage';
|
|||||||
import { PermissionCard } from './PermissionCard';
|
import { PermissionCard } from './PermissionCard';
|
||||||
import type { Permission } from '@/types/permission';
|
import type { Permission } from '@/types/permission';
|
||||||
import type { AnimationHandlers, ContentChangeReason } from '@/hooks/useChatScrollManager';
|
import type { AnimationHandlers, ContentChangeReason } from '@/hooks/useChatScrollManager';
|
||||||
import { isFullySyntheticMessage } from '@/lib/messages/synthetic';
|
import { filterSyntheticParts } from '@/lib/messages/synthetic';
|
||||||
import { useTurnGrouping } from './hooks/useTurnGrouping';
|
import { useTurnGrouping } from './hooks/useTurnGrouping';
|
||||||
|
|
||||||
interface MessageListProps {
|
interface MessageListProps {
|
||||||
@@ -40,16 +40,21 @@ const MessageList: React.FC<MessageListProps> = ({
|
|||||||
|
|
||||||
const displayMessages = React.useMemo(() => {
|
const displayMessages = React.useMemo(() => {
|
||||||
const seenIds = new Set<string>();
|
const seenIds = new Set<string>();
|
||||||
return messages.filter((message) => {
|
return messages
|
||||||
const messageId = message.info?.id;
|
.filter((message) => {
|
||||||
if (typeof messageId === 'string') {
|
const messageId = message.info?.id;
|
||||||
if (seenIds.has(messageId)) {
|
if (typeof messageId === 'string') {
|
||||||
return false;
|
if (seenIds.has(messageId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seenIds.add(messageId);
|
||||||
}
|
}
|
||||||
seenIds.add(messageId);
|
return true;
|
||||||
}
|
})
|
||||||
return !isFullySyntheticMessage(message.parts);
|
.map((message) => ({
|
||||||
});
|
...message,
|
||||||
|
parts: filterSyntheticParts(message.parts),
|
||||||
|
}));
|
||||||
}, [messages]);
|
}, [messages]);
|
||||||
|
|
||||||
const { getContextForMessage } = useTurnGrouping(displayMessages);
|
const { getContextForMessage } = useTurnGrouping(displayMessages);
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
import type { Part } from "@opencode-ai/sdk";
|
import type { Part } from "@opencode-ai/sdk";
|
||||||
|
|
||||||
const isSyntheticPart = (part: Part | undefined): boolean => {
|
export const isSyntheticPart = (part: Part | undefined): boolean => {
|
||||||
if (!part || typeof part !== "object") {
|
if (!part || typeof part !== "object") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Boolean((part as { synthetic?: boolean }).synthetic);
|
return Boolean((part as { synthetic?: boolean }).synthetic);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a message consists entirely of synthetic parts.
|
||||||
|
* Used for status/completion logic (not display filtering).
|
||||||
|
*/
|
||||||
export const isFullySyntheticMessage = (parts: Part[] | undefined): boolean => {
|
export const isFullySyntheticMessage = (parts: Part[] | undefined): boolean => {
|
||||||
if (!Array.isArray(parts) || parts.length === 0) {
|
if (!Array.isArray(parts) || parts.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -14,3 +18,24 @@ export const isFullySyntheticMessage = (parts: Part[] | undefined): boolean => {
|
|||||||
|
|
||||||
return parts.every((part) => isSyntheticPart(part));
|
return parts.every((part) => isSyntheticPart(part));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters out synthetic parts from a message, but only if there are
|
||||||
|
* non-synthetic parts present. If all parts are synthetic, returns
|
||||||
|
* them as-is so the message can still be displayed.
|
||||||
|
*/
|
||||||
|
export const filterSyntheticParts = (parts: Part[] | undefined): Part[] => {
|
||||||
|
if (!Array.isArray(parts) || parts.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasNonSynthetic = parts.some((part) => !isSyntheticPart(part));
|
||||||
|
|
||||||
|
// If there are non-synthetic parts, filter out synthetic ones
|
||||||
|
if (hasNonSynthetic) {
|
||||||
|
return parts.filter((part) => !isSyntheticPart(part));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all parts are synthetic, return them all (so message is displayed)
|
||||||
|
return parts;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user