@mesh-tech/mesh-cli
Version:
CLI for Mesh platform development utilities
207 lines (206 loc) • 7.09 kB
JavaScript
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";
}