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

114 lines
3.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useCallback } from 'react'
import type { Attachment, HandleImageAttachmentClick, TaskArtifact } from '../types'
import type { ApiEvent } from './useNovaEvents'
import { extractToolOutputArtifact } from '../task-panel/Preview/previewUtils'
/**
* 附件处理逻辑 Hook
*/
export function useAttachmentHandlers(onSelectAttachment: (artifact: TaskArtifact) => void) {
// 处理附件点击
const handleAttachmentClick = useCallback(
(attachment: Attachment) => {
const artifact: TaskArtifact = {
path: attachment.path || attachment.file_url || attachment.file_id || '',
file_name: attachment.file_name,
file_type: attachment.file_type,
url: attachment.file_url,
}
onSelectAttachment(artifact)
},
[onSelectAttachment]
)
// 处理图片附件点击
const handleImageAttachmentClick = useCallback<HandleImageAttachmentClick>(
(image, from = 'assistant') => {
const getFileExtension = (str?: string): string => {
if (!str) return 'jpg'
const parts = str.split('.')
const ext = parts.length > 1 ? parts[parts.length - 1].toLowerCase().replace(/\?.*$/, '') : ''
return ext || 'jpg'
}
const fileType =
getFileExtension(image.file_name) || getFileExtension(image.path) || getFileExtension(image.url) || 'jpg'
const artifact: TaskArtifact = {
path: image.path || image.url || '',
file_name: image.file_name || '图片',
file_type: fileType,
url: image.url,
from,
}
onSelectAttachment(artifact)
},
[onSelectAttachment]
)
// 处理工具调用点击
const handleToolCallClick = useCallback(
(event: ApiEvent) => {
const content = event.content as Record<string, unknown> | undefined
const actionType = (content?.action_type as string | undefined) || undefined
const toolName = content?.tool_name as string | undefined
const actionName = content?.action_name as string | undefined
const metaToolName = (content?.metadata as Record<string, unknown> | undefined)?.tool_name as string | undefined
const toLower = (v?: string) => v?.toLowerCase()
const isSkillLoader =
toLower(actionType) === 'skill_loader' ||
toLower(actionName) === 'skill_loader' ||
toLower(toolName) === 'skill_loader' ||
toLower(metaToolName) === 'skill_loader'
const base: TaskArtifact = {
path: event.event_id,
file_name: toolName || '工具调用',
file_type: 'tool_call',
event_type: 'tool_call',
action_type: isSkillLoader
? 'skill_loader'
: actionType || actionName || toolName,
tool_name: toolName,
event_arguments: content?.arguments,
tool_input: content?.tool_input,
tool_output: content?.tool_output,
}
// Skill Loader点击时按 Markdown 文档渲染
if (isSkillLoader) {
const output = content?.tool_output
const mdContent =
typeof output === 'string'
? output
: output != null
? JSON.stringify(output, null, 2)
: ''
onSelectAttachment({
...base,
file_type: 'md',
content: mdContent,
})
return
}
const outputArtifact = extractToolOutputArtifact(base)
if (outputArtifact) {
onSelectAttachment(outputArtifact)
return
}
onSelectAttachment(base)
},
[onSelectAttachment]
)
return {
handleAttachmentClick,
handleImageAttachmentClick,
handleToolCallClick,
}
}