@langchain/core 0.2.15 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/caches.cjs +1 -1
- package/caches.d.cts +1 -1
- package/caches.d.ts +1 -1
- package/caches.js +1 -1
- package/callbacks/dispatch/web.cjs +1 -0
- package/callbacks/dispatch/web.d.cts +1 -0
- package/callbacks/dispatch/web.d.ts +1 -0
- package/callbacks/dispatch/web.js +1 -0
- package/callbacks/dispatch.cjs +1 -0
- package/callbacks/dispatch.d.cts +1 -0
- package/callbacks/dispatch.d.ts +1 -0
- package/callbacks/dispatch.js +1 -0
- package/dist/{caches.cjs → caches/base.cjs} +6 -6
- package/dist/{caches.d.ts → caches/base.d.ts} +7 -7
- package/dist/{caches.js → caches/base.js} +6 -6
- package/dist/caches/tests/in_memory_cache.test.d.ts +1 -0
- package/dist/caches/tests/in_memory_cache.test.js +33 -0
- package/dist/callbacks/base.cjs +8 -0
- package/dist/callbacks/base.d.ts +16 -10
- package/dist/callbacks/base.js +8 -0
- package/dist/callbacks/dispatch/index.cjs +49 -0
- package/dist/callbacks/dispatch/index.d.ts +35 -0
- package/dist/callbacks/dispatch/index.js +45 -0
- package/dist/callbacks/dispatch/web.cjs +61 -0
- package/dist/callbacks/dispatch/web.d.ts +32 -0
- package/dist/callbacks/dispatch/web.js +57 -0
- package/dist/callbacks/manager.cjs +20 -0
- package/dist/callbacks/manager.d.ts +2 -1
- package/dist/callbacks/manager.js +20 -0
- package/dist/language_models/base.cjs +4 -4
- package/dist/language_models/base.d.ts +2 -2
- package/dist/language_models/base.js +1 -1
- package/dist/language_models/chat_models.d.ts +22 -5
- package/dist/language_models/llms.d.ts +1 -1
- package/dist/language_models/tests/chat_models.test.js +33 -0
- package/dist/load/import_map.cjs +2 -2
- package/dist/load/import_map.d.ts +2 -2
- package/dist/load/import_map.js +2 -2
- package/dist/messages/ai.cjs +19 -0
- package/dist/messages/ai.d.ts +2 -0
- package/dist/messages/ai.js +19 -0
- package/dist/messages/base.cjs +95 -5
- package/dist/messages/base.d.ts +5 -1
- package/dist/messages/base.js +93 -4
- package/dist/messages/chat.cjs +12 -0
- package/dist/messages/chat.d.ts +2 -0
- package/dist/messages/chat.js +12 -0
- package/dist/messages/index.cjs +1 -0
- package/dist/messages/index.d.ts +2 -1
- package/dist/messages/index.js +1 -0
- package/dist/messages/modifier.cjs +35 -0
- package/dist/messages/modifier.d.ts +19 -0
- package/dist/messages/modifier.js +31 -0
- package/dist/messages/tests/base_message.test.js +134 -2
- package/dist/messages/tests/message_utils.test.js +54 -2
- package/dist/messages/tool.cjs +45 -0
- package/dist/messages/tool.d.ts +29 -0
- package/dist/messages/tool.js +46 -1
- package/dist/messages/transformers.cjs +6 -0
- package/dist/messages/transformers.d.ts +3 -2
- package/dist/messages/transformers.js +6 -0
- package/dist/messages/utils.cjs +5 -1
- package/dist/messages/utils.js +5 -1
- package/dist/output_parsers/openai_tools/json_output_tools_parsers.cjs +2 -0
- package/dist/output_parsers/openai_tools/json_output_tools_parsers.js +2 -0
- package/dist/runnables/base.cjs +104 -1
- package/dist/runnables/base.d.ts +50 -0
- package/dist/runnables/base.js +101 -0
- package/dist/runnables/index.cjs +2 -1
- package/dist/runnables/index.d.ts +1 -1
- package/dist/runnables/index.js +1 -1
- package/dist/runnables/tests/runnable_stream_events.test.js +1 -1
- package/dist/runnables/tests/runnable_stream_events_v2.test.js +106 -1
- package/dist/runnables/tests/runnable_tools.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_tools.test.js +149 -0
- package/dist/{tools.cjs → tools/index.cjs} +135 -47
- package/dist/{tools.d.ts → tools/index.d.ts} +76 -47
- package/dist/{tools.js → tools/index.js} +134 -45
- package/dist/tools/tests/tools.test.d.ts +1 -0
- package/dist/tools/tests/tools.test.js +85 -0
- package/dist/tools/utils.cjs +28 -0
- package/dist/tools/utils.d.ts +11 -0
- package/dist/tools/utils.js +23 -0
- package/dist/tracers/base.cjs +1 -0
- package/dist/tracers/base.d.ts +1 -1
- package/dist/tracers/base.js +1 -0
- package/dist/tracers/event_stream.cjs +15 -0
- package/dist/tracers/event_stream.d.ts +1 -0
- package/dist/tracers/event_stream.js +15 -0
- package/dist/types/zod.cjs +2 -0
- package/dist/types/zod.d.ts +2 -0
- package/dist/types/zod.js +1 -0
- package/dist/utils/function_calling.cjs +38 -10
- package/dist/utils/function_calling.d.ts +32 -11
- package/dist/utils/function_calling.js +36 -9
- package/dist/utils/testing/index.cjs +10 -3
- package/dist/utils/testing/index.d.ts +1 -1
- package/dist/utils/testing/index.js +9 -2
- package/package.json +28 -1
- package/tools.cjs +1 -1
- package/tools.d.cts +1 -1
- package/tools.d.ts +1 -1
- package/tools.js +1 -1
package/dist/messages/base.js
CHANGED
|
@@ -11,14 +11,40 @@ export function mergeContent(firstContent, secondContent) {
|
|
|
11
11
|
// If both are arrays
|
|
12
12
|
}
|
|
13
13
|
else if (Array.isArray(secondContent)) {
|
|
14
|
-
return
|
|
15
|
-
|
|
14
|
+
return (_mergeLists(firstContent, secondContent) ?? [
|
|
15
|
+
...firstContent,
|
|
16
|
+
...secondContent,
|
|
17
|
+
]);
|
|
16
18
|
}
|
|
17
19
|
else {
|
|
18
20
|
// Otherwise, add the second content as a new element of the list
|
|
19
21
|
return [...firstContent, { type: "text", text: secondContent }];
|
|
20
22
|
}
|
|
21
23
|
}
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
25
|
+
function stringifyWithDepthLimit(obj, depthLimit) {
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
function helper(obj, currentDepth) {
|
|
28
|
+
if (typeof obj !== "object" || obj === null || obj === undefined) {
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
31
|
+
if (currentDepth >= depthLimit) {
|
|
32
|
+
if (Array.isArray(obj)) {
|
|
33
|
+
return "[Array]";
|
|
34
|
+
}
|
|
35
|
+
return "[Object]";
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(obj)) {
|
|
38
|
+
return obj.map((item) => helper(item, currentDepth + 1));
|
|
39
|
+
}
|
|
40
|
+
const result = {};
|
|
41
|
+
for (const key of Object.keys(obj)) {
|
|
42
|
+
result[key] = helper(obj[key], currentDepth + 1);
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
return JSON.stringify(helper(obj, 0), null, 2);
|
|
47
|
+
}
|
|
22
48
|
/**
|
|
23
49
|
* Base class for all types of messages in a conversation. It includes
|
|
24
50
|
* properties like `content`, `name`, and `additional_kwargs`. It also
|
|
@@ -123,6 +149,32 @@ export class BaseMessage extends Serializable {
|
|
|
123
149
|
.kwargs,
|
|
124
150
|
};
|
|
125
151
|
}
|
|
152
|
+
static lc_name() {
|
|
153
|
+
return "BaseMessage";
|
|
154
|
+
}
|
|
155
|
+
// Can't be protected for silly reasons
|
|
156
|
+
get _printableFields() {
|
|
157
|
+
return {
|
|
158
|
+
id: this.id,
|
|
159
|
+
content: this.content,
|
|
160
|
+
name: this.name,
|
|
161
|
+
additional_kwargs: this.additional_kwargs,
|
|
162
|
+
response_metadata: this.response_metadata,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
get [Symbol.toStringTag]() {
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
167
|
+
return this.constructor.lc_name();
|
|
168
|
+
}
|
|
169
|
+
// Override the default behavior of console.log
|
|
170
|
+
[Symbol.for("nodejs.util.inspect.custom")](depth) {
|
|
171
|
+
if (depth === null) {
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
const printable = stringifyWithDepthLimit(this._printableFields, Math.max(4, depth));
|
|
175
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
176
|
+
return `${this.constructor.lc_name()} ${printable}`;
|
|
177
|
+
}
|
|
126
178
|
}
|
|
127
179
|
export function isOpenAIToolCallArray(value) {
|
|
128
180
|
return (Array.isArray(value) &&
|
|
@@ -148,9 +200,13 @@ right
|
|
|
148
200
|
throw new Error(`field[${key}] already exists in the message chunk, but with a different type.`);
|
|
149
201
|
}
|
|
150
202
|
else if (typeof merged[key] === "string") {
|
|
151
|
-
|
|
203
|
+
if (key === "type") {
|
|
204
|
+
// Do not merge 'type' fields
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
merged[key] += value;
|
|
152
208
|
}
|
|
153
|
-
else if (
|
|
209
|
+
else if (typeof merged[key] === "object" && !Array.isArray(merged[key])) {
|
|
154
210
|
merged[key] = _mergeDicts(merged[key], value);
|
|
155
211
|
}
|
|
156
212
|
else if (Array.isArray(merged[key])) {
|
|
@@ -187,6 +243,12 @@ export function _mergeLists(left, right) {
|
|
|
187
243
|
merged.push(item);
|
|
188
244
|
}
|
|
189
245
|
}
|
|
246
|
+
else if (typeof item === "object" &&
|
|
247
|
+
"text" in item &&
|
|
248
|
+
item.text === "") {
|
|
249
|
+
// No-op - skip empty text blocks
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
190
252
|
else {
|
|
191
253
|
merged.push(item);
|
|
192
254
|
}
|
|
@@ -194,6 +256,33 @@ export function _mergeLists(left, right) {
|
|
|
194
256
|
return merged;
|
|
195
257
|
}
|
|
196
258
|
}
|
|
259
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
260
|
+
export function _mergeObj(left, right) {
|
|
261
|
+
if (!left && !right) {
|
|
262
|
+
throw new Error("Cannot merge two undefined objects.");
|
|
263
|
+
}
|
|
264
|
+
if (!left || !right) {
|
|
265
|
+
return left || right;
|
|
266
|
+
}
|
|
267
|
+
else if (typeof left !== typeof right) {
|
|
268
|
+
throw new Error(`Cannot merge objects of different types.\nLeft ${typeof left}\nRight ${typeof right}`);
|
|
269
|
+
}
|
|
270
|
+
else if (typeof left === "string" && typeof right === "string") {
|
|
271
|
+
return (left + right);
|
|
272
|
+
}
|
|
273
|
+
else if (Array.isArray(left) && Array.isArray(right)) {
|
|
274
|
+
return _mergeLists(left, right);
|
|
275
|
+
}
|
|
276
|
+
else if (typeof left === "object" && typeof right === "object") {
|
|
277
|
+
return _mergeDicts(left, right);
|
|
278
|
+
}
|
|
279
|
+
else if (left === right) {
|
|
280
|
+
return left;
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
throw new Error(`Can not merge objects of different types.\nLeft ${left}\nRight ${right}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
197
286
|
/**
|
|
198
287
|
* Represents a chunk of a message, which can be concatenated with other
|
|
199
288
|
* message chunks. It includes a method `_merge_kwargs_dict()` for merging
|
package/dist/messages/chat.cjs
CHANGED
|
@@ -32,6 +32,12 @@ class ChatMessage extends base_js_1.BaseMessage {
|
|
|
32
32
|
static isInstance(message) {
|
|
33
33
|
return message._getType() === "generic";
|
|
34
34
|
}
|
|
35
|
+
get _printableFields() {
|
|
36
|
+
return {
|
|
37
|
+
...super._printableFields,
|
|
38
|
+
role: this.role,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
42
|
exports.ChatMessage = ChatMessage;
|
|
37
43
|
/**
|
|
@@ -68,5 +74,11 @@ class ChatMessageChunk extends base_js_1.BaseMessageChunk {
|
|
|
68
74
|
id: this.id ?? chunk.id,
|
|
69
75
|
});
|
|
70
76
|
}
|
|
77
|
+
get _printableFields() {
|
|
78
|
+
return {
|
|
79
|
+
...super._printableFields,
|
|
80
|
+
role: this.role,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
71
83
|
}
|
|
72
84
|
exports.ChatMessageChunk = ChatMessageChunk;
|
package/dist/messages/chat.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export declare class ChatMessage extends BaseMessage implements ChatMessageField
|
|
|
13
13
|
constructor(fields: ChatMessageFieldsWithRole);
|
|
14
14
|
_getType(): MessageType;
|
|
15
15
|
static isInstance(message: BaseMessage): message is ChatMessage;
|
|
16
|
+
get _printableFields(): Record<string, unknown>;
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
19
|
* Represents a chunk of a chat message, which can be concatenated with
|
|
@@ -25,4 +26,5 @@ export declare class ChatMessageChunk extends BaseMessageChunk {
|
|
|
25
26
|
constructor(fields: ChatMessageFieldsWithRole);
|
|
26
27
|
_getType(): MessageType;
|
|
27
28
|
concat(chunk: ChatMessageChunk): ChatMessageChunk;
|
|
29
|
+
get _printableFields(): Record<string, unknown>;
|
|
28
30
|
}
|
package/dist/messages/chat.js
CHANGED
|
@@ -29,6 +29,12 @@ export class ChatMessage extends BaseMessage {
|
|
|
29
29
|
static isInstance(message) {
|
|
30
30
|
return message._getType() === "generic";
|
|
31
31
|
}
|
|
32
|
+
get _printableFields() {
|
|
33
|
+
return {
|
|
34
|
+
...super._printableFields,
|
|
35
|
+
role: this.role,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
32
38
|
}
|
|
33
39
|
/**
|
|
34
40
|
* Represents a chunk of a chat message, which can be concatenated with
|
|
@@ -64,4 +70,10 @@ export class ChatMessageChunk extends BaseMessageChunk {
|
|
|
64
70
|
id: this.id ?? chunk.id,
|
|
65
71
|
});
|
|
66
72
|
}
|
|
73
|
+
get _printableFields() {
|
|
74
|
+
return {
|
|
75
|
+
...super._printableFields,
|
|
76
|
+
role: this.role,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
67
79
|
}
|
package/dist/messages/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __exportStar(require("./human.cjs"), exports);
|
|
|
23
23
|
__exportStar(require("./system.cjs"), exports);
|
|
24
24
|
__exportStar(require("./utils.cjs"), exports);
|
|
25
25
|
__exportStar(require("./transformers.cjs"), exports);
|
|
26
|
+
__exportStar(require("./modifier.cjs"), exports);
|
|
26
27
|
// TODO: Use a star export when we deprecate the
|
|
27
28
|
// existing "ToolCall" type in "base.js".
|
|
28
29
|
var tool_js_1 = require("./tool.cjs");
|
package/dist/messages/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export * from "./human.js";
|
|
|
6
6
|
export * from "./system.js";
|
|
7
7
|
export * from "./utils.js";
|
|
8
8
|
export * from "./transformers.js";
|
|
9
|
-
export
|
|
9
|
+
export * from "./modifier.js";
|
|
10
|
+
export { type ToolMessageFieldsWithToolCallId, ToolMessage, ToolMessageChunk, type InvalidToolCall, } from "./tool.js";
|
package/dist/messages/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from "./human.js";
|
|
|
6
6
|
export * from "./system.js";
|
|
7
7
|
export * from "./utils.js";
|
|
8
8
|
export * from "./transformers.js";
|
|
9
|
+
export * from "./modifier.js";
|
|
9
10
|
// TODO: Use a star export when we deprecate the
|
|
10
11
|
// existing "ToolCall" type in "base.js".
|
|
11
12
|
export { ToolMessage, ToolMessageChunk, } from "./tool.js";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RemoveMessage = void 0;
|
|
4
|
+
const base_js_1 = require("./base.cjs");
|
|
5
|
+
/**
|
|
6
|
+
* Message responsible for deleting other messages.
|
|
7
|
+
*/
|
|
8
|
+
class RemoveMessage extends base_js_1.BaseMessage {
|
|
9
|
+
constructor(fields) {
|
|
10
|
+
super({
|
|
11
|
+
...fields,
|
|
12
|
+
content: "",
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* The ID of the message to remove.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(this, "id", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: void 0
|
|
22
|
+
});
|
|
23
|
+
this.id = fields.id;
|
|
24
|
+
}
|
|
25
|
+
_getType() {
|
|
26
|
+
return "remove";
|
|
27
|
+
}
|
|
28
|
+
get _printableFields() {
|
|
29
|
+
return {
|
|
30
|
+
...super._printableFields,
|
|
31
|
+
id: this.id,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.RemoveMessage = RemoveMessage;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseMessage, BaseMessageFields, MessageType } from "./base.js";
|
|
2
|
+
export interface RemoveMessageFields extends Omit<BaseMessageFields, "content"> {
|
|
3
|
+
/**
|
|
4
|
+
* The ID of the message to remove.
|
|
5
|
+
*/
|
|
6
|
+
id: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Message responsible for deleting other messages.
|
|
10
|
+
*/
|
|
11
|
+
export declare class RemoveMessage extends BaseMessage {
|
|
12
|
+
/**
|
|
13
|
+
* The ID of the message to remove.
|
|
14
|
+
*/
|
|
15
|
+
id: string;
|
|
16
|
+
constructor(fields: RemoveMessageFields);
|
|
17
|
+
_getType(): MessageType;
|
|
18
|
+
get _printableFields(): Record<string, unknown>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { BaseMessage } from "./base.js";
|
|
2
|
+
/**
|
|
3
|
+
* Message responsible for deleting other messages.
|
|
4
|
+
*/
|
|
5
|
+
export class RemoveMessage extends BaseMessage {
|
|
6
|
+
constructor(fields) {
|
|
7
|
+
super({
|
|
8
|
+
...fields,
|
|
9
|
+
content: "",
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* The ID of the message to remove.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(this, "id", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: void 0
|
|
19
|
+
});
|
|
20
|
+
this.id = fields.id;
|
|
21
|
+
}
|
|
22
|
+
_getType() {
|
|
23
|
+
return "remove";
|
|
24
|
+
}
|
|
25
|
+
get _printableFields() {
|
|
26
|
+
return {
|
|
27
|
+
...super._printableFields,
|
|
28
|
+
id: this.id,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { test } from "@jest/globals";
|
|
1
|
+
import { test, describe, it, expect } from "@jest/globals";
|
|
2
2
|
import { ChatPromptTemplate } from "../../prompts/chat.js";
|
|
3
|
-
import { HumanMessage, AIMessage, ToolMessage } from "../index.js";
|
|
3
|
+
import { HumanMessage, AIMessage, ToolMessage, ToolMessageChunk, AIMessageChunk, } from "../index.js";
|
|
4
4
|
import { load } from "../../load/index.js";
|
|
5
5
|
test("Test ChatPromptTemplate can format OpenAI content image messages", async () => {
|
|
6
6
|
const message = new HumanMessage({
|
|
@@ -111,3 +111,135 @@ test("Deserialisation and serialisation of messages with ID", async () => {
|
|
|
111
111
|
expect(deserialized).toEqual(message);
|
|
112
112
|
expect(deserialized.id).toBe(messageId);
|
|
113
113
|
});
|
|
114
|
+
test("Can concat artifact (string) of ToolMessageChunk", () => {
|
|
115
|
+
const rawOutputOne = "Hello";
|
|
116
|
+
const rawOutputTwo = " world";
|
|
117
|
+
const chunk1 = new ToolMessageChunk({
|
|
118
|
+
content: "Hello",
|
|
119
|
+
tool_call_id: "1",
|
|
120
|
+
artifact: rawOutputOne,
|
|
121
|
+
});
|
|
122
|
+
const chunk2 = new ToolMessageChunk({
|
|
123
|
+
content: " world",
|
|
124
|
+
tool_call_id: "1",
|
|
125
|
+
artifact: rawOutputTwo,
|
|
126
|
+
});
|
|
127
|
+
const concated = chunk1.concat(chunk2);
|
|
128
|
+
expect(concated.artifact).toBe(`${rawOutputOne}${rawOutputTwo}`);
|
|
129
|
+
});
|
|
130
|
+
test("Can concat artifact (array) of ToolMessageChunk", () => {
|
|
131
|
+
const rawOutputOne = ["Hello", " world"];
|
|
132
|
+
const rawOutputTwo = ["!!"];
|
|
133
|
+
const chunk1 = new ToolMessageChunk({
|
|
134
|
+
content: "Hello",
|
|
135
|
+
tool_call_id: "1",
|
|
136
|
+
artifact: rawOutputOne,
|
|
137
|
+
});
|
|
138
|
+
const chunk2 = new ToolMessageChunk({
|
|
139
|
+
content: " world",
|
|
140
|
+
tool_call_id: "1",
|
|
141
|
+
artifact: rawOutputTwo,
|
|
142
|
+
});
|
|
143
|
+
const concated = chunk1.concat(chunk2);
|
|
144
|
+
expect(concated.artifact).toEqual(["Hello", " world", "!!"]);
|
|
145
|
+
});
|
|
146
|
+
test("Can concat artifact (object) of ToolMessageChunk", () => {
|
|
147
|
+
const rawOutputOne = {
|
|
148
|
+
foo: "bar",
|
|
149
|
+
};
|
|
150
|
+
const rawOutputTwo = {
|
|
151
|
+
bar: "baz",
|
|
152
|
+
};
|
|
153
|
+
const chunk1 = new ToolMessageChunk({
|
|
154
|
+
content: "Hello",
|
|
155
|
+
tool_call_id: "1",
|
|
156
|
+
artifact: rawOutputOne,
|
|
157
|
+
});
|
|
158
|
+
const chunk2 = new ToolMessageChunk({
|
|
159
|
+
content: " world",
|
|
160
|
+
tool_call_id: "1",
|
|
161
|
+
artifact: rawOutputTwo,
|
|
162
|
+
});
|
|
163
|
+
const concated = chunk1.concat(chunk2);
|
|
164
|
+
expect(concated.artifact).toEqual({
|
|
165
|
+
foo: "bar",
|
|
166
|
+
bar: "baz",
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe("Complex AIMessageChunk concat", () => {
|
|
170
|
+
it("concatenates content arrays of strings", () => {
|
|
171
|
+
expect(new AIMessageChunk({
|
|
172
|
+
content: [{ type: "text", text: "I am" }],
|
|
173
|
+
id: "ai4",
|
|
174
|
+
}).concat(new AIMessageChunk({ content: [{ type: "text", text: " indeed." }] }))).toEqual(new AIMessageChunk({
|
|
175
|
+
id: "ai4",
|
|
176
|
+
content: [
|
|
177
|
+
{ type: "text", text: "I am" },
|
|
178
|
+
{ type: "text", text: " indeed." },
|
|
179
|
+
],
|
|
180
|
+
}));
|
|
181
|
+
});
|
|
182
|
+
it("concatenates mixed content arrays", () => {
|
|
183
|
+
expect(new AIMessageChunk({
|
|
184
|
+
content: [{ index: 0, type: "text", text: "I am" }],
|
|
185
|
+
}).concat(new AIMessageChunk({ content: [{ type: "text", text: " indeed." }] }))).toEqual(new AIMessageChunk({
|
|
186
|
+
content: [
|
|
187
|
+
{ index: 0, type: "text", text: "I am" },
|
|
188
|
+
{ type: "text", text: " indeed." },
|
|
189
|
+
],
|
|
190
|
+
}));
|
|
191
|
+
});
|
|
192
|
+
it("merges content arrays with same index", () => {
|
|
193
|
+
expect(new AIMessageChunk({ content: [{ index: 0, text: "I am" }] }).concat(new AIMessageChunk({ content: [{ index: 0, text: " indeed." }] }))).toEqual(new AIMessageChunk({ content: [{ index: 0, text: "I am indeed." }] }));
|
|
194
|
+
});
|
|
195
|
+
it("does not merge when one chunk is missing an index", () => {
|
|
196
|
+
expect(new AIMessageChunk({ content: [{ index: 0, text: "I am" }] }).concat(new AIMessageChunk({ content: [{ text: " indeed." }] }))).toEqual(new AIMessageChunk({
|
|
197
|
+
content: [{ index: 0, text: "I am" }, { text: " indeed." }],
|
|
198
|
+
}));
|
|
199
|
+
});
|
|
200
|
+
it("does not create a holey array when there's a gap between indexes", () => {
|
|
201
|
+
expect(new AIMessageChunk({ content: [{ index: 0, text: "I am" }] }).concat(new AIMessageChunk({ content: [{ index: 2, text: " indeed." }] }))).toEqual(new AIMessageChunk({
|
|
202
|
+
content: [
|
|
203
|
+
{ index: 0, text: "I am" },
|
|
204
|
+
{ index: 2, text: " indeed." },
|
|
205
|
+
],
|
|
206
|
+
}));
|
|
207
|
+
});
|
|
208
|
+
it("does not merge content arrays with separate indexes", () => {
|
|
209
|
+
expect(new AIMessageChunk({ content: [{ index: 0, text: "I am" }] }).concat(new AIMessageChunk({ content: [{ index: 1, text: " indeed." }] }))).toEqual(new AIMessageChunk({
|
|
210
|
+
content: [
|
|
211
|
+
{ index: 0, text: "I am" },
|
|
212
|
+
{ index: 1, text: " indeed." },
|
|
213
|
+
],
|
|
214
|
+
}));
|
|
215
|
+
});
|
|
216
|
+
it("merges content arrays with same index and type", () => {
|
|
217
|
+
expect(new AIMessageChunk({
|
|
218
|
+
content: [{ index: 0, text: "I am", type: "text_block" }],
|
|
219
|
+
}).concat(new AIMessageChunk({
|
|
220
|
+
content: [{ index: 0, text: " indeed.", type: "text_block" }],
|
|
221
|
+
}))).toEqual(new AIMessageChunk({
|
|
222
|
+
content: [{ index: 0, text: "I am indeed.", type: "text_block" }],
|
|
223
|
+
}));
|
|
224
|
+
});
|
|
225
|
+
it("merges content arrays with same index and different types without updating type", () => {
|
|
226
|
+
expect(new AIMessageChunk({
|
|
227
|
+
content: [{ index: 0, text: "I am", type: "text_block" }],
|
|
228
|
+
}).concat(new AIMessageChunk({
|
|
229
|
+
content: [{ index: 0, text: " indeed.", type: "text_block_delta" }],
|
|
230
|
+
}))).toEqual(new AIMessageChunk({
|
|
231
|
+
content: [{ index: 0, text: "I am indeed.", type: "text_block" }],
|
|
232
|
+
}));
|
|
233
|
+
});
|
|
234
|
+
it("concatenates empty string content and merges other fields", () => {
|
|
235
|
+
expect(new AIMessageChunk({
|
|
236
|
+
content: [{ index: 0, type: "text", text: "I am" }],
|
|
237
|
+
}).concat(new AIMessageChunk({
|
|
238
|
+
content: [{ type: "text", text: "" }],
|
|
239
|
+
response_metadata: { extra: "value" },
|
|
240
|
+
}))).toEqual(new AIMessageChunk({
|
|
241
|
+
content: [{ index: 0, type: "text", text: "I am" }],
|
|
242
|
+
response_metadata: { extra: "value" },
|
|
243
|
+
}));
|
|
244
|
+
});
|
|
245
|
+
});
|
|
@@ -3,6 +3,7 @@ import { filterMessages, mergeMessageRuns, trimMessages, } from "../transformers
|
|
|
3
3
|
import { AIMessage } from "../ai.js";
|
|
4
4
|
import { HumanMessage } from "../human.js";
|
|
5
5
|
import { SystemMessage } from "../system.js";
|
|
6
|
+
import { getBufferString } from "../utils.js";
|
|
6
7
|
describe("filterMessage", () => {
|
|
7
8
|
const getMessages = () => [
|
|
8
9
|
new SystemMessage("you're a good assistant."),
|
|
@@ -97,8 +98,8 @@ describe("mergeMessageRuns", () => {
|
|
|
97
98
|
{ type: "text", text: "my favorite dish is lasagna" },
|
|
98
99
|
],
|
|
99
100
|
tool_calls: [
|
|
100
|
-
{ name: "blah_tool", args: { x: 2 }, id: "123" },
|
|
101
|
-
{ name: "blah_tool", args: { x: -10 }, id: "456" },
|
|
101
|
+
{ name: "blah_tool", args: { x: 2 }, id: "123", type: "tool_call" },
|
|
102
|
+
{ name: "blah_tool", args: { x: -10 }, id: "456", type: "tool_call" },
|
|
102
103
|
],
|
|
103
104
|
id: "baz",
|
|
104
105
|
}),
|
|
@@ -380,3 +381,54 @@ describe("trimMessages can trim", () => {
|
|
|
380
381
|
expect(typeof trimmedMessages.func).toBe("function");
|
|
381
382
|
});
|
|
382
383
|
});
|
|
384
|
+
test("getBufferString can handle complex messages", () => {
|
|
385
|
+
const messageArr1 = [new HumanMessage("Hello there!")];
|
|
386
|
+
const messageArr2 = [
|
|
387
|
+
new AIMessage({
|
|
388
|
+
content: [
|
|
389
|
+
{
|
|
390
|
+
type: "text",
|
|
391
|
+
text: "Hello there!",
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
}),
|
|
395
|
+
];
|
|
396
|
+
const messageArr3 = [
|
|
397
|
+
new HumanMessage({
|
|
398
|
+
content: [
|
|
399
|
+
{
|
|
400
|
+
type: "image_url",
|
|
401
|
+
image_url: {
|
|
402
|
+
url: "https://example.com/image.jpg",
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
type: "image_url",
|
|
407
|
+
image_url: "https://example.com/image.jpg",
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
}),
|
|
411
|
+
];
|
|
412
|
+
const bufferString1 = getBufferString(messageArr1);
|
|
413
|
+
expect(bufferString1).toBe("Human: Hello there!");
|
|
414
|
+
const bufferString2 = getBufferString(messageArr2);
|
|
415
|
+
expect(bufferString2).toBe(`AI: ${JSON.stringify([
|
|
416
|
+
{
|
|
417
|
+
type: "text",
|
|
418
|
+
text: "Hello there!",
|
|
419
|
+
},
|
|
420
|
+
], null, 2)}`);
|
|
421
|
+
const bufferString3 = getBufferString(messageArr3);
|
|
422
|
+
expect(bufferString3).toBe(`Human: ${JSON.stringify([
|
|
423
|
+
{
|
|
424
|
+
type: "image_url",
|
|
425
|
+
image_url: {
|
|
426
|
+
url: "https://example.com/image.jpg",
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
type: "image_url",
|
|
431
|
+
image_url: "https://example.com/image.jpg",
|
|
432
|
+
},
|
|
433
|
+
], null, 2)}`);
|
|
434
|
+
});
|
package/dist/messages/tool.cjs
CHANGED
|
@@ -25,7 +25,22 @@ class ToolMessage extends base_js_1.BaseMessage {
|
|
|
25
25
|
writable: true,
|
|
26
26
|
value: void 0
|
|
27
27
|
});
|
|
28
|
+
/**
|
|
29
|
+
* Artifact of the Tool execution which is not meant to be sent to the model.
|
|
30
|
+
*
|
|
31
|
+
* Should only be specified if it is different from the message content, e.g. if only
|
|
32
|
+
* a subset of the full tool output is being passed as message content but the full
|
|
33
|
+
* output is needed in other parts of the code.
|
|
34
|
+
*/
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
+
Object.defineProperty(this, "artifact", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: void 0
|
|
41
|
+
});
|
|
28
42
|
this.tool_call_id = fields.tool_call_id;
|
|
43
|
+
this.artifact = fields.artifact;
|
|
29
44
|
}
|
|
30
45
|
_getType() {
|
|
31
46
|
return "tool";
|
|
@@ -33,6 +48,13 @@ class ToolMessage extends base_js_1.BaseMessage {
|
|
|
33
48
|
static isInstance(message) {
|
|
34
49
|
return message._getType() === "tool";
|
|
35
50
|
}
|
|
51
|
+
get _printableFields() {
|
|
52
|
+
return {
|
|
53
|
+
...super._printableFields,
|
|
54
|
+
tool_call_id: this.tool_call_id,
|
|
55
|
+
artifact: this.artifact,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
36
58
|
}
|
|
37
59
|
exports.ToolMessage = ToolMessage;
|
|
38
60
|
/**
|
|
@@ -48,7 +70,22 @@ class ToolMessageChunk extends base_js_1.BaseMessageChunk {
|
|
|
48
70
|
writable: true,
|
|
49
71
|
value: void 0
|
|
50
72
|
});
|
|
73
|
+
/**
|
|
74
|
+
* Artifact of the Tool execution which is not meant to be sent to the model.
|
|
75
|
+
*
|
|
76
|
+
* Should only be specified if it is different from the message content, e.g. if only
|
|
77
|
+
* a subset of the full tool output is being passed as message content but the full
|
|
78
|
+
* output is needed in other parts of the code.
|
|
79
|
+
*/
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
Object.defineProperty(this, "artifact", {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
configurable: true,
|
|
84
|
+
writable: true,
|
|
85
|
+
value: void 0
|
|
86
|
+
});
|
|
51
87
|
this.tool_call_id = fields.tool_call_id;
|
|
88
|
+
this.artifact = fields.artifact;
|
|
52
89
|
}
|
|
53
90
|
static lc_name() {
|
|
54
91
|
return "ToolMessageChunk";
|
|
@@ -61,10 +98,18 @@ class ToolMessageChunk extends base_js_1.BaseMessageChunk {
|
|
|
61
98
|
content: (0, base_js_1.mergeContent)(this.content, chunk.content),
|
|
62
99
|
additional_kwargs: (0, base_js_1._mergeDicts)(this.additional_kwargs, chunk.additional_kwargs),
|
|
63
100
|
response_metadata: (0, base_js_1._mergeDicts)(this.response_metadata, chunk.response_metadata),
|
|
101
|
+
artifact: (0, base_js_1._mergeObj)(this.artifact, chunk.artifact),
|
|
64
102
|
tool_call_id: this.tool_call_id,
|
|
65
103
|
id: this.id ?? chunk.id,
|
|
66
104
|
});
|
|
67
105
|
}
|
|
106
|
+
get _printableFields() {
|
|
107
|
+
return {
|
|
108
|
+
...super._printableFields,
|
|
109
|
+
tool_call_id: this.tool_call_id,
|
|
110
|
+
artifact: this.artifact,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
68
113
|
}
|
|
69
114
|
exports.ToolMessageChunk = ToolMessageChunk;
|
|
70
115
|
function defaultToolCallParser(
|