console.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import styles from "ansi-styles";
  2. import { BaseTracer } from "./base.js";
  3. function wrap(style, text) {
  4. return `${style.open}${text}${style.close}`;
  5. }
  6. function tryJsonStringify(obj, fallback) {
  7. try {
  8. return JSON.stringify(obj, null, 2);
  9. }
  10. catch (err) {
  11. return fallback;
  12. }
  13. }
  14. function formatKVMapItem(value) {
  15. if (typeof value === "string") {
  16. return value.trim();
  17. }
  18. if (value === null || value === undefined) {
  19. return value;
  20. }
  21. return tryJsonStringify(value, value.toString());
  22. }
  23. function elapsed(run) {
  24. if (!run.end_time)
  25. return "";
  26. const elapsed = run.end_time - run.start_time;
  27. if (elapsed < 1000) {
  28. return `${elapsed}ms`;
  29. }
  30. return `${(elapsed / 1000).toFixed(2)}s`;
  31. }
  32. const { color } = styles;
  33. /**
  34. * A tracer that logs all events to the console. It extends from the
  35. * `BaseTracer` class and overrides its methods to provide custom logging
  36. * functionality.
  37. * @example
  38. * ```typescript
  39. *
  40. * const llm = new ChatAnthropic({
  41. * temperature: 0,
  42. * tags: ["example", "callbacks", "constructor"],
  43. * callbacks: [new ConsoleCallbackHandler()],
  44. * });
  45. *
  46. * ```
  47. */
  48. export class ConsoleCallbackHandler extends BaseTracer {
  49. constructor() {
  50. super(...arguments);
  51. Object.defineProperty(this, "name", {
  52. enumerable: true,
  53. configurable: true,
  54. writable: true,
  55. value: "console_callback_handler"
  56. });
  57. }
  58. /**
  59. * Method used to persist the run. In this case, it simply returns a
  60. * resolved promise as there's no persistence logic.
  61. * @param _run The run to persist.
  62. * @returns A resolved promise.
  63. */
  64. persistRun(_run) {
  65. return Promise.resolve();
  66. }
  67. // utility methods
  68. /**
  69. * Method used to get all the parent runs of a given run.
  70. * @param run The run whose parents are to be retrieved.
  71. * @returns An array of parent runs.
  72. */
  73. getParents(run) {
  74. const parents = [];
  75. let currentRun = run;
  76. while (currentRun.parent_run_id) {
  77. const parent = this.runMap.get(currentRun.parent_run_id);
  78. if (parent) {
  79. parents.push(parent);
  80. currentRun = parent;
  81. }
  82. else {
  83. break;
  84. }
  85. }
  86. return parents;
  87. }
  88. /**
  89. * Method used to get a string representation of the run's lineage, which
  90. * is used in logging.
  91. * @param run The run whose lineage is to be retrieved.
  92. * @returns A string representation of the run's lineage.
  93. */
  94. getBreadcrumbs(run) {
  95. const parents = this.getParents(run).reverse();
  96. const string = [...parents, run]
  97. .map((parent, i, arr) => {
  98. const name = `${parent.execution_order}:${parent.run_type}:${parent.name}`;
  99. return i === arr.length - 1 ? wrap(styles.bold, name) : name;
  100. })
  101. .join(" > ");
  102. return wrap(color.grey, string);
  103. }
  104. // logging methods
  105. /**
  106. * Method used to log the start of a chain run.
  107. * @param run The chain run that has started.
  108. * @returns void
  109. */
  110. onChainStart(run) {
  111. const crumbs = this.getBreadcrumbs(run);
  112. console.log(`${wrap(color.green, "[chain/start]")} [${crumbs}] Entering Chain run with input: ${tryJsonStringify(run.inputs, "[inputs]")}`);
  113. }
  114. /**
  115. * Method used to log the end of a chain run.
  116. * @param run The chain run that has ended.
  117. * @returns void
  118. */
  119. onChainEnd(run) {
  120. const crumbs = this.getBreadcrumbs(run);
  121. console.log(`${wrap(color.cyan, "[chain/end]")} [${crumbs}] [${elapsed(run)}] Exiting Chain run with output: ${tryJsonStringify(run.outputs, "[outputs]")}`);
  122. }
  123. /**
  124. * Method used to log any errors of a chain run.
  125. * @param run The chain run that has errored.
  126. * @returns void
  127. */
  128. onChainError(run) {
  129. const crumbs = this.getBreadcrumbs(run);
  130. console.log(`${wrap(color.red, "[chain/error]")} [${crumbs}] [${elapsed(run)}] Chain run errored with error: ${tryJsonStringify(run.error, "[error]")}`);
  131. }
  132. /**
  133. * Method used to log the start of an LLM run.
  134. * @param run The LLM run that has started.
  135. * @returns void
  136. */
  137. onLLMStart(run) {
  138. const crumbs = this.getBreadcrumbs(run);
  139. const inputs = "prompts" in run.inputs
  140. ? { prompts: run.inputs.prompts.map((p) => p.trim()) }
  141. : run.inputs;
  142. console.log(`${wrap(color.green, "[llm/start]")} [${crumbs}] Entering LLM run with input: ${tryJsonStringify(inputs, "[inputs]")}`);
  143. }
  144. /**
  145. * Method used to log the end of an LLM run.
  146. * @param run The LLM run that has ended.
  147. * @returns void
  148. */
  149. onLLMEnd(run) {
  150. const crumbs = this.getBreadcrumbs(run);
  151. console.log(`${wrap(color.cyan, "[llm/end]")} [${crumbs}] [${elapsed(run)}] Exiting LLM run with output: ${tryJsonStringify(run.outputs, "[response]")}`);
  152. }
  153. /**
  154. * Method used to log any errors of an LLM run.
  155. * @param run The LLM run that has errored.
  156. * @returns void
  157. */
  158. onLLMError(run) {
  159. const crumbs = this.getBreadcrumbs(run);
  160. console.log(`${wrap(color.red, "[llm/error]")} [${crumbs}] [${elapsed(run)}] LLM run errored with error: ${tryJsonStringify(run.error, "[error]")}`);
  161. }
  162. /**
  163. * Method used to log the start of a tool run.
  164. * @param run The tool run that has started.
  165. * @returns void
  166. */
  167. onToolStart(run) {
  168. const crumbs = this.getBreadcrumbs(run);
  169. console.log(`${wrap(color.green, "[tool/start]")} [${crumbs}] Entering Tool run with input: "${formatKVMapItem(run.inputs.input)}"`);
  170. }
  171. /**
  172. * Method used to log the end of a tool run.
  173. * @param run The tool run that has ended.
  174. * @returns void
  175. */
  176. onToolEnd(run) {
  177. const crumbs = this.getBreadcrumbs(run);
  178. console.log(`${wrap(color.cyan, "[tool/end]")} [${crumbs}] [${elapsed(run)}] Exiting Tool run with output: "${formatKVMapItem(run.outputs?.output)}"`);
  179. }
  180. /**
  181. * Method used to log any errors of a tool run.
  182. * @param run The tool run that has errored.
  183. * @returns void
  184. */
  185. onToolError(run) {
  186. const crumbs = this.getBreadcrumbs(run);
  187. console.log(`${wrap(color.red, "[tool/error]")} [${crumbs}] [${elapsed(run)}] Tool run errored with error: ${tryJsonStringify(run.error, "[error]")}`);
  188. }
  189. /**
  190. * Method used to log the start of a retriever run.
  191. * @param run The retriever run that has started.
  192. * @returns void
  193. */
  194. onRetrieverStart(run) {
  195. const crumbs = this.getBreadcrumbs(run);
  196. console.log(`${wrap(color.green, "[retriever/start]")} [${crumbs}] Entering Retriever run with input: ${tryJsonStringify(run.inputs, "[inputs]")}`);
  197. }
  198. /**
  199. * Method used to log the end of a retriever run.
  200. * @param run The retriever run that has ended.
  201. * @returns void
  202. */
  203. onRetrieverEnd(run) {
  204. const crumbs = this.getBreadcrumbs(run);
  205. console.log(`${wrap(color.cyan, "[retriever/end]")} [${crumbs}] [${elapsed(run)}] Exiting Retriever run with output: ${tryJsonStringify(run.outputs, "[outputs]")}`);
  206. }
  207. /**
  208. * Method used to log any errors of a retriever run.
  209. * @param run The retriever run that has errored.
  210. * @returns void
  211. */
  212. onRetrieverError(run) {
  213. const crumbs = this.getBreadcrumbs(run);
  214. console.log(`${wrap(color.red, "[retriever/error]")} [${crumbs}] [${elapsed(run)}] Retriever run errored with error: ${tryJsonStringify(run.error, "[error]")}`);
  215. }
  216. /**
  217. * Method used to log the action selected by the agent.
  218. * @param run The run in which the agent action occurred.
  219. * @returns void
  220. */
  221. onAgentAction(run) {
  222. const agentRun = run;
  223. const crumbs = this.getBreadcrumbs(run);
  224. console.log(`${wrap(color.blue, "[agent/action]")} [${crumbs}] Agent selected action: ${tryJsonStringify(agentRun.actions[agentRun.actions.length - 1], "[action]")}`);
  225. }
  226. }