Files
test1/components/nova-sdk/utils/slideEventHelpers.ts
2026-03-20 07:33:46 +00:00

88 lines
2.6 KiB
TypeScript

import type { ApiEvent } from '../types'
/**
* 检查是否为 slide_create_in_batches 事件
*/
export function isSlideCreateInBatchesEvent(
event: ApiEvent,
state?: 'start' | 'running' | 'done'
): boolean {
if (event.content?.action_type !== 'slide_create_in_batches') {
return false
}
if (!state) return true
const eventStatus = event.event_status as string | undefined
const isStream = !!event.stream
if (state === 'start') return !isStream && eventStatus === 'running'
if (state === 'running') return isStream && eventStatus === 'running'
if (state === 'done') return eventStatus === 'success'
return false
}
/**
* Slide 流式数据累积结果
*/
export interface SlideStreamData {
slideChunks: Map<string, string>
slidePages?: Array<{ html: string; status: 'completed' }>
}
/**
* 处理 slide 事件的流式数据累积
*/
export function processSlideEvents(rawEvents: ApiEvent[]): SlideStreamData {
const slideChunks = new Map<string, string>() // index -> content
let slidePages: Array<{ html: string; status: 'completed' }> | undefined
for (const event of rawEvents) {
// slide_create_in_batches 特殊处理:累积 chunks
if (isSlideCreateInBatchesEvent(event, 'running')) {
const chunk = event.content?.tool_input as { index?: number; content?: string } | undefined
if (chunk?.content) {
const key = (chunk.index || 1).toString()
const existing = slideChunks.get(key) || ''
slideChunks.set(key, existing + chunk.content)
}
}
if (isSlideCreateInBatchesEvent(event, 'done')) {
const output = event.content?.tool_output as { generated_files?: Array<{ index: number; content: string }> } | undefined
if (output?.generated_files) {
slidePages = output.generated_files.map((slide) => ({
html: slide.content,
status: 'completed' as const,
}))
}
}
}
return { slideChunks, slidePages }
}
/**
* 为事件附加 slide 元数据
*/
export function attachSlideMetadata(
event: ApiEvent,
slideData: SlideStreamData
): { pages?: Array<{ html: string; status: 'running' | 'completed' }>; isStreaming: boolean } | undefined {
if (!isSlideCreateInBatchesEvent(event)) {
return undefined
}
const { slideChunks, slidePages } = slideData
const streamPages = slideChunks.size > 0
? Array.from(slideChunks.entries())
.sort(([a], [b]) => Number(a) - Number(b))
.map(([, content]) => ({ html: content, status: 'running' as const }))
: undefined
return {
pages: slidePages || streamPages,
isStreaming: !slidePages && !!streamPages,
}
}