()
| 327 | }; |
| 328 | |
| 329 | const handleCopyAsMarkdown = async () => { |
| 330 | if (!run) return; |
| 331 | let markdown = `# Agent Execution: ${run.agent_name}\n\n`; |
| 332 | markdown += `**Task:** ${run.task}\n`; |
| 333 | markdown += `**Model:** ${run.model === 'opus' ? 'Claude 4 Opus' : 'Claude 4 Sonnet'}\n`; |
| 334 | markdown += `**Date:** ${formatISOTimestamp(run.created_at)}\n`; |
| 335 | if (run.metrics?.duration_ms) markdown += `**Duration:** ${(run.metrics.duration_ms / 1000).toFixed(2)}s\n`; |
| 336 | if (run.metrics?.total_tokens) markdown += `**Total Tokens:** ${run.metrics.total_tokens}\n`; |
| 337 | if (run.metrics?.cost_usd) markdown += `**Cost:** $${run.metrics.cost_usd.toFixed(4)} USD\n`; |
| 338 | markdown += `\n---\n\n`; |
| 339 | |
| 340 | for (const msg of messages) { |
| 341 | if (msg.type === "system" && msg.subtype === "init") { |
| 342 | markdown += `## System Initialization\n\n`; |
| 343 | markdown += `- Session ID: \`${msg.session_id || 'N/A'}\`\n`; |
| 344 | markdown += `- Model: \`${msg.model || 'default'}\`\n`; |
| 345 | if (msg.cwd) markdown += `- Working Directory: \`${msg.cwd}\`\n`; |
| 346 | if (msg.tools?.length) markdown += `- Tools: ${msg.tools.join(', ')}\n`; |
| 347 | markdown += `\n`; |
| 348 | } else if (msg.type === "assistant" && msg.message) { |
| 349 | markdown += `## Assistant\n\n`; |
| 350 | for (const content of msg.message.content || []) { |
| 351 | if (content.type === "text") { |
| 352 | markdown += `${content.text}\n\n`; |
| 353 | } else if (content.type === "tool_use") { |
| 354 | markdown += `### Tool: ${content.name}\n\n`; |
| 355 | markdown += `\`\`\`json\n${JSON.stringify(content.input, null, 2)}\n\`\`\`\n\n`; |
| 356 | } |
| 357 | } |
| 358 | if (msg.message.usage) { |
| 359 | markdown += `*Tokens: ${msg.message.usage.input_tokens} in, ${msg.message.usage.output_tokens} out*\n\n`; |
| 360 | } |
| 361 | } else if (msg.type === "user" && msg.message) { |
| 362 | markdown += `## User\n\n`; |
| 363 | for (const content of msg.message.content || []) { |
| 364 | if (content.type === "text") { |
| 365 | markdown += `${content.text}\n\n`; |
| 366 | } else if (content.type === "tool_result") { |
| 367 | markdown += `### Tool Result\n\n`; |
| 368 | markdown += `\`\`\`\n${content.content}\n\`\`\`\n\n`; |
| 369 | } |
| 370 | } |
| 371 | } else if (msg.type === "result") { |
| 372 | markdown += `## Execution Result\n\n`; |
| 373 | if (msg.result) { |
| 374 | markdown += `${msg.result}\n\n`; |
| 375 | } |
| 376 | if (msg.error) { |
| 377 | markdown += `**Error:** ${msg.error}\n\n`; |
| 378 | } |
| 379 | } |
| 380 | } |
| 381 | |
| 382 | await navigator.clipboard.writeText(markdown); |
| 383 | setCopyPopoverOpen(false); |
| 384 | setToast({ message: 'Output copied as Markdown', type: 'success' }); |
| 385 | }; |
| 386 |
nothing calls this directly
no test coverage detected