export function textFromContent(content) { if (typeof content === 'string') { return content; } if (!Array.isArray(content)) { return ''; } return content .map((part) => { if (typeof part === 'string') { return part; } if (part?.type === 'output_text' || part?.type === 'input_text' || part?.type === 'text') { return part.text || ''; } return part?.text || ''; }) .filter(Boolean) .join('\n'); } export function contentFromItem(item) { if (!item) { return ''; } const contentText = textFromContent(item.content); if (contentText) { return contentText; } if (typeof item.text === 'string') { return item.text; } if (typeof item.aggregated_output === 'string') { return item.aggregated_output; } if (typeof item.message === 'string') { return item.message; } return ''; } export function statusLabel(kind, status = 'running') { const done = status === 'completed'; const failed = status === 'failed'; const labels = { turn: done ? '任务已完成' : failed ? '任务失败' : '正在处理', reasoning: done ? '思考完成' : '正在思考', agent_message: '正在回复', message: '正在回复', command_execution: done ? '命令已完成' : failed ? '命令失败' : '正在执行命令', file_change: done ? '文件已修改' : failed ? '文件修改失败' : '正在修改文件', mcp_tool_call: done ? '工具调用完成' : failed ? '工具调用失败' : '正在调用工具', web_search: done ? '搜索完成' : failed ? '搜索失败' : '正在搜索', todo_list: done ? '计划已更新' : '正在规划', image_generation_call: done ? '图片生成完成' : failed ? '图片生成失败' : '正在生成图片', custom_tool_call: done ? '工具调用完成' : failed ? '工具调用失败' : '正在调用工具', function_call: done ? '工具调用完成' : failed ? '工具调用失败' : '正在调用工具', error: '出现错误' }; return labels[kind] || (done ? '已完成' : failed ? '失败' : '正在处理'); } export function compactStatusLabel(content, fallback = '正在处理') { const label = String(content || '') .replace(/\s+/g, ' ') .trim(); if (!label) { return fallback; } return label.length > 68 ? `${label.slice(0, 68)}...` : label; } export function detailFromItem(item) { if (!item) { return ''; } if (item.command) { return item.command; } if (item.query) { return item.query; } if (item.tool || item.server) { return [item.server, item.tool].filter(Boolean).join(' / '); } if (Array.isArray(item.changes)) { return item.changes.map((change) => `${change.kind || 'update'} ${change.path}`).join('\n'); } if (item.message) { return item.message; } return contentFromItem(item); } export function eventItem(event) { if (event.item) { return event.item; } if (event.payload && (event.type === 'response_item' || event.type === 'event_msg')) { return event.payload; } return null; } export function eventStatus(event, item) { if (item?.status) { return item.status === 'in_progress' ? 'running' : item.status; } if (event.type === 'item.completed') { return 'completed'; } if (event.type === 'item.started' || event.type === 'item.updated') { return 'running'; } if (event.type === 'event_msg' && item?.type?.endsWith('_end')) { return item.exit_code || item.exit_code === 0 ? (item.exit_code === 0 ? 'completed' : 'failed') : 'completed'; } if (event.type === 'response_item') { return 'completed'; } return 'running'; } export function emitStatus(emit, { sessionId, turnId, kind, status = 'running', label, detail = '' }) { emit({ type: 'status-update', sessionId, turnId, kind, status, label: label || statusLabel(kind, status), detail, timestamp: new Date().toISOString() }); }