diff --git a/lib/ai/pattern-model.ts b/lib/ai/pattern-model.ts index 24b1b5b..f59b516 100644 --- a/lib/ai/pattern-model.ts +++ b/lib/ai/pattern-model.ts @@ -13,6 +13,17 @@ import type { const textDecoder = new TextDecoder(); +const SUPPORTED_EVENT_TYPES = [ + 'token', + 'tool_start', + 'tool_end', + 'heartbeat', + 'agent_start', + 'agent_finish', + 'tool_selection_start', + 'tool_selection_end', +] as const; + export class PatternModel implements LanguageModelV1 { readonly modelId = 'pattern-model'; readonly provider = 'pattern'; @@ -61,7 +72,7 @@ export class PatternModel implements LanguageModelV1 { * @returns Reasoning text for a tool start event */ private getToolStartReasoningText(event: ToolStartEvent) { - return `#### Tool call - ${event.tool}\n${Object.entries(event.tool_input ?? {}).map((entry) => `* **${entry[0]}**: ${entry[1]}\n`)}`; + return `#### Tool call - ${event.tool_name}\n${Object.entries(JSON.parse(event.params)).map((entry) => `* **${entry[0]}**: ${entry[1]}\n`)}`; } /** @@ -89,20 +100,11 @@ export class PatternModel implements LanguageModelV1 { type: 'text-delta', textDelta: event.data, }); - } else if (event.type === 'tool_start') { + } else if (SUPPORTED_EVENT_TYPES.includes(event.type)) { /** * 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', diff --git a/lib/ai/types.ts b/lib/ai/types.ts index 85d11f1..8323745 100644 --- a/lib/ai/types.ts +++ b/lib/ai/types.ts @@ -5,25 +5,53 @@ export interface TokenEvent { export interface ToolStartEvent { type: 'tool_start'; - tool: string; - tool_input: Record; + tool_name: string; + params: string; + timestamp: string; } -export interface CompletionEvent { - type: 'completion'; - data: 'Stream completed'; +export interface ToolEndEvent { + type: 'tool_end'; + tool_name: string; + output: any; + timestamp: string; } export interface HeartbeatEvent { type: 'heartbeat'; - data: 'still_processing'; + data: 'processing_started' | 'still_processing'; +} + +export interface AgentStartEvent { + type: 'agent_start'; + timestamp: string; +} + +export interface AgentFinishEvent { + type: 'agent_finish'; + timestamp: string; +} + +export interface ToolSelectionStartEvent { + type: 'tool_selection_start'; + timestamp: string; +} + +export interface ToolSelectionEndEvent { + type: 'tool_selection_end'; + selected_tools: string[]; + timestamp: string; } export type PatternStreamingResponseEvent = | TokenEvent | ToolStartEvent - | CompletionEvent - | HeartbeatEvent; + | ToolEndEvent + | HeartbeatEvent + | AgentStartEvent + | AgentFinishEvent + | ToolSelectionStartEvent + | ToolSelectionEndEvent; export interface PatternProviderMetadata { accessToken: string;