formatters.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /**
  2. * Multi-Agent Logging System - Formatters
  3. *
  4. * Visual formatting utilities for pretty-printing delegation hierarchies.
  5. */
  6. /**
  7. * Format a session header with box drawing
  8. */
  9. export function formatSessionHeader(
  10. sessionId: string,
  11. agent: string,
  12. depth: number,
  13. parentId?: string
  14. ): string {
  15. const indent = ' '.repeat(depth);
  16. const type = depth === 0 ? 'PARENT' : 'CHILD';
  17. const shortId = sessionId.substring(0, 12);
  18. const boxWidth = 60;
  19. let header = `\n${indent}┌${'─'.repeat(boxWidth)}┐\n`;
  20. header += `${indent}│ 🎯 ${type}: ${agent} (${shortId}...)`;
  21. // Pad to box width
  22. const contentLength = ` 🎯 ${type}: ${agent} (${shortId}...)`.length;
  23. const padding = boxWidth - contentLength;
  24. header += ' '.repeat(Math.max(0, padding)) + '│\n';
  25. if (parentId) {
  26. const shortParent = parentId.substring(0, 12);
  27. header += `${indent}│ Parent: ${shortParent}...`;
  28. const parentLineLength = ` Parent: ${shortParent}...`.length;
  29. const parentPadding = boxWidth - parentLineLength;
  30. header += ' '.repeat(Math.max(0, parentPadding)) + '│\n';
  31. header += `${indent}│ Depth: ${depth}`;
  32. const depthLineLength = ` Depth: ${depth}`.length;
  33. const depthPadding = boxWidth - depthLineLength;
  34. header += ' '.repeat(Math.max(0, depthPadding)) + '│\n';
  35. }
  36. header += `${indent}└${'─'.repeat(boxWidth)}┘`;
  37. return header;
  38. }
  39. /**
  40. * Format a message with emoji and indentation
  41. */
  42. export function formatMessage(
  43. role: 'user' | 'assistant',
  44. text: string,
  45. depth: number
  46. ): string {
  47. const indent = ' '.repeat(depth + 1);
  48. const emoji = role === 'user' ? '📝' : '🤖';
  49. const label = role === 'user' ? 'User' : 'Agent';
  50. // Truncate long messages
  51. const maxLength = 80;
  52. const displayText = text.length > maxLength
  53. ? text.substring(0, maxLength) + '...'
  54. : text;
  55. return `${indent}${emoji} ${label}: ${displayText}`;
  56. }
  57. /**
  58. * Format a tool call with indentation
  59. */
  60. export function formatToolCall(
  61. tool: string,
  62. input: any,
  63. depth: number
  64. ): string {
  65. const indent = ' '.repeat(depth + 1);
  66. let output = `${indent}🔧 TOOL: ${tool}`;
  67. // Add relevant input details
  68. if (input?.filePath) {
  69. output += `\n${indent} └─ file: ${input.filePath}`;
  70. } else if (input?.pattern) {
  71. output += `\n${indent} └─ pattern: ${input.pattern}`;
  72. } else if (input?.command) {
  73. const cmd = input.command.substring(0, 50);
  74. output += `\n${indent} └─ command: ${cmd}${input.command.length > 50 ? '...' : ''}`;
  75. }
  76. return output;
  77. }
  78. /**
  79. * Format a delegation event
  80. */
  81. export function formatDelegation(
  82. toAgent: string,
  83. prompt: string,
  84. depth: number
  85. ): string {
  86. const indent = ' '.repeat(depth + 1);
  87. // Truncate long prompts
  88. const maxLength = 50;
  89. const displayPrompt = prompt.length > maxLength
  90. ? prompt.substring(0, maxLength) + '...'
  91. : prompt;
  92. let output = `\n${indent}🔧 TOOL: task\n`;
  93. output += `${indent} ├─ subagent: ${toAgent}\n`;
  94. output += `${indent} ├─ prompt: ${displayPrompt}\n`;
  95. output += `${indent} └─ Creating child session...`;
  96. return output;
  97. }
  98. /**
  99. * Format child session linked message
  100. */
  101. export function formatChildLinked(
  102. childSessionId: string,
  103. depth: number,
  104. verbose: boolean = false
  105. ): string {
  106. if (verbose) {
  107. // Verbose mode: show full details with indentation
  108. const indent = ' '.repeat(depth + 1);
  109. const shortId = childSessionId.substring(0, 12);
  110. return `${indent} └─ Child session: ${shortId}...`;
  111. } else {
  112. // Non-verbose mode: show concise message
  113. const shortId = childSessionId.substring(0, 12);
  114. return ` → Child agent started (session: ${shortId}...)`;
  115. }
  116. }
  117. /**
  118. * Format session completion
  119. */
  120. export function formatSessionComplete(
  121. sessionType: 'PARENT' | 'CHILD',
  122. duration: number,
  123. depth: number,
  124. agent?: string,
  125. verbose: boolean = false
  126. ): string {
  127. if (verbose) {
  128. // Verbose mode: show full details with indentation
  129. const indent = ' '.repeat(depth);
  130. const durationSec = (duration / 1000).toFixed(1);
  131. return `${indent}✅ ${sessionType} COMPLETE (${durationSec}s)\n`;
  132. } else {
  133. // Non-verbose mode: show concise message for child sessions only
  134. const durationSec = (duration / 1000).toFixed(1);
  135. const agentName = agent || 'child agent';
  136. return ` ✓ Child agent completed (${agentName}, ${durationSec}s)`;
  137. }
  138. }
  139. /**
  140. * Format a system message
  141. */
  142. export function formatSystemMessage(
  143. message: string,
  144. depth: number
  145. ): string {
  146. const indent = ' '.repeat(depth + 1);
  147. return `${indent}ℹ️ ${message}`;
  148. }