初始化模版工程

This commit is contained in:
Cloud Bot
2026-03-20 07:33:46 +00:00
commit 23717e0ecd
386 changed files with 51675 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
import { useMemo } from 'react'
import type { ApiEvent } from '../types'
import type { TaskArtifact, TaskStatus } from '../types'
import { TaskStatus as Status } from '../types'
/**
* 从事件中提取 artifacts 和 taskStatus
*/
export function useArtifactsExtractor(rawEvents: ApiEvent[]) {
return useMemo(() => {
const extractedArtifacts: TaskArtifact[] = []
const artifactKeys = new Set<string>() // 用于去重
let status: TaskStatus = Status.PENDING
for (const event of rawEvents) {
const content = event.content as Record<string, unknown> | undefined
const isUserInput = event.event_type === 'user_input' || event.role === 'user'
if (!content) continue
// 1. 提取 attachments
if (content.attachments) {
const attachments = Array.isArray(content.attachments)
? content.attachments
: [content.attachments]
for (const att of attachments) {
if (att?.file_name) {
const key = att.file_url || att.file_id || att.path || att.file_name
if (!artifactKeys.has(key)) {
artifactKeys.add(key)
extractedArtifacts.push({
path: att.path || att.file_url || att.file_id || '',
file_name: att.file_name,
file_type: att.file_type || att.file_name.split('.').pop() || '',
url: att.file_url,
from: isUserInput ? 'user' : 'assistant'
})
}
}
}
}
// 2. 提取 attachment_files
if (content.attachment_files && Array.isArray(content.attachment_files)) {
for (const file of content.attachment_files) {
if (file?.file_name) {
const key = file.url || file.path || file.file_name
if (!artifactKeys.has(key)) {
artifactKeys.add(key)
extractedArtifacts.push({
path: file.path || file.url || '',
file_name: file.file_name,
file_type: file.file_type || file.file_name.split('.').pop() || '',
url: file.url,
from: isUserInput ? 'user' : 'assistant'
})
}
}
}
}
// 3. 提取 generated_files (如 slide_create_in_batches 的输出)
const toolOutput = content.tool_output as Record<string, unknown> | undefined
if (toolOutput?.generated_files && Array.isArray(toolOutput.generated_files)) {
for (const file of toolOutput.generated_files) {
if (file?.index !== undefined && file?.content) {
const fileName = `slide_${file.index}.html`
const key = `generated_${event.event_id}_${file.index}`
if (!artifactKeys.has(key)) {
artifactKeys.add(key)
extractedArtifacts.push({
path: key,
file_name: fileName,
file_type: 'html',
event_type: 'generated_file',
tool_output: file.content,
from: isUserInput ? 'user' : 'assistant'
})
}
}
}
}
// 4. 提取 files (其他可能的文件字段)
if (content.files && Array.isArray(content.files)) {
for (const file of content.files) {
if (file?.name || file?.file_name) {
const fileName = file.name || file.file_name
const key = file.url || file.path || file.id || fileName
if (!artifactKeys.has(key)) {
artifactKeys.add(key)
extractedArtifacts.push({
path: file.path || file.url || file.id || '',
file_name: fileName,
file_type: file.type || file.file_type || fileName.split('.').pop() || '',
url: file.url,
from: isUserInput ? 'user' : 'assistant'
})
}
}
}
}
// 提取 taskStatus
const eventStatus = event.event_status as string | undefined
if (eventStatus === 'running' || eventStatus === 'in_progress') {
status = Status.IN_PROGRESS
} else if (eventStatus === 'success' || eventStatus === 'completed') {
status = Status.COMPLETED
} else if (eventStatus === 'failed' || eventStatus === 'error') {
status = Status.FAILED
}
}
return { artifacts: extractedArtifacts, taskStatus: status }
}, [rawEvents])
}