fix(langchain): serialize ToolMessage/FunctionMessage with correct role and tool_call_id - #950
Open
milanagm wants to merge 2 commits into
Conversation
…le and tool_call_id
|
@milanagm is attempting to deploy a commit to the langfuse Team on Vercel. A member of the Team first needs to authorize it. |
…oolmessage-serialized-without-role-and Resolved conflict in tests/integration/langchain.integration.test.ts: kept main's two completion-start-time tests (langfuse#948) alongside the new tool/function message serialization test, and merged the @langchain/core/messages import into a single declaration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
extractChatMessageContentin the LangChainCallbackHandlerserializesToolMessageandFunctionMessagewithrole: message.name.nameis optional onToolMessage, and idiomatic usage (new ToolMessage({ content, tool_call_id })) never sets it, so the serialized message ends up with no role at all. Whennameis set, the role becomes the tool's function name (e.g."get_debt"), not a valid ChatML role. On top of that,tool_call_idwas dropped entirely: it's a top-level field onToolMessage, not part ofadditional_kwargs.This breaks "Open in Playground" for any generation whose history contains tool results. The web playground converter (
playgroundConverter.ts) only maps a message to aToolResultwhen it finds atool_call_id, and otherwise falls back torole || ChatMessageRole.Assistant, so tool results render as plain assistant messages and re-running the completion loses the tool linkage.Fixes #930
Linear: https://linear.app/clickhouse/issue/LFE-15880/langchain-toolmessage-serialized-without-role-and-tool-call-id-breaks
Changes
ToolMessage→{ role: "tool", name, content, additional_kwargs, tool_call_id }FunctionMessage(same pattern one branch above) →{ role: "function", name, content, additional_kwargs }nameis kept as its own field rather than dropped, matching what LangChain itself sends to the OpenAI Chat Completions API and what the Python SDK's_convert_message_to_dictalready does forToolMessage/FunctionMessage.LlmMessagetype with optionalnameandtool_call_idfields instead of attaching them withas any.Verification
pnpm lintpnpm typecheckpnpm testpnpm test:integrationpnpm test:e2e(not run: requires a reachable Langfuse server and API credentials not available in this environment)pnpm format:checkAlso verified end-to-end against a local Langfuse instance using the exact history from the issue: before the fix, the
ToolMessagehistory opens in the Playground as a plain Assistant message with no tool linkage; after the fix, it opens as a Tool message linked to the originating tool call (call_1).Release info
Bump level
Libraries affected
Changelog notes
@langfuse/langchainserializingToolMessage/FunctionMessagewithout a validroleand droppingtool_call_id, which broke "Open in Playground" for traces containing tool results.The PR appears safe to merge with no actionable correctness, security, or repository-rule issues identified.
Summary
role: "tool", optionalname, and top-leveltool_call_id.role: "function"and preservesnameseparately.LlmMessagewith typed optional metadata fields.Reviews (1) · Last reviewed commit: "fix(langchain): serialize ToolMessage/Fu..."