ForcePilot/web/src/components/SubagentThreadModal.vue
2026-06-03 14:09:45 +08:00

105 lines
2.6 KiB
Vue
Raw 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.

<template>
<a-modal
:open="open"
:title="subagentName || '子智能体'"
:footer="null"
:width="800"
:destroyOnClose="true"
@cancel="$emit('update:open', false)"
>
<div class="subagent-thread-modal-body">
<div v-if="loading" class="subagent-thread-modal-state">正在加载子智能体消息...</div>
<div v-else-if="error" class="subagent-thread-modal-state is-error">{{ error }}</div>
<ThreadMessageList v-else :messages="messages" />
</div>
</a-modal>
</template>
<script setup>
import { ref, watch } from 'vue'
import { agentApi } from '@/apis'
import { MessageProcessor } from '@/utils/messageProcessor'
import ThreadMessageList from '@/components/ThreadMessageList.vue'
const props = defineProps({
open: {
type: Boolean,
default: false
},
childThreadId: {
type: String,
default: ''
},
subagentName: {
type: String,
default: ''
}
})
defineEmits(['update:open'])
const loading = ref(false)
const error = ref('')
const messages = ref([])
// LangChain 内容块数组 → 纯文本(仅保留 text 块)
const flattenContent = (content) => {
if (typeof content === 'string') return content
if (Array.isArray(content)) {
return content
.filter((block) => block && block.type === 'text')
.map((block) => block.text || '')
.join('')
}
return content ?? ''
}
const loadHistory = async (threadId) => {
if (!threadId) return
loading.value = true
error.value = ''
messages.value = []
try {
// 子智能体消息存于 LangGraph checkpoint需走 state 接口并把 tool 结果嵌入 AI 消息。
const response = await agentApi.getAgentState(threadId, { includeMessages: true })
// checkpoint 的 content 可能是 LangChain 内容块数组,扁平成文本供 MarkdownPreview 渲染。
const normalized = (response.messages || []).map((msg) => ({
...msg,
content: flattenContent(msg.content)
}))
messages.value = MessageProcessor.convertToolResultToMessages(normalized)
} catch (e) {
error.value = '加载子智能体消息失败'
console.error('Failed to load subagent thread messages:', e)
} finally {
loading.value = false
}
}
watch(
() => [props.open, props.childThreadId],
([isOpen, threadId]) => {
if (isOpen && threadId) loadHistory(threadId)
},
{ immediate: true }
)
</script>
<style lang="less" scoped>
.subagent-thread-modal-body {
max-height: 70vh;
overflow-y: auto;
}
.subagent-thread-modal-state {
padding: 32px 0;
text-align: center;
color: var(--gray-500);
font-size: 13px;
&.is-error {
color: var(--color-error-600);
}
}
</style>