diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index e9679c6..c129956 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -8,11 +8,15 @@ import { import { auth } from '@/app/(auth)/auth'; import { patternProvider } from '@/lib/ai/pattern-provider'; import { deleteChatById, getChatById } from '@/lib/db/queries'; -import { generateUUID, getMostRecentUserMessage } from '@/lib/utils'; +import { + extractErrorMessageOrDefault, + generateUUID, + getMostRecentUserMessage, +} from '@/lib/utils'; import { getOrCreateConversation } from '../../service'; -export const maxDuration = 60; +export const maxDuration = 300; export async function POST(request: Request) { const { id, messages }: { id: string; messages: Array } = @@ -70,8 +74,8 @@ export async function POST(request: Request) { sendReasoning: true, }); }, - onError: () => { - return 'Oops, an error occured!'; + onError: (error) => { + return extractErrorMessageOrDefault(error); }, }); } diff --git a/lib/ai/pattern-model.ts b/lib/ai/pattern-model.ts index ccde7ea..3770278 100644 --- a/lib/ai/pattern-model.ts +++ b/lib/ai/pattern-model.ts @@ -96,10 +96,19 @@ export class PatternModel implements LanguageModelV1 { * TODO: Re-enable reasoning when backend supports it * https://github.com/pattern-tech/pattern-app/issues/27 */ + } else if ( + event.type === 'completion' || + event.type === 'heartbeat' + ) { + /** + * Ignore heartbeat and completion events. Completion event is + * identified automatically when the stream is ended, and the + * heartbeat event is only for keeping the connection alive + */ } else { controller.enqueue({ type: 'error', - error: `Event type is not supported`, + error: `Event type "${(event as unknown as { type: string }).type}" is not supported`, }); } }); diff --git a/lib/ai/types.ts b/lib/ai/types.ts index 00529db..85d11f1 100644 --- a/lib/ai/types.ts +++ b/lib/ai/types.ts @@ -9,7 +9,21 @@ export interface ToolStartEvent { tool_input: Record; } -export type PatternStreamingResponseEvent = TokenEvent | ToolStartEvent; +export interface CompletionEvent { + type: 'completion'; + data: 'Stream completed'; +} + +export interface HeartbeatEvent { + type: 'heartbeat'; + data: 'still_processing'; +} + +export type PatternStreamingResponseEvent = + | TokenEvent + | ToolStartEvent + | CompletionEvent + | HeartbeatEvent; export interface PatternProviderMetadata { accessToken: string;