UNPKG

@mesh-tech/mesh-cli

Version:

CLI for Mesh platform development utilities

207 lines (206 loc) 7.09 kB
export async function classifyHistoryEvents(rawEvents, decodePayload) { const activityTypeByScheduledId = new Map(); const events = []; for (const event of rawEvents) { const eventId = String(event.eventId); const scheduled = event.activityTaskScheduledEventAttributes; if (scheduled) { const name = scheduled.activityType?.name; if (name) activityTypeByScheduledId.set(eventId, name); continue; } const signal = event.workflowExecutionSignaledEventAttributes; if (signal?.signalName === "submit_user_message") { events.push({ eventId, kind: "userSignal", payload: await decodePayload(signal.input?.payloads), }); continue; } const completed = event.activityTaskCompletedEventAttributes; if (completed) { const scheduledId = String(completed.scheduledEventId); if (activityTypeByScheduledId.get(scheduledId) === "callLLM") { events.push({ eventId, kind: "callLLMResult", payload: await decodePayload(completed.result?.payloads), }); } } } return events; } export async function extractSnapshotMessages(rawEvents, decodePayload) { let lastCallLLMScheduledId; let lastCallLLMInputPayloads; const activityTypeByScheduledId = new Map(); let lastCallLLMResultPayloads; for (const event of rawEvents) { const eventId = String(event.eventId); const scheduled = event.activityTaskScheduledEventAttributes; if (scheduled) { const name = scheduled.activityType?.name; if (name) activityTypeByScheduledId.set(eventId, name); if (name === "callLLM") { lastCallLLMScheduledId = eventId; lastCallLLMInputPayloads = scheduled.input?.payloads; lastCallLLMResultPayloads = undefined; } continue; } const completed = event.activityTaskCompletedEventAttributes; if (completed) { const scheduledId = String(completed.scheduledEventId); if (activityTypeByScheduledId.get(scheduledId) === "callLLM") { lastCallLLMResultPayloads = completed.result?.payloads; } } } if (lastCallLLMScheduledId === undefined) return []; const inputArgs = await decodePayload(lastCallLLMInputPayloads); const inputMessages = messagesFrom(inputArgs); const result = await decodePayload(lastCallLLMResultPayloads); const resultMessages = messagesFrom(result); return [...inputMessages, ...resultMessages]; } function messagesFrom(payload) { if (isRecord(payload) && Array.isArray(payload.messages)) { return payload.messages; } return []; } function extractText(content) { if (typeof content === "string") return content; if (Array.isArray(content)) { return content .filter((p) => !!p && typeof p === "object" && p.type === "text") .map((p) => (typeof p.text === "string" ? p.text : "")) .join(""); } return ""; } function summarizeArgs(args) { try { const str = JSON.stringify(args ?? {}); return str.length > 100 ? str.substring(0, 97) + "..." : str; } catch { return "..."; } } function formatToolCall(part) { const name = typeof part.toolName === "string" ? part.toolName : "?"; const args = "input" in part ? part.input : part.args; return `${name}(${summarizeArgs(args)})`; } function isRecord(v) { return !!v && typeof v === "object"; } function extractUserText(payload) { if (!isRecord(payload)) return null; const messages = payload.messages; if (Array.isArray(messages)) { const parts = []; for (const m of messages) { if (isRecord(m) && m.role === "user") { const t = extractText(m.content); if (t) parts.push(t); } } if (parts.length > 0) return parts.join("\n"); } for (const field of ["content", "text", "message"]) { const v = payload[field]; if (typeof v === "string" && v) return v; const t = extractText(v); if (t) return t; } return null; } function extractAssistantTurn(payload) { if (!isRecord(payload)) return null; const messages = payload.messages; if (!Array.isArray(messages)) { const t = extractText(payload.content) || extractText(payload.text); return t ? { text: t, toolCalls: [] } : null; } let text = ""; const toolCalls = []; for (const m of messages) { if (!isRecord(m) || m.role !== "assistant") continue; text += extractText(m.content); if (Array.isArray(m.content)) { for (const p of m.content) { if (isRecord(p) && p.type === "tool-call") { toolCalls.push(formatToolCall(p)); } } } } if (!text && toolCalls.length === 0) return null; return { text, toolCalls }; } export function reconstructTranscript(events) { const turns = []; for (const event of events) { if (event.kind === "userSignal") { const text = extractUserText(event.payload); turns.push(text !== null ? { role: "user", text, eventId: event.eventId } : { role: "user", text: placeholder(event.eventId), eventId: event.eventId }); } else if (event.kind === "callLLMResult") { const turn = extractAssistantTurn(event.payload); if (turn) { turns.push({ role: "assistant", text: turn.text, eventId: event.eventId, ...(turn.toolCalls.length > 0 ? { toolCalls: turn.toolCalls } : {}), }); } else { turns.push({ role: "assistant", text: placeholder(event.eventId), eventId: event.eventId, }); } } } return turns; } function placeholder(eventId) { return `_[unparseable turn: ${eventId}]_`; } export function renderTranscriptMarkdown(turns) { const blocks = []; for (const turn of turns) { const heading = turn.role === "user" ? "## User" : "## Assistant"; const lines = [heading, ""]; if (turn.text) lines.push(turn.text); if (turn.toolCalls && turn.toolCalls.length > 0) { if (turn.text) lines.push(""); for (const tc of turn.toolCalls) lines.push(`→ tool: ${tc}`); } blocks.push(lines.join("\n")); } return blocks.join("\n\n") + "\n"; }