logger.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /**
  2. * Multi-Agent Logging System - Logger
  3. *
  4. * Pretty-prints delegation hierarchies with visual indentation and formatting.
  5. */
  6. import { SessionTracker } from './session-tracker.js';
  7. import {
  8. formatSessionHeader,
  9. formatMessage,
  10. formatToolCall,
  11. formatDelegation,
  12. formatChildLinked,
  13. formatSessionComplete,
  14. formatSystemMessage,
  15. } from './formatters.js';
  16. /**
  17. * Multi-agent logger with hierarchy-aware formatting
  18. */
  19. export class MultiAgentLogger {
  20. private tracker: SessionTracker;
  21. private enabled: boolean;
  22. private verbose: boolean;
  23. constructor(enabled = true, verbose = false) {
  24. this.tracker = new SessionTracker();
  25. this.enabled = enabled;
  26. this.verbose = verbose;
  27. }
  28. /**
  29. * Log session start
  30. */
  31. logSessionStart(sessionId: string, agent: string, parentId?: string): void {
  32. if (!this.enabled) return;
  33. this.tracker.registerSession(sessionId, agent, parentId);
  34. const node = this.tracker.getSession(sessionId);
  35. if (!node) return;
  36. // Only log session headers in verbose mode
  37. if (this.verbose) {
  38. const header = formatSessionHeader(sessionId, agent, node.depth, parentId);
  39. console.log(header);
  40. }
  41. }
  42. /**
  43. * Log delegation event
  44. */
  45. logDelegation(
  46. parentSessionId: string,
  47. toAgent: string,
  48. prompt: string
  49. ): string {
  50. if (!this.enabled) return '';
  51. const delegationId = this.tracker.recordDelegation(parentSessionId, toAgent, prompt);
  52. const node = this.tracker.getSession(parentSessionId);
  53. const depth = node?.depth ?? 0;
  54. // Only log delegation details in verbose mode
  55. if (this.verbose) {
  56. const formatted = formatDelegation(toAgent, prompt, depth);
  57. console.log(formatted);
  58. }
  59. return delegationId;
  60. }
  61. /**
  62. * Log child session linked to delegation
  63. */
  64. logChildLinked(delegationId: string, childSessionId: string): void {
  65. if (!this.enabled) return;
  66. this.tracker.linkChildSession(delegationId, childSessionId);
  67. const delegation = this.tracker.getDelegation(delegationId);
  68. if (!delegation) return;
  69. const parent = this.tracker.getSession(delegation.parentSessionId);
  70. const depth = parent?.depth ?? 0;
  71. // Always log child session link (important for delegation visibility)
  72. const formatted = formatChildLinked(childSessionId, depth, this.verbose);
  73. console.log(formatted);
  74. }
  75. /**
  76. * Log user or assistant message
  77. */
  78. logMessage(sessionId: string, role: 'user' | 'assistant', text: string): void {
  79. if (!this.enabled) return;
  80. // Only log messages in verbose mode
  81. if (!this.verbose) return;
  82. const node = this.tracker.getSession(sessionId);
  83. const depth = node?.depth ?? 0;
  84. const formatted = formatMessage(role, text, depth);
  85. console.log(formatted);
  86. }
  87. /**
  88. * Log tool call
  89. */
  90. logToolCall(sessionId: string, tool: string, input: any): void {
  91. if (!this.enabled) return;
  92. // Skip logging task tool (handled by logDelegation)
  93. if (tool === 'task') return;
  94. // Only log tool calls in verbose mode
  95. if (!this.verbose) return;
  96. const node = this.tracker.getSession(sessionId);
  97. const depth = node?.depth ?? 0;
  98. const formatted = formatToolCall(tool, input, depth);
  99. console.log(formatted);
  100. }
  101. /**
  102. * Log session completion
  103. */
  104. logSessionComplete(sessionId: string): void {
  105. if (!this.enabled) return;
  106. const node = this.tracker.getSession(sessionId);
  107. if (!node) return;
  108. this.tracker.completeSession(sessionId);
  109. const duration = node.endTime
  110. ? node.endTime - node.startTime
  111. : Date.now() - node.startTime;
  112. const sessionType = node.depth === 0 ? 'PARENT' : 'CHILD';
  113. // Always log child session completion (important for delegation visibility)
  114. // Only log parent completion in verbose mode
  115. if (sessionType === 'CHILD' || this.verbose) {
  116. const formatted = formatSessionComplete(sessionType, duration, node.depth, node.agent, this.verbose);
  117. console.log(formatted);
  118. }
  119. }
  120. /**
  121. * Log system message
  122. */
  123. logSystem(sessionId: string, message: string): void {
  124. if (!this.enabled) return;
  125. // Only log system messages in verbose mode
  126. if (!this.verbose) return;
  127. const node = this.tracker.getSession(sessionId);
  128. const depth = node?.depth ?? 0;
  129. const formatted = formatSystemMessage(message, depth);
  130. console.log(formatted);
  131. }
  132. /**
  133. * Get the session tracker for analysis
  134. */
  135. getTracker(): SessionTracker {
  136. return this.tracker;
  137. }
  138. /**
  139. * Enable or disable logging
  140. */
  141. setEnabled(enabled: boolean): void {
  142. this.enabled = enabled;
  143. }
  144. /**
  145. * Check if logging is enabled
  146. */
  147. isEnabled(): boolean {
  148. return this.enabled;
  149. }
  150. /**
  151. * Clear all tracked data
  152. */
  153. clear(): void {
  154. this.tracker.clear();
  155. }
  156. }