🛠️ fix: Restrict Editable Content Types & Consolidate Typing (#9173)

* fix: only allow editing expected content types & align typing app-wide

* chore: update TPayload to use TEditedContent type for editedContent
This commit is contained in:
Danny Avila 2025-08-20 13:21:47 -04:00 committed by GitHub
parent da4aa37493
commit 49cd3894aa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 18 deletions

View file

@ -336,6 +336,7 @@ export type TAskProps = {
export type TOptions = {
editedMessageId?: string | null;
editedContent?: t.TEditedContent;
editedText?: string | null;
isRegenerate?: boolean;
isContinued?: boolean;

View file

@ -94,6 +94,12 @@ const ContentParts = memo(
return null;
}
const isToolCall =
part.type === ContentTypes.TOOL_CALL || part['tool_call_ids'] != null;
if (isToolCall) {
return null;
}
return (
<EditTextPart
index={idx}

View file

@ -62,17 +62,26 @@ const EditTextPart = ({
const messages = getMessages();
const parentMessage = messages?.find((msg) => msg.messageId === message?.parentMessageId);
const editedContent =
part.type === ContentTypes.THINK
? {
index,
type: ContentTypes.THINK as const,
[ContentTypes.THINK]: data.text,
}
: {
index,
type: ContentTypes.TEXT as const,
[ContentTypes.TEXT]: data.text,
};
if (!parentMessage) {
return;
}
ask(
{ ...parentMessage },
{
editedContent: {
index,
text: data.text,
type: part.type,
},
editedContent,
editedMessageId: messageId,
isRegenerate: true,
isEdited: true,

View file

@ -267,13 +267,13 @@ export default function useChatFunctions({
if (editedContent && latestMessage?.content) {
initialResponse.content = cloneDeep(latestMessage.content);
const { index, text, type } = editedContent;
const { index, type, ...part } = editedContent;
if (initialResponse.content && index >= 0 && index < initialResponse.content.length) {
const contentPart = initialResponse.content[index];
if (type === ContentTypes.THINK && contentPart.type === ContentTypes.THINK) {
contentPart[ContentTypes.THINK] = text;
contentPart[ContentTypes.THINK] = part[ContentTypes.THINK];
} else if (type === ContentTypes.TEXT && contentPart.type === ContentTypes.TEXT) {
contentPart[ContentTypes.TEXT] = text;
contentPart[ContentTypes.TEXT] = part[ContentTypes.TEXT];
}
}
} else {

View file

@ -11,6 +11,7 @@ import type {
} from './schemas';
import type { SettingDefinition } from './generate';
import type { TMinimalFeedback } from './feedback';
import type { ContentTypes } from './types/runs';
import type { Agent } from './types/assistants';
export * from './schemas';
@ -108,11 +109,19 @@ export type TPayload = Partial<TMessage> &
messages?: TMessages;
isTemporary: boolean;
ephemeralAgent?: TEphemeralAgent | null;
editedContent?: {
editedContent?: TEditedContent | null;
};
export type TEditedContent =
| {
index: number;
text: string;
type: 'text' | 'think';
} | null;
type: ContentTypes.THINK;
[ContentTypes.THINK]: string;
}
| {
index: number;
type: ContentTypes.TEXT;
[ContentTypes.TEXT]: string;
};
export type TSubmission = {
@ -129,11 +138,7 @@ export type TSubmission = {
endpointOption: TEndpointOption;
clientTimestamp?: string;
ephemeralAgent?: TEphemeralAgent | null;
editedContent?: {
index: number;
text: string;
type: 'text' | 'think';
} | null;
editedContent?: TEditedContent | null;
};
export type EventSubmission = Omit<TSubmission, 'initialResponse'> & { initialResponse: TMessage };