From d3837fc975f0b258af3dbd44167223d2e9b4d22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?cls=5F=E5=AE=81=E6=B3=A2=E6=9C=AC=E6=9C=BA?= <908705107@qq.com> Date: Sat, 13 Jun 2026 13:28:40 +0800 Subject: [PATCH] feat: clarify workflow run history --- .../ai_platform/api/workflow_api.py | 11 ++++ .../ai_platform/schemas/workflow_schema.py | 6 ++ .../src/api/ai-platform/ai-platform.ts | 6 ++ .../views/ai-platform/workflow-runs/data.ts | 21 +++++++ .../views/ai-platform/workflow-runs/index.vue | 56 +++++++++++++++++++ 5 files changed, 100 insertions(+) diff --git a/backend-fastapi/ai_platform/api/workflow_api.py b/backend-fastapi/ai_platform/api/workflow_api.py index ab65aed..d476bfd 100644 --- a/backend-fastapi/ai_platform/api/workflow_api.py +++ b/backend-fastapi/ai_platform/api/workflow_api.py @@ -570,12 +570,23 @@ async def list_workflow_runs( def _build_run_list_item(run: AIWorkflowRun, workflow_name: str = "") -> dict: + execution_log = run.execution_log or [] + last_log = next( + (log for log in reversed(execution_log) if isinstance(log, dict)), + {}, + ) return { "id": run.id, "workflow_id": run.workflow_id, "workflow_name": workflow_name, "status": run.status or "pending", "trigger_type": run.trigger_type or "api", + "inputs": run.inputs or {}, + "outputs": run.outputs or {}, + "current_node_id": run.current_node_id or "", + "last_node_id": last_log.get("node_id", ""), + "last_node_label": last_log.get("node_label", ""), + "last_node_type": last_log.get("node_type", ""), "total_steps": run.total_steps or 0, "total_tokens": run.total_tokens or 0, "elapsed_time": run.elapsed_time or 0, diff --git a/backend-fastapi/ai_platform/schemas/workflow_schema.py b/backend-fastapi/ai_platform/schemas/workflow_schema.py index c0a8738..93cc625 100644 --- a/backend-fastapi/ai_platform/schemas/workflow_schema.py +++ b/backend-fastapi/ai_platform/schemas/workflow_schema.py @@ -124,6 +124,12 @@ class WorkflowRunListResponse(BaseModel): workflow_name: str = "" status: str = "pending" trigger_type: str = "api" + inputs: dict = Field(default_factory=dict) + outputs: dict = Field(default_factory=dict) + current_node_id: str = "" + last_node_id: str = "" + last_node_label: str = "" + last_node_type: str = "" total_steps: int = 0 total_tokens: int = 0 elapsed_time: int = 0 diff --git a/web/apps/web-ele/src/api/ai-platform/ai-platform.ts b/web/apps/web-ele/src/api/ai-platform/ai-platform.ts index 86e6983..e01bf69 100644 --- a/web/apps/web-ele/src/api/ai-platform/ai-platform.ts +++ b/web/apps/web-ele/src/api/ai-platform/ai-platform.ts @@ -289,6 +289,12 @@ export interface WorkflowRunListItem { workflow_name: string; status: string; trigger_type: string; + inputs: Record; + outputs: Record; + current_node_id: string; + last_node_id: string; + last_node_label: string; + last_node_type: string; total_steps: number; total_tokens: number; elapsed_time: number; diff --git a/web/apps/web-ele/src/views/ai-platform/workflow-runs/data.ts b/web/apps/web-ele/src/views/ai-platform/workflow-runs/data.ts index 2117547..70cafb1 100644 --- a/web/apps/web-ele/src/views/ai-platform/workflow-runs/data.ts +++ b/web/apps/web-ele/src/views/ai-platform/workflow-runs/data.ts @@ -107,6 +107,13 @@ export function useZqTableColumns(): Column[] { title: $t('ai-platform.workflowRuns.columns.workflow'), minWidth: 160, }, + { + key: 'task_summary', + title: '任务', + minWidth: 240, + showOverflowTooltip: true, + slots: { default: 'cell-task_summary' }, + }, { key: 'status', title: $t('ai-platform.workflowRuns.columns.status'), @@ -135,6 +142,20 @@ export function useZqTableColumns(): Column[] { width: 90, align: 'center' as const, }, + { + key: 'last_node', + title: '最后节点', + minWidth: 150, + showOverflowTooltip: true, + slots: { default: 'cell-last_node' }, + }, + { + key: 'result_summary', + title: '结果摘要', + minWidth: 260, + showOverflowTooltip: true, + slots: { default: 'cell-result_summary' }, + }, { key: 'elapsed_time', title: $t('ai-platform.workflowRuns.columns.duration'), diff --git a/web/apps/web-ele/src/views/ai-platform/workflow-runs/index.vue b/web/apps/web-ele/src/views/ai-platform/workflow-runs/index.vue index 719a3ad..bd3ae7f 100644 --- a/web/apps/web-ele/src/views/ai-platform/workflow-runs/index.vue +++ b/web/apps/web-ele/src/views/ai-platform/workflow-runs/index.vue @@ -82,6 +82,40 @@ const [Grid] = useZqTable({ function openDetail(row: WorkflowRunListItem) { detailRef.value?.open(row.id); } + +function previewText(value: any, maxLength = 120) { + if (value === undefined || value === null || value === '') return '-'; + const text = + typeof value === 'string' + ? value + : JSON.stringify(value, null, 0); + return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; +} + +function getTaskSummary(row: WorkflowRunListItem) { + const issueId = row.inputs?.issue_id; + const request = + row.inputs?.request || + row.inputs?.user_input || + row.inputs?.query || + row.inputs?.task; + if (issueId && request) return `${issueId}:${request}`; + return previewText(request || row.inputs, 160); +} + +function getLastNode(row: WorkflowRunListItem) { + return row.last_node_label || row.last_node_id || row.current_node_id || '-'; +} + +function getResultSummary(row: WorkflowRunListItem) { + const output = row.outputs?.output || row.outputs?.final_result; + if (output) return previewText(output, 180); + + const nodeValues = Object.entries(row.outputs || {}) + .filter(([key]) => key.startsWith('_node_')) + .map(([, value]) => (value as any)?.output || value); + return previewText(nodeValues.at(-1) || row.error_message || row.outputs, 180); +} + + + + + +