// Чистый разбор хвоста стенограммы: последний обмен (user + assistant + действия). // Схема сверена с observer-transcript-parser: entry.message.role / entry.message.content // (строка или массив блоков text/tool_use{name,input}). function parseLines(text) { const entries = []; for (const line of String(text || '').split(/\r?\n/)) { const t = line.trim(); if (!t) continue; try { entries.push(JSON.parse(t)); } catch { /* битую строку пропускаем */ } } return entries; } // Настоящий промпт пользователя (НЕ tool_result): content — строка или массив с text-блоком. // В формате Anthropic tool_result — это сообщения role:user, их пропускаем, иначе теряются // и настоящий промпт, и все действия ассистента до него. function isRealUserPrompt(msg) { if (!msg || msg.role !== 'user') return false; const c = msg.content; if (typeof c === 'string') return true; if (Array.isArray(c)) return c.some((b) => b && b.type === 'text'); return false; } /** Последний обмен из стенограммы: { user, assistant, actions:[{tool,input}] }. */ export function parseLastExchange(transcriptText) { const entries = parseLines(transcriptText); let u = -1; for (let i = entries.length - 1; i >= 0; i--) { if (entries[i] && isRealUserPrompt(entries[i].message)) { u = i; break; } } const userContent = u >= 0 ? entries[u].message.content : ''; const user = typeof userContent === 'string' ? userContent : (Array.isArray(userContent) ? userContent.filter((b) => b && b.type === 'text').map((b) => b.text).join('\n') : ''); let assistant = ''; const actions = []; for (let i = u + 1; i < entries.length; i++) { const m = entries[i] && entries[i].message; if (!m || m.role !== 'assistant') continue; const c = m.content; if (Array.isArray(c)) { for (const b of c) { if (b && b.type === 'text' && b.text) assistant += (assistant ? '\n' : '') + b.text; if (b && b.type === 'tool_use') actions.push({ tool: b.name, input: JSON.stringify(b.input ?? {}) }); } } else if (typeof c === 'string') { assistant += (assistant ? '\n' : '') + c; } } return { user, assistant, actions }; }