feat: 接入 Agent 历史记录
- src/services/devopsApi.ts: 增加真实 Agent 调用历史列表接口 - src/components/GlobalAgentDrawer.vue: 抽屉打开时加载持久化历史,并展示用途、状态、问题和上下文摘要
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
*/
|
||||
import { Close, Promotion } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { devopsApi } from '../services/devopsApi'
|
||||
import { usePlatformStore } from '../stores/platform'
|
||||
import type { AgentMode, AgentPurpose } from '../types/devops'
|
||||
import type { AgentInvocation, AgentMode, AgentPurpose } from '../types/devops'
|
||||
|
||||
type AgentMessage = {
|
||||
id: string
|
||||
@@ -28,6 +28,7 @@ const selectedProject = ref('')
|
||||
const selectedRun = ref('')
|
||||
const prompt = ref('帮我检查当前发布是否存在配置、构建或通知风险。')
|
||||
const sending = ref(false)
|
||||
const historyLoading = ref(false)
|
||||
const messages = ref<AgentMessage[]>([
|
||||
{
|
||||
id: 'welcome',
|
||||
@@ -38,6 +39,14 @@ const messages = ref<AgentMessage[]>([
|
||||
},
|
||||
])
|
||||
|
||||
const purposeTitles: Record<AgentPurpose, string> = {
|
||||
'release-risk': '发布风险',
|
||||
'failure-diagnosis': '失败诊断',
|
||||
'runbook-qa': 'Runbook',
|
||||
'release-note': '发布说明',
|
||||
'incident-review': '事故复盘',
|
||||
}
|
||||
|
||||
const activeCard = computed(() => {
|
||||
return platform.agentCards.find((card) => card.mode === selectedMode.value)
|
||||
})
|
||||
@@ -98,6 +107,26 @@ watch(selectedMode, (mode) => {
|
||||
prompt.value = '帮我检查当前发布是否存在配置、构建或通知风险。'
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
void loadInvocationHistory()
|
||||
})
|
||||
|
||||
async function loadInvocationHistory() {
|
||||
historyLoading.value = true
|
||||
|
||||
try {
|
||||
const invocations = await devopsApi.listAgentInvocations()
|
||||
messages.value = [
|
||||
messages.value[0],
|
||||
...invocations.slice(0, 20).map(toHistoryMessage),
|
||||
]
|
||||
} catch (error) {
|
||||
ElMessage.error(error instanceof Error ? error.message : 'Agent 历史加载失败')
|
||||
} finally {
|
||||
historyLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function sendPrompt() {
|
||||
const text = prompt.value.trim()
|
||||
|
||||
@@ -137,6 +166,37 @@ async function sendPrompt() {
|
||||
}
|
||||
}
|
||||
|
||||
function toHistoryMessage(invocation: AgentInvocation): AgentMessage {
|
||||
return {
|
||||
id: invocation.id,
|
||||
role: 'assistant',
|
||||
title: `${purposeTitles[invocation.type]} · ${statusLabel(invocation.status)}`,
|
||||
content: [
|
||||
`问题:${invocation.promptSummary}`,
|
||||
'',
|
||||
invocation.resultMarkdown || 'Agent 未返回内容',
|
||||
].join('\n'),
|
||||
contextSummary: invocation.contextSummary,
|
||||
createdAt: formatTime(invocation.createdAt),
|
||||
}
|
||||
}
|
||||
|
||||
function statusLabel(status: AgentInvocation['status']): string {
|
||||
if (status === 'success') {
|
||||
return '成功'
|
||||
}
|
||||
|
||||
if (status === 'failed') {
|
||||
return '失败'
|
||||
}
|
||||
|
||||
if (status === 'running') {
|
||||
return '运行中'
|
||||
}
|
||||
|
||||
return '等待中'
|
||||
}
|
||||
|
||||
function handleComposerKeydown(event: KeyboardEvent) {
|
||||
if (event.key !== 'Enter' || (!event.metaKey && !event.ctrlKey)) {
|
||||
return
|
||||
@@ -208,6 +268,7 @@ function formatTime(value: string): string {
|
||||
</div>
|
||||
|
||||
<div class="message-list">
|
||||
<div v-if="historyLoading" class="history-loading">正在加载历史记录...</div>
|
||||
<article v-for="message in messages" :key="message.id" class="agent-message" :class="message.role">
|
||||
<div class="message-meta">
|
||||
<strong>{{ message.title }}</strong>
|
||||
@@ -300,6 +361,12 @@ function formatTime(value: string): string {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.history-loading {
|
||||
color: #64748b;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.agent-message {
|
||||
max-width: 100%;
|
||||
padding: 12px;
|
||||
|
||||
@@ -503,6 +503,12 @@ export const devopsApi = {
|
||||
return data
|
||||
},
|
||||
|
||||
async listAgentInvocations(): Promise<AgentInvocation[]> {
|
||||
const { data } = await http.get<AgentInvocation[]>('/agent/invocations')
|
||||
lastDataSource = 'backend'
|
||||
return data
|
||||
},
|
||||
|
||||
async getSettings(): Promise<SystemSetting[]> {
|
||||
const [health, integrationConfig] = await Promise.all([
|
||||
fetchHealth(),
|
||||
|
||||
Reference in New Issue
Block a user