Spaces:
Sleeping
Sleeping
| import toast from 'react-hot-toast'; | |
| const WIPLogTypes = ['plans', 'tools', 'code']; | |
| const AllLogTypes = [ | |
| 'plans', | |
| 'tools', | |
| 'code', | |
| 'final_code', | |
| 'final_error', | |
| ] as const; | |
| export type ChunkBody = { | |
| type: (typeof AllLogTypes)[number]; | |
| status: 'started' | 'completed' | 'failed' | 'running'; | |
| timestamp?: string; | |
| payload: | |
| | Array<Record<string, string>> // PlansBody | ToolsBody | |
| | PrismaJson.FinalCodeBody['payload'] // CodeBody & FinalCodeBody | |
| | PrismaJson.StructuredError; // ErrorBody | |
| }; | |
| export type WIPChunkBodyGroup = PrismaJson.MessageBody & { | |
| timestamp?: string; | |
| duration?: number; | |
| }; | |
| /** | |
| * Formats the stream logs and returns an array of grouped sections. | |
| * | |
| * @param content - The content of the stream logs. | |
| * @returns An array of grouped sections and an optional final code result. | |
| */ | |
| export const formatStreamLogs = ( | |
| content: WIPChunkBodyGroup[] | null, | |
| result: PrismaJson.FinalResultBody | null, | |
| ): { | |
| formattedSections: WIPChunkBodyGroup[]; | |
| finalResult?: PrismaJson.FinalCodeBody['payload']; | |
| finalError?: PrismaJson.StructuredError; | |
| } => { | |
| if (!content) | |
| return { | |
| formattedSections: [], | |
| }; | |
| // Merge consecutive logs of the same type to the latest status | |
| const groupedSections = [...content, ...(result ? [result] : [])].reduce( | |
| (acc: WIPChunkBodyGroup[], curr: WIPChunkBodyGroup) => { | |
| const lastGroup = acc[acc.length - 1]; | |
| if ( | |
| acc.length > 0 && | |
| lastGroup.type === curr.type && | |
| curr.status !== 'started' | |
| ) { | |
| acc[acc.length - 1] = { | |
| ...curr, | |
| // always use the timestamp of the first log | |
| timestamp: lastGroup?.timestamp, | |
| // duration is the difference between the last log and the first log | |
| duration: | |
| lastGroup?.timestamp && curr.timestamp | |
| ? Date.parse(curr.timestamp) - Date.parse(lastGroup.timestamp) | |
| : undefined, | |
| }; | |
| } else { | |
| acc.push(curr); | |
| } | |
| return acc; | |
| }, | |
| [], | |
| ); | |
| return { | |
| formattedSections: groupedSections.filter(section => | |
| WIPLogTypes.includes(section.type), | |
| ), | |
| finalResult: groupedSections.find(section => section.type === 'final_code') | |
| ?.payload as PrismaJson.FinalCodeBody['payload'], | |
| finalError: groupedSections.find(section => section.type === 'final_error') | |
| ?.payload as PrismaJson.StructuredError, | |
| }; | |
| }; | |