From be5f191f139a44a8f9021e40c2f318326c45eeae Mon Sep 17 00:00:00 2001 From: Jacob Lee Date: Wed, 17 Jul 2024 17:40:35 -0700 Subject: [PATCH] core[patch]: Improve console.log format for messages (#6121) * Improve console.log format for messages * Fix lint * Fix console.dir case --- langchain-core/src/messages/ai.ts | 19 ++++++++ langchain-core/src/messages/base.ts | 61 +++++++++++++++++++++++++ langchain-core/src/messages/chat.ts | 14 ++++++ langchain-core/src/messages/modifier.ts | 7 +++ langchain-core/src/messages/tool.ts | 16 +++++++ 5 files changed, 117 insertions(+) diff --git a/langchain-core/src/messages/ai.ts b/langchain-core/src/messages/ai.ts index a0148dd2dd3c..2ba47ff7ff2a 100644 --- a/langchain-core/src/messages/ai.ts +++ b/langchain-core/src/messages/ai.ts @@ -128,6 +128,15 @@ export class AIMessage extends BaseMessage { _getType(): MessageType { return "ai"; } + + override get _printableFields(): Record { + return { + ...super._printableFields, + tool_calls: this.tool_calls, + invalid_tool_calls: this.invalid_tool_calls, + usage_metadata: this.usage_metadata, + }; + } } export function isAIMessage(x: BaseMessage): x is AIMessage { @@ -234,6 +243,16 @@ export class AIMessageChunk extends BaseMessageChunk { return "ai"; } + override get _printableFields(): Record { + return { + ...super._printableFields, + tool_calls: this.tool_calls, + tool_call_chunks: this.tool_call_chunks, + invalid_tool_calls: this.invalid_tool_calls, + usage_metadata: this.usage_metadata, + }; + } + concat(chunk: AIMessageChunk) { const combinedFields: AIMessageChunkFields = { content: mergeContent(this.content, chunk.content), diff --git a/langchain-core/src/messages/base.ts b/langchain-core/src/messages/base.ts index c09e15c372b6..a0f9ca1e3640 100644 --- a/langchain-core/src/messages/base.ts +++ b/langchain-core/src/messages/base.ts @@ -140,6 +140,34 @@ export function mergeContent( } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function stringifyWithDepthLimit(obj: any, depthLimit: number): string { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function helper(obj: any, currentDepth: number): any { + if (typeof obj !== "object" || obj === null || obj === undefined) { + return obj; + } + if (currentDepth >= depthLimit) { + if (Array.isArray(obj)) { + return "[Array]"; + } + return "[Object]"; + } + + if (Array.isArray(obj)) { + return obj.map((item) => helper(item, currentDepth + 1)); + } + + const result: Record = {}; + for (const key of Object.keys(obj)) { + result[key] = helper(obj[key], currentDepth + 1); + } + return result; + } + + return JSON.stringify(helper(obj, 0), null, 2); +} + /** * Base class for all types of messages in a conversation. It includes * properties like `content`, `name`, and `additional_kwargs`. It also @@ -227,6 +255,39 @@ export abstract class BaseMessage .kwargs as StoredMessageData, }; } + + static lc_name() { + return "BaseMessage"; + } + + // Can't be protected for silly reasons + get _printableFields(): Record { + return { + id: this.id, + content: this.content, + name: this.name, + additional_kwargs: this.additional_kwargs, + response_metadata: this.response_metadata, + }; + } + + get [Symbol.toStringTag]() { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (this.constructor as any).lc_name(); + } + + // Override the default behavior of console.log + [Symbol.for("nodejs.util.inspect.custom")](depth: number | null) { + if (depth === null) { + return this; + } + const printable = stringifyWithDepthLimit( + this._printableFields, + Math.max(4, depth) + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return `${(this.constructor as any).lc_name()} ${printable}`; + } } // TODO: Deprecate when SDK typing is updated diff --git a/langchain-core/src/messages/chat.ts b/langchain-core/src/messages/chat.ts index fb71956e6f8d..7c3f80492389 100644 --- a/langchain-core/src/messages/chat.ts +++ b/langchain-core/src/messages/chat.ts @@ -48,6 +48,13 @@ export class ChatMessage static isInstance(message: BaseMessage): message is ChatMessage { return message._getType() === "generic"; } + + override get _printableFields(): Record { + return { + ...super._printableFields, + role: this.role, + }; + } } /** @@ -93,4 +100,11 @@ export class ChatMessageChunk extends BaseMessageChunk { id: this.id ?? chunk.id, }); } + + override get _printableFields(): Record { + return { + ...super._printableFields, + role: this.role, + }; + } } diff --git a/langchain-core/src/messages/modifier.ts b/langchain-core/src/messages/modifier.ts index 13737086a267..aab91151a8fb 100644 --- a/langchain-core/src/messages/modifier.ts +++ b/langchain-core/src/messages/modifier.ts @@ -28,4 +28,11 @@ export class RemoveMessage extends BaseMessage { _getType(): MessageType { return "remove"; } + + override get _printableFields(): Record { + return { + ...super._printableFields, + id: this.id, + }; + } } diff --git a/langchain-core/src/messages/tool.ts b/langchain-core/src/messages/tool.ts index 482b2fa54d57..61b24891780f 100644 --- a/langchain-core/src/messages/tool.ts +++ b/langchain-core/src/messages/tool.ts @@ -75,6 +75,14 @@ export class ToolMessage extends BaseMessage { static isInstance(message: BaseMessage): message is ToolMessage { return message._getType() === "tool"; } + + override get _printableFields(): Record { + return { + ...super._printableFields, + tool_call_id: this.tool_call_id, + artifact: this.artifact, + }; + } } /** @@ -124,6 +132,14 @@ export class ToolMessageChunk extends BaseMessageChunk { id: this.id ?? chunk.id, }); } + + override get _printableFields(): Record { + return { + ...super._printableFields, + tool_call_id: this.tool_call_id, + artifact: this.artifact, + }; + } } /**