| 1 | import type { TaskDetail, TaskMessage } from '@/api/ai/ai.types' |
| 2 | |
| 3 | // 认为这些状态表示任务已结束(不再需要轮询) |
| 4 | // 同时支持大写和小写格式(兼容后端返回的格式) |
| 5 | const COMPLETED_STATUS_VALUES = [ |
| 6 | 'completed', |
| 7 | 'COMPLETED', |
| 8 | 'failed', |
| 9 | 'FAILED', |
| 10 | 'cancelled', |
| 11 | 'CANCELLED', |
| 12 | 'aborted', |
| 13 | 'ABORTED', |
| 14 | 'requires_action', // 需要用户操作也算完成(停止轮询) |
| 15 | 'error', |
| 16 | ] |
| 17 | |
| 18 | /** |
| 19 | * 根据 TaskDetail 的 status 判断任务是否完成 |
| 20 | */ |
| 21 | export function isTaskCompletedByStatus( |
| 22 | task: Pick<TaskDetail, 'status'> | null | undefined, |
| 23 | ): boolean { |
| 24 | if (!task) |
| 25 | return false |
| 26 | const statusValue = task.status as string |
| 27 | return ( |
| 28 | COMPLETED_STATUS_VALUES.includes(statusValue?.toLowerCase()) |
| 29 | || COMPLETED_STATUS_VALUES.includes(statusValue) |
| 30 | ) |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * 兼容旧逻辑:根据消息列表粗略判断任务是否完成 |
| 35 | * 仅在没有 status 信息时作为兜底使用 |
| 36 | */ |
| 37 | export function isTaskCompletedByMessages(messages: TaskMessage[]): boolean { |
| 38 | if (!messages || messages.length === 0) { |
| 39 | return false |
| 40 | } |
| 41 | |
| 42 | // 从后往前遍历消息,检查是否有完成标志 |
| 43 | for (let i = messages.length - 1; i >= 0; i--) { |
| 44 | const msg = messages[i] |
| 45 | |
| 46 | // 检查 stream_event 类型的消息 |
| 47 | if (msg.type === 'stream_event') { |
| 48 | const streamEvent = msg as any |
| 49 | const event = streamEvent.event |
| 50 | |
| 51 | // message_delta 中 stop_reason === 'end_turn' 表示一轮对话结束 |
| 52 | if (event?.type === 'message_delta' && event?.delta?.stop_reason === 'end_turn') { |
| 53 | return true |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | return false |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * 统一对外导出的方法:优先看 status,其次兜底看 messages |
| 63 | */ |
| 64 | export function isTaskCompleted( |
| 65 | messages: TaskMessage[], |
| 66 | task?: Pick<TaskDetail, 'status'> | null, |
| 67 | ): boolean { |
| 68 | if (task && isTaskCompletedByStatus(task)) { |
| 69 | return true |
| 70 | } |
| 71 | return isTaskCompletedByMessages(messages) |
| 72 | } |
| 73 |