Spaces:
Running
Running
| import type { AgentRunLog } from "@/lib/agent-run-log-types"; | |
| /** Markdown export for pasting into an LLM β safe for client bundles (no Redis). */ | |
| export function buildDebugTrace(run: AgentRunLog): string { | |
| const lines: string[] = []; | |
| const ts = new Date(run.startedAt).toISOString(); | |
| lines.push("# Job Scorer Agent Debug Trace"); | |
| lines.push(`Run ID: \`${run.runId}\``); | |
| lines.push(`User: \`${run.userId}\``); | |
| if (run.sessionId) lines.push(`Session: \`${run.sessionId}\``); | |
| lines.push(`Started: ${ts}`); | |
| lines.push(`Duration: ${(run.durationMs / 1000).toFixed(1)}s`); | |
| lines.push(`Stopped because: **${run.stoppedBecause}**`); | |
| lines.push(`Credit cost: ${run.creditCost}`); | |
| lines.push(`Result: ${run.finalResultSummary ?? "none"}`); | |
| if (run.errorMessage) lines.push(`Run error: ${run.errorMessage}`); | |
| lines.push(""); | |
| lines.push("## Completion Steps (LLM decisions)"); | |
| for (const step of run.completionSteps) { | |
| lines.push(`### Step ${step.stepIndex + 1} β ${step.model || "?"} (${step.provider})`); | |
| lines.push(`Duration: ${step.durationMs}ms`); | |
| if (step.assistantReasoningText) { | |
| lines.push("**Model reasoning before tool call:**"); | |
| lines.push(`> ${step.assistantReasoningText.replace(/\n/g, "\n> ")}`); | |
| } | |
| if (step.toolCalls?.length) { | |
| lines.push("**Tool calls chosen:**"); | |
| for (const tc of step.toolCalls) { | |
| lines.push(`- \`${tc.name}\`: \`${JSON.stringify(tc.input).slice(0, 200)}\``); | |
| } | |
| } else if (!step.errorMessage) { | |
| lines.push("*No tool call β final response turn*"); | |
| } | |
| if (step.errorMessage) { | |
| lines.push(`**Error:** ${step.errorMessage}`); | |
| } | |
| if (step.messages?.length) { | |
| lines.push(`<details><summary>Full message array (${step.messages.length} messages)</summary>`); | |
| lines.push(""); | |
| lines.push("```json"); | |
| lines.push(JSON.stringify(step.messages, null, 2).slice(0, 8000)); | |
| lines.push("```"); | |
| lines.push("</details>"); | |
| } | |
| lines.push(""); | |
| } | |
| lines.push("## Tool Timeline"); | |
| for (const t of run.tools) { | |
| const status = t.status === "ok" ? "β" : t.status === "error" ? "β" : "β "; | |
| lines.push(`${status} **${t.tool}** β ${t.durationMs}ms β ${t.provider ?? "unknown provider"}`); | |
| if (t.resultSummary) lines.push(` Result: ${t.resultSummary}`); | |
| if (t.creditCost !== undefined && t.creditCost > 0) lines.push(` Credits: ${t.creditCost}`); | |
| if (t.input && Object.keys(t.input).length > 0) { | |
| lines.push(` Input: \`${JSON.stringify(t.input).slice(0, 300)}\``); | |
| } | |
| } | |
| lines.push(""); | |
| lines.push("---"); | |
| lines.push("*Job Scorer debug trace β paste into Claude for diagnosis*"); | |
| return lines.join("\n"); | |
| } | |