UNPKG

@langchain/langgraph

Version:

LangGraph

194 lines 8.14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const constants_js_1 = require("../constants.cjs"); const last_value_js_1 = require("../channels/last_value.cjs"); const read_js_1 = require("./read.cjs"); const write_js_1 = require("./write.cjs"); (0, vitest_1.describe)("ChannelRead", () => { (0, vitest_1.it)("should read a single channel value", async () => { // Setup mock read function const mockRead = vitest_1.vi .fn() .mockImplementation((channel) => { if (channel === "test_channel") { return "test_value"; } return null; }); const config = { configurable: { [constants_js_1.CONFIG_KEY_READ]: mockRead, }, }; // Create channel read const channelRead = new read_js_1.ChannelRead("test_channel"); // Run the channel read with our config const result = await channelRead.invoke(null, config); // Verify results (0, vitest_1.expect)(result).toBe("test_value"); }); (0, vitest_1.it)("should read multiple channel values", async () => { // Setup mock read function const mockRead = vitest_1.vi .fn() .mockImplementation((channels) => { if (Array.isArray(channels)) { return { channel1: "value1", channel2: "value2", }; } return null; }); const config = { configurable: { [constants_js_1.CONFIG_KEY_READ]: mockRead, }, }; // Create channel read for multiple channels const channelRead = new read_js_1.ChannelRead(["channel1", "channel2"]); // Run the channel read with our config const result = await channelRead.invoke(null, config); // Verify results (0, vitest_1.expect)(result).toEqual({ channel1: "value1", channel2: "value2", }); }); (0, vitest_1.it)("should apply a mapper function to the channel value", async () => { // Setup mock read function const mockRead = vitest_1.vi.fn().mockImplementation(() => "test_value"); const config = { configurable: { [constants_js_1.CONFIG_KEY_READ]: mockRead, }, }; // Create mapper function const mapper = (value) => `mapped_${value}`; // Create channel read with mapper const channelRead = new read_js_1.ChannelRead("test_channel", mapper); // Run the channel read with our config const result = await channelRead.invoke(null, config); // Verify results (0, vitest_1.expect)(result).toBe("mapped_test_value"); }); (0, vitest_1.it)("should throw an error if no read function is configured", async () => { // Create channel read without configuring a read function const channelRead = new read_js_1.ChannelRead("test_channel"); const config = {}; // Run the channel read with empty config await (0, vitest_1.expect)(channelRead.invoke(null, config)).rejects.toThrow("not configured with a read function"); }); }); (0, vitest_1.describe)("PregelNode", () => { (0, vitest_1.it)("should create a node that subscribes to channels", () => { const node = new read_js_1.PregelNode({ channels: ["input", "context"], triggers: ["input"], }); (0, vitest_1.expect)(node.channels).toEqual(["input", "context"]); (0, vitest_1.expect)(node.triggers).toEqual(["input"]); }); (0, vitest_1.it)("should chain with ChannelWrite using pipe", () => { const node = new read_js_1.PregelNode({ channels: ["input"], triggers: ["input"], }); const write = new write_js_1.ChannelWrite([ { channel: "output", value: "test_output" }, ]); const pipeResult = node.pipe(write); (0, vitest_1.expect)(pipeResult.writers).toHaveLength(1); (0, vitest_1.expect)(pipeResult.writers[0]).toBe(write); }); (0, vitest_1.it)("should combine multiple consecutive ChannelWrite instances", () => { const node = new read_js_1.PregelNode({ channels: ["input"], triggers: ["input"], }); const write1 = new write_js_1.ChannelWrite([{ channel: "output1", value: "value1" }]); const write2 = new write_js_1.ChannelWrite([{ channel: "output2", value: "value2" }]); // Chain two writes const pipeResult = node.pipe(write1).pipe(write2); // Get optimized writers const optimizedWriters = pipeResult.getWriters(); // Should be combined into a single ChannelWrite (0, vitest_1.expect)(optimizedWriters).toHaveLength(1); (0, vitest_1.expect)(optimizedWriters[0]).toBeInstanceOf(write_js_1.ChannelWrite); (0, vitest_1.expect)(optimizedWriters[0].writes).toHaveLength(2); }); (0, vitest_1.it)("should join additional channels", () => { const node = new read_js_1.PregelNode({ channels: { input: "input", context: "context" }, triggers: ["input"], }); const joinedNode = node.join(["history"]); (0, vitest_1.expect)(joinedNode.channels).toEqual({ input: "input", context: "context", history: "history", }); }); }); (0, vitest_1.describe)("Integrated Channel Read and Write", () => { (0, vitest_1.it)("should perform direct channel operations", async () => { // Use direct channel operations rather than depending on invoke // Setup test environment with real channels const channels = { input: new last_value_js_1.LastValue(), output: new last_value_js_1.LastValue(), }; // Set initial value in input channel channels.input.update(["test_input"]); // Get value from input channel const inputValue = channels.input.get(); (0, vitest_1.expect)(inputValue).toBe("test_input"); // Process value const processedValue = `processed_${inputValue}`; // Write to output channel const updated = channels.output.update([processedValue]); (0, vitest_1.expect)(updated).toBe(true); // Read from output channel const outputValue = channels.output.get(); (0, vitest_1.expect)(outputValue).toBe("processed_test_input"); }); (0, vitest_1.it)("should work with manual read and write operations", async () => { // Setup test environment with real channels const channels = { input: new last_value_js_1.LastValue(), output: new last_value_js_1.LastValue(), }; // Initialize input channel with a value channels.input.update(["test_input"]); // Setup write tracking let writtenValue = null; // Manual read operation const readFunc = (channel) => { if (channel === "input") { return channels.input.get(); } return null; }; // Manual write operation const writeFunc = (values) => { for (const [channel, value] of values) { if (channel === "output") { writtenValue = value; channels.output.update([value]); } } }; // Read from input channel const inputValue = readFunc("input"); (0, vitest_1.expect)(inputValue).toBe("test_input"); // Process the value const processedValue = `processed_${inputValue}`; // Write to output channel writeFunc([["output", processedValue]]); // Verify the write happened (0, vitest_1.expect)(writtenValue).toBe("processed_test_input"); (0, vitest_1.expect)(channels.output.get()).toBe("processed_test_input"); }); }); //# sourceMappingURL=read.test.js.map