Skip to content

Commit 5703efc

Browse files
fix(@langchain/cerebras): recognize ToolMessage responses (#8925)
Co-authored-by: Hunter Lovell <[email protected]>
1 parent 6da726f commit 5703efc

File tree

3 files changed

+151
-11
lines changed

3 files changed

+151
-11
lines changed

.changeset/kind-fireants-retire.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@langchain/cerebras": patch
3+
---
4+
5+
recognize ToolMessage responses
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { test, expect, describe } from "@jest/globals";
2+
import {
3+
HumanMessage,
4+
AIMessage,
5+
SystemMessage,
6+
ToolMessage,
7+
} from "@langchain/core/messages";
8+
import { convertToCerebrasMessageParams } from "../utils.js";
9+
10+
describe("convertToCerebrasMessageParams", () => {
11+
test("should convert ToolMessage with content properly", () => {
12+
const toolMessage = new ToolMessage({
13+
content: "42",
14+
tool_call_id: "139485753823DJDB#JXJX",
15+
name: "count_globules",
16+
});
17+
18+
const result = convertToCerebrasMessageParams([toolMessage]);
19+
20+
expect(result).toHaveLength(1);
21+
expect(result[0]).toEqual({
22+
role: "tool",
23+
content: "42",
24+
tool_call_id: "139485753823DJDB#JXJX",
25+
});
26+
});
27+
28+
test("should convert a full conversation with tool calls", () => {
29+
const messages = [
30+
new HumanMessage(
31+
"Please tell me the current number of globules in the environment."
32+
),
33+
new AIMessage({
34+
content: "",
35+
tool_calls: [
36+
{
37+
id: "139485753823DJDB#JXJX",
38+
name: "count_globules",
39+
args: {},
40+
type: "tool_call",
41+
},
42+
],
43+
}),
44+
new ToolMessage({
45+
content: "42",
46+
tool_call_id: "139485753823DJDB#JXJX",
47+
name: "count_globules",
48+
}),
49+
];
50+
51+
const result = convertToCerebrasMessageParams(messages);
52+
53+
expect(result).toHaveLength(3);
54+
55+
// Check human message
56+
expect(result[0]).toEqual({
57+
role: "user",
58+
content:
59+
"Please tell me the current number of globules in the environment.",
60+
});
61+
62+
// Check AI message with tool calls
63+
expect(result[1]).toEqual({
64+
role: "assistant",
65+
tool_calls: [
66+
{
67+
id: "139485753823DJDB#JXJX",
68+
type: "function",
69+
function: {
70+
name: "count_globules",
71+
arguments: "{}",
72+
},
73+
},
74+
],
75+
content: "",
76+
});
77+
78+
// Check tool message
79+
expect(result[2]).toEqual({
80+
role: "tool",
81+
content: "42",
82+
tool_call_id: "139485753823DJDB#JXJX",
83+
});
84+
});
85+
86+
test("should throw error for non-string tool message content", () => {
87+
const toolMessage = new ToolMessage({
88+
content: [
89+
{ type: "text", text: "array" },
90+
{ type: "text", text: "content" },
91+
],
92+
tool_call_id: "test-id",
93+
name: "test-tool",
94+
});
95+
96+
expect(() => convertToCerebrasMessageParams([toolMessage])).toThrow(
97+
"Non string tool message content is not supported"
98+
);
99+
});
100+
101+
test("should handle system messages", () => {
102+
const systemMessage = new SystemMessage("You are a helpful assistant.");
103+
104+
const result = convertToCerebrasMessageParams([systemMessage]);
105+
106+
expect(result).toHaveLength(1);
107+
expect(result[0]).toEqual({
108+
role: "system",
109+
content: "You are a helpful assistant.",
110+
});
111+
});
112+
});

libs/langchain-cerebras/src/utils.ts

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ function convertAIMessageToCerebras(
6262
);
6363

6464
if (typeof messages.content === "string") {
65+
// Check if there are tool calls even with string content
66+
if (messages.tool_calls?.length) {
67+
const toolCalls: CerebrasToolCall[] = messages.tool_calls.map((tc) => ({
68+
id: tc.id!,
69+
type: "function",
70+
function: {
71+
name: tc.name,
72+
arguments: JSON.stringify(tc.args),
73+
},
74+
}));
75+
return [
76+
{
77+
role: "assistant",
78+
content: messages.content,
79+
tool_calls: toolCalls,
80+
},
81+
];
82+
}
6583
return [
6684
{
6785
role: "assistant",
@@ -117,11 +135,11 @@ function convertHumanGenericMessagesToCerebras(
117135
},
118136
];
119137
}
120-
return message.content.map((c) => {
138+
return message.content.map((c): CerebrasMessageParam => {
121139
if (c.type === "text") {
122140
return {
123141
role: "user",
124-
content: c.text,
142+
content: c.text as string,
125143
};
126144
} else if (c.type === "image_url") {
127145
if (typeof c.image_url === "string") {
@@ -130,7 +148,12 @@ function convertHumanGenericMessagesToCerebras(
130148
content: "",
131149
images: [extractBase64FromDataUrl(c.image_url)],
132150
};
133-
} else if (c.image_url.url && typeof c.image_url.url === "string") {
151+
} else if (
152+
typeof c.image_url === "object" &&
153+
c.image_url !== null &&
154+
"url" in c.image_url &&
155+
typeof c.image_url.url === "string"
156+
) {
134157
return {
135158
role: "user",
136159
content: "",
@@ -189,16 +212,16 @@ export function convertToCerebrasMessageParams(
189212
messages: BaseMessage[]
190213
): CerebrasMessageParam[] {
191214
return messages.flatMap((msg) => {
192-
if (["human", "generic"].includes(msg._getType())) {
193-
return convertHumanGenericMessagesToCerebras(msg);
194-
} else if (msg._getType() === "ai") {
195-
return convertAIMessageToCerebras(msg);
196-
} else if (msg._getType() === "system") {
197-
return convertSystemMessageToCerebras(msg);
198-
} else if (msg._getType() === "tool") {
215+
if (["human", "generic"].includes(msg.getType())) {
216+
return convertHumanGenericMessagesToCerebras(msg as HumanMessage);
217+
} else if (msg.getType() === "ai") {
218+
return convertAIMessageToCerebras(msg as AIMessage);
219+
} else if (msg.getType() === "system") {
220+
return convertSystemMessageToCerebras(msg as SystemMessage);
221+
} else if (msg.getType() === "tool") {
199222
return convertToolMessageToCerebras(msg as ToolMessage);
200223
} else {
201-
throw new Error(`Unsupported message type: ${msg._getType()}`);
224+
throw new Error(`Unsupported message type: ${msg.getType()}`);
202225
}
203226
});
204227
}

0 commit comments

Comments
 (0)