Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions app/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ export const AI = createAI<AIState, UIState>({
userId: actualUserId,
path,
title,
messages: updatedMessages
messages: updatedMessages.filter(msg => !(msg.content === 'end' && msg.type === 'end'))
}
await saveChat(chat, actualUserId)
}
Expand Down Expand Up @@ -710,6 +710,8 @@ export const getUIStateFromAIState = (aiState: AIState): UIState => {
id,
component: <CopilotDisplay content={content as string} />
}
default:
return null
}
break
case 'assistant':
Expand Down Expand Up @@ -770,6 +772,8 @@ export const getUIStateFromAIState = (aiState: AIState): UIState => {
)
}
}
default:
return null
}
break
case 'tool':
Expand Down Expand Up @@ -868,5 +872,5 @@ export const getUIStateFromAIState = (aiState: AIState): UIState => {
}
}
})
.filter(message => message !== null) as UIState
.filter(message => message !== null && message !== undefined) as UIState
}
11 changes: 4 additions & 7 deletions app/search/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export async function generateMetadata({ params }: SearchPageProps) {
// TODO: Metadata generation might need authenticated user if chats are private
// For now, assuming getChat can be called or it handles anon access for metadata appropriately
const userId = await getCurrentUserIdOnServer(); // Attempt to get user for metadata
const chat = await getChat(id, userId || 'anonymous'); // Pass userId or 'anonymous' if none
const chat = await getChat(id, userId || undefined); // Pass userId or undefined if none (allows public fallback)
return {
title: chat?.title?.toString().slice(0, 50) || 'Search',
};
Expand Down Expand Up @@ -48,14 +48,11 @@ export default async function SearchPage({ params }: SearchPageProps) {
const initialMessages: AIMessage[] = dbMessages.map((dbMsg): AIMessage => {
return {
id: dbMsg.id,
role: dbMsg.role as AIMessage['role'], // Cast role, ensure AIMessage['role'] includes all dbMsg.role possibilities
role: dbMsg.role as AIMessage['role'],
content: dbMsg.content,
createdAt: dbMsg.createdAt ? new Date(dbMsg.createdAt) : undefined,
// 'type' and 'name' are not in the basic Drizzle 'messages' schema.
// These would be undefined unless specific logic is added to derive them.
// For instance, if a message with role 'tool' should have a 'name',
// or if some messages have a specific 'type' based on content or other flags.
// This mapping assumes standard user/assistant messages primarily.
type: dbMsg.type ? (dbMsg.type as AIMessage['type']) : undefined,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All existing messages rows get NULL for these newly added columns, and this migration neither backfills them nor derives legacy discriminators during rehydration. getUIStateFromAIState drops every message whose type is falsy, so opening any chat saved before this deployment produces an empty UI. Add a backward-compatible derivation/backfill before relying on dbMsg.type here.

name: dbMsg.name || undefined,
};
});

Expand Down
3 changes: 3 additions & 0 deletions drizzle/migrations/0009_add_message_type_name.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE "messages" ADD COLUMN "type" text;
--> statement-breakpoint
ALTER TABLE "messages" ADD COLUMN "name" text;
Loading