From ef8ab06a7ac65b4fdbf8a3bc29ca3d92ab595ac8 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 2 Apr 2025 15:41:59 +0000 Subject: [PATCH 1/4] chore: apply backend streaming updates into app --- lib/ai/pattern-model.ts | 3 ++- lib/ai/types.ts | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/ai/pattern-model.ts b/lib/ai/pattern-model.ts index ccde7ea..d025af2 100644 --- a/lib/ai/pattern-model.ts +++ b/lib/ai/pattern-model.ts @@ -96,10 +96,11 @@ 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') { } 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..161543f 100644 --- a/lib/ai/types.ts +++ b/lib/ai/types.ts @@ -9,7 +9,15 @@ export interface ToolStartEvent { tool_input: Record; } -export type PatternStreamingResponseEvent = TokenEvent | ToolStartEvent; +export interface CompletionEvent { + type: 'completion'; + data: 'Stream completed'; +} + +export type PatternStreamingResponseEvent = + | TokenEvent + | ToolStartEvent + | CompletionEvent; export interface PatternProviderMetadata { accessToken: string; From 932491ff021bc8419312b76aedcbfcf7a871cc1e Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Thu, 3 Apr 2025 12:08:01 +0000 Subject: [PATCH 2/4] feat: support heartbeat events in stream chunks --- lib/ai/pattern-model.ts | 10 +++++++++- lib/ai/types.ts | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/ai/pattern-model.ts b/lib/ai/pattern-model.ts index d025af2..3770278 100644 --- a/lib/ai/pattern-model.ts +++ b/lib/ai/pattern-model.ts @@ -96,7 +96,15 @@ 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') { + } 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', diff --git a/lib/ai/types.ts b/lib/ai/types.ts index 161543f..85d11f1 100644 --- a/lib/ai/types.ts +++ b/lib/ai/types.ts @@ -14,10 +14,16 @@ export interface CompletionEvent { data: 'Stream completed'; } +export interface HeartbeatEvent { + type: 'heartbeat'; + data: 'still_processing'; +} + export type PatternStreamingResponseEvent = | TokenEvent | ToolStartEvent - | CompletionEvent; + | CompletionEvent + | HeartbeatEvent; export interface PatternProviderMetadata { accessToken: string; From 9f64bc6d265ecf3e3ba43ff50afb066f34066803 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Thu, 3 Apr 2025 17:01:49 +0330 Subject: [PATCH 3/4] fix: increase chat api `maxDuration` config to 300s --- app/(chat)/api/chat/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index e9679c6..9860bc1 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -12,7 +12,7 @@ import { 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 } = From 7229cbed201c46693a1bdb12823a3d295d6b8eb7 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Thu, 3 Apr 2025 14:18:11 +0000 Subject: [PATCH 4/4] chore: return streaming error data to the app --- app/(chat)/api/chat/route.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index 9860bc1..c129956 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -8,7 +8,11 @@ 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'; @@ -70,8 +74,8 @@ export async function POST(request: Request) { sendReasoning: true, }); }, - onError: () => { - return 'Oops, an error occured!'; + onError: (error) => { + return extractErrorMessageOrDefault(error); }, }); }