初始化模版工程
This commit is contained in:
113
components/nova-sdk/hooks/useAttachmentHandlers.ts
Normal file
113
components/nova-sdk/hooks/useAttachmentHandlers.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user