| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /**
- * Centralized message state mutation utilities
- * Eliminates duplicate array cloning logic and type casting from MessagesProvider
- */
- import type { Message, WebguiPart, SDKMessage, TextPart } from "../types/messages"
- /**
- * Upsert a message (add new or update existing)
- */
- export function upsertMessage(messages: Message[], message: Message): Message[] {
- const index = messages.findIndex((m) => m.info.id === message.info.id)
- if (index >= 0) {
- const updated = [...messages]
- updated[index] = message
- return updated
- }
- return [...messages, message]
- }
- /**
- * Update message info while preserving parts
- */
- export function updateMessageInfo(messages: Message[], messageID: string, info: SDKMessage): Message[] {
- const index = messages.findIndex((m) => m.info.id === messageID)
- if (index >= 0) {
- const updated = [...messages]
- updated[index] = { ...updated[index], info }
- return updated
- }
- // Create new message if not found
- return [...messages, { info, parts: [] }]
- }
- /**
- * Update message with partial data
- */
- export function updateMessage(messages: Message[], messageID: string, update: Partial<Message>): Message[] {
- const index = messages.findIndex((m) => m.info.id === messageID)
- if (index < 0) return messages
- const updated = [...messages]
- updated[index] = { ...updated[index], ...update }
- return updated
- }
- /**
- * Remove a message by ID
- */
- export function removeMessage(messages: Message[], messageID: string): Message[] {
- return messages.filter((m) => m.info.id !== messageID)
- }
- /**
- * Upsert a part in a message (add new or update existing)
- */
- export function upsertPart(messages: Message[], messageID: string, part: WebguiPart): Message[] {
- const messageIndex = messages.findIndex((m) => m.info.id === messageID)
- if (messageIndex < 0) return messages
- const updated = [...messages]
- const message = updated[messageIndex]
- const partIndex = message.parts.findIndex((p) => p.id === part.id)
- if (partIndex >= 0) {
- // Update existing part
- const updatedParts = [...message.parts]
- updatedParts[partIndex] = part
- updated[messageIndex] = { ...message, parts: updatedParts }
- } else {
- // Add new part
- updated[messageIndex] = { ...message, parts: [...message.parts, part] }
- }
- return updated
- }
- /**
- * Apply a text delta to a part (for streaming)
- */
- export function applyPartDelta(messages: Message[], messageID: string, part: WebguiPart, delta: string): Message[] {
- if (part.type !== "text") {
- // For non-text parts, just upsert normally
- return upsertPart(messages, messageID, part)
- }
- const messageIndex = messages.findIndex((m) => m.info.id === messageID)
- if (messageIndex < 0) return messages
- const updated = [...messages]
- const message = updated[messageIndex]
- const partIndex = message.parts.findIndex((p) => p.id === part.id)
- if (partIndex >= 0) {
- // Append delta to existing text part
- const existingPart = message.parts[partIndex]
- if (existingPart.type === "text") {
- const updatedParts = [...message.parts]
- updatedParts[partIndex] = {
- ...existingPart,
- text: (existingPart.text || "") + delta,
- }
- updated[messageIndex] = { ...message, parts: updatedParts }
- }
- } else {
- // New part with delta as initial text
- const newPart: TextPart = { ...(part as TextPart), text: delta }
- updated[messageIndex] = { ...message, parts: [...message.parts, newPart] }
- }
- return updated
- }
- /**
- * Update a specific part in a message
- */
- export function updatePart(messages: Message[], messageID: string, partID: string, update: Partial<WebguiPart>): Message[] {
- const messageIndex = messages.findIndex((m) => m.info.id === messageID)
- if (messageIndex < 0) return messages
- const updated = [...messages]
- const message = updated[messageIndex]
- const partIndex = message.parts.findIndex((p) => p.id === partID)
- if (partIndex < 0) return messages
- const updatedParts = [...message.parts]
- updatedParts[partIndex] = { ...updatedParts[partIndex], ...update } as WebguiPart
- updated[messageIndex] = { ...message, parts: updatedParts }
- return updated
- }
- /**
- * Remove a part from a message
- */
- export function removePart(messages: Message[], messageID: string, partID: string): Message[] {
- const messageIndex = messages.findIndex((m) => m.info.id === messageID)
- if (messageIndex < 0) return messages
- const updated = [...messages]
- const message = updated[messageIndex]
- updated[messageIndex] = {
- ...message,
- parts: message.parts.filter((p) => p.id !== partID),
- }
- return updated
- }
- /**
- * Get messages for a specific session
- */
- export function getMessagesBySession(messages: Message[], sessionID: string): Message[] {
- return messages.filter((m) => m.info.sessionID === sessionID)
- }
|