UNPKG

@agentica/core

Version:

Agentic AI Library specialized in LLM Function Calling

466 lines 23.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } }; Object.defineProperty(exports, "__esModule", { value: true }); const StreamUtil_1 = require("./StreamUtil"); // Helper function to create a stream with numbers from start to end function createNumberStream(start, end) { return new ReadableStream({ start(controller) { for (let i = start; i <= end; i++) { controller.enqueue(i); } controller.close(); }, }); } // Helper function to create an empty stream function createEmptyStream() { return new ReadableStream({ start(controller) { controller.close(); }, }); } // Helper function to convert ReadableStream to array function streamToArray(stream) { return __awaiter(this, void 0, void 0, function* () { const reader = stream.getReader(); const result = []; while (true) { const { done, value } = yield reader.read(); if (done) { break; } result.push(value); } return result; }); } // Helper function to create test stream function createTestStream(items) { return new ReadableStream({ start(controller) { for (const item of items) { controller.enqueue(item); } controller.close(); }, }); } // Delay function (for simulating async operations) function delay(ms) { return __awaiter(this, void 0, void 0, function* () { return new Promise(resolve => setTimeout(resolve, ms)); }); } // Helper function to create a stream with numbers from start to end asynchronously function createDelayedNumberStream(start, end, delayMs) { return __awaiter(this, void 0, void 0, function* () { // Simulate async work yield delay(delayMs); return new ReadableStream({ start(controller) { for (let i = start; i <= end; i++) { controller.enqueue(i); } controller.close(); }, }); }); } // Helper function to create an empty stream asynchronously function createEmptyDelayedStream(delayMs) { return __awaiter(this, void 0, void 0, function* () { // Simulate async work yield delay(delayMs); return new ReadableStream({ start(controller) { controller.close(); }, }); }); } // Helper function to create a stream with items having various delay times function createVariableDelayedNumberStream(items) { return __awaiter(this, void 0, void 0, function* () { // Wait for all items to be ready based on their delays yield Promise.all(items.map((item) => __awaiter(this, void 0, void 0, function* () { return delay(item.delay); }))); return new ReadableStream({ start(controller) { for (const item of items) { controller.enqueue(item.value); } controller.close(); }, }); }); } describe("streamUtil", () => { describe("readAll", () => { it("should read all values from a stream", () => __awaiter(void 0, void 0, void 0, function* () { const stream = createNumberStream(1, 5); const result = yield StreamUtil_1.StreamUtil.readAll(stream); expect(result).toEqual([1, 2, 3, 4, 5]); })); it("should return empty array for empty stream", () => __awaiter(void 0, void 0, void 0, function* () { const stream = createEmptyStream(); const result = yield StreamUtil_1.StreamUtil.readAll(stream); expect(result).toEqual([]); })); it("should handle error in stream", () => __awaiter(void 0, void 0, void 0, function* () { const stream = new ReadableStream({ start(controller) { controller.enqueue(1); controller.enqueue(2); controller.error(new Error("Stream error")); }, }); yield expect(StreamUtil_1.StreamUtil.readAll(stream)).rejects.toThrow("Stream error"); })); it("should handle null or undefined values in stream", () => __awaiter(void 0, void 0, void 0, function* () { const stream = createTestStream([1, null, 3, undefined, 5]); const result = yield StreamUtil_1.StreamUtil.readAll(stream); expect(result).toEqual([1, null, 3, undefined, 5]); })); }); describe("reduce", () => { it("should concatenate strings from number stream", () => __awaiter(void 0, void 0, void 0, function* () { const stringStream = createNumberStream(1, 3); const stringResult = yield StreamUtil_1.StreamUtil.reduce(stringStream, (acc, cur) => acc + cur.toString(), { initial: "" }); expect(stringResult).toBe("123"); })); it("should sum numbers from stream", () => __awaiter(void 0, void 0, void 0, function* () { const sumStream = createNumberStream(1, 5); const sumResult = yield StreamUtil_1.StreamUtil.reduce(sumStream, (acc, cur) => acc + cur, { initial: 0 }); expect(sumResult).toBe(15); })); it("should work without initial value", () => __awaiter(void 0, void 0, void 0, function* () { const noInitialStream = createNumberStream(1, 4); const noInitialResult = yield StreamUtil_1.StreamUtil.reduce(noInitialStream, (acc, cur) => acc + cur, { initial: 0 }); expect(noInitialResult).toBe(10); })); it("should return initial value for empty stream", () => __awaiter(void 0, void 0, void 0, function* () { const emptyStream = createEmptyStream(); const emptyResult = yield StreamUtil_1.StreamUtil.reduce(emptyStream, (acc, cur) => acc + cur.toString(), { initial: "initial value" }); expect(emptyResult).toBe("initial value"); })); it("should work with async generated stream", () => __awaiter(void 0, void 0, void 0, function* () { const stringStream = yield createDelayedNumberStream(1, 3, 10); const stringResult = yield StreamUtil_1.StreamUtil.reduce(stringStream, (acc, cur) => acc + cur.toString(), { initial: "" }); expect(stringResult).toBe("123"); })); it("should work with async stream without initial value", () => __awaiter(void 0, void 0, void 0, function* () { const noInitialStream = yield createDelayedNumberStream(1, 4, 15); const noInitialResult = yield StreamUtil_1.StreamUtil.reduce(noInitialStream, (acc, cur) => acc + cur, { initial: 0 }); expect(noInitialResult).toBe(10); })); it("should work with async stream transformation and aggregation into array", () => __awaiter(void 0, void 0, void 0, function* () { const transformStream = yield createDelayedNumberStream(1, 3, 10); const transformResult = yield StreamUtil_1.StreamUtil.reduce(transformStream, (acc, cur) => { if (typeof acc === "number") { // Handle case when no initial value is provided return [`item${acc}`, `item${cur}`]; } return [...acc, `item${cur}`]; }, { initial: [] }); expect(transformResult).toEqual(["item1", "item2", "item3"]); })); it("should return initial value for async generated empty stream", () => __awaiter(void 0, void 0, void 0, function* () { const emptyStream = yield createEmptyDelayedStream(30); const emptyResult = yield StreamUtil_1.StreamUtil.reduce(emptyStream, (acc, cur) => acc + cur.toString(), { initial: "initial" }); expect(emptyResult).toBe("initial"); })); it("should work with stream with values created with various async delays", () => __awaiter(void 0, void 0, void 0, function* () { const delayStream = yield createVariableDelayedNumberStream([ { value: 1, delay: 20 }, { value: 2, delay: 40 }, { value: 3, delay: 10 }, ]); const delayResult = yield StreamUtil_1.StreamUtil.reduce(delayStream, (acc, cur) => acc + cur, { initial: 0 }); expect(delayResult).toBe(6); })); it("should handle error in reducer function", () => __awaiter(void 0, void 0, void 0, function* () { const stream = createNumberStream(1, 3); yield expect(StreamUtil_1.StreamUtil.reduce(stream, (acc, cur) => { if (cur === 2) { throw new Error("Test error"); } return acc + cur; }, { initial: 0 })).rejects.toThrow("Test error"); })); it("should handle null or undefined values in stream", () => __awaiter(void 0, void 0, void 0, function* () { const stream = createTestStream([1, null, 3, undefined, 5]); const result = yield StreamUtil_1.StreamUtil.reduce(stream, (acc, cur) => (acc !== null && acc !== void 0 ? acc : 0) + (cur !== null && cur !== void 0 ? cur : 0), { initial: 0 }); expect(result).toBe(9); // 1 + 0 + 3 + 0 + 5 = 9 })); }); describe("from", () => { it("should create a stream with a single value", () => __awaiter(void 0, void 0, void 0, function* () { const stream = StreamUtil_1.StreamUtil.from("Hello, world!"); const reader = stream.getReader(); const { done, value } = yield reader.read(); expect(done).toBe(false); expect(value).toBe("Hello, world!"); const next = yield reader.read(); expect(next.done).toBe(true); })); it("should handle null or undefined values", () => __awaiter(void 0, void 0, void 0, function* () { const stream = StreamUtil_1.StreamUtil.from(null); const reader = stream.getReader(); const { done, value } = yield reader.read(); expect(done).toBe(false); expect(value).toBeNull(); const next = yield reader.read(); expect(next.done).toBe(true); })); }); describe("transform", () => { it("should transform number stream by doubling", () => __awaiter(void 0, void 0, void 0, function* () { const numbersInput = [1, 2, 3, 4, 5]; const numberStream = createTestStream(numbersInput); const doubledStream = StreamUtil_1.StreamUtil.transform(numberStream, (num) => num * 2); const doubledResult = yield streamToArray(doubledStream); const expectedDoubled = numbersInput.map(n => n * 2); expect(doubledResult).toEqual(expectedDoubled); })); it("should transform object stream", () => __awaiter(void 0, void 0, void 0, function* () { const objectsInput = [ { name: "item1", value: 10 }, { name: "item2", value: 20 }, { name: "item3", value: 30 }, ]; const objectStream = createTestStream(objectsInput); const transformedObjectStream = StreamUtil_1.StreamUtil.transform(objectStream, obj => ({ id: obj.name.toUpperCase(), doubledValue: obj.value * 2, })); const transformedObjects = yield streamToArray(transformedObjectStream); const expectedObjects = objectsInput.map(obj => ({ id: obj.name.toUpperCase(), doubledValue: obj.value * 2, })); expect(transformedObjects).toEqual(expectedObjects); })); it("should handle empty stream", () => __awaiter(void 0, void 0, void 0, function* () { const emptyStream = createEmptyStream(); const transformedEmptyStream = StreamUtil_1.StreamUtil.transform(emptyStream, n => n * 2); const emptyResult = yield streamToArray(transformedEmptyStream); expect(emptyResult).toEqual([]); })); it("should transform type (number -> string)", () => __awaiter(void 0, void 0, void 0, function* () { const numbersInput = [1, 2, 3, 4, 5]; const numberStream = createTestStream(numbersInput); const stringStream = StreamUtil_1.StreamUtil.transform(numberStream, num => `Number: ${num}`); const stringResult = yield streamToArray(stringStream); const expectedStrings = numbersInput.map(n => `Number: ${n}`); expect(stringResult).toEqual(expectedStrings); })); it("should handle error in transformer function", () => __awaiter(void 0, void 0, void 0, function* () { const stream = createNumberStream(1, 3); const transformedStream = StreamUtil_1.StreamUtil.transform(stream, (num) => { if (num === 2) { throw new Error("Transform error"); } return num * 2; }); yield expect(streamToArray(transformedStream)).rejects.toThrow("Transform error"); })); it("should handle null or undefined values in stream", () => __awaiter(void 0, void 0, void 0, function* () { const stream = createTestStream([1, null, 3, undefined, 5]); const transformedStream = StreamUtil_1.StreamUtil.transform(stream, num => (num !== null && num !== void 0 ? num : 0) * 2); const result = yield streamToArray(transformedStream); expect(result).toEqual([2, 0, 6, 0, 10]); })); }); describe("toAsyncGenerator", () => { it("should yield a single value", () => __awaiter(void 0, void 0, void 0, function* () { var _a, e_1, _b, _c; const generator = (0, StreamUtil_1.toAsyncGenerator)("test value"); const result = []; try { for (var _d = true, generator_1 = __asyncValues(generator), generator_1_1; generator_1_1 = yield generator_1.next(), _a = generator_1_1.done, !_a; _d = true) { _c = generator_1_1.value; _d = false; const value = _c; result.push(value); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (!_d && !_a && (_b = generator_1.return)) yield _b.call(generator_1); } finally { if (e_1) throw e_1.error; } } expect(result).toEqual(["test value"]); })); it("should handle null or undefined values", () => __awaiter(void 0, void 0, void 0, function* () { var _a, e_2, _b, _c; const generator = (0, StreamUtil_1.toAsyncGenerator)(null); const result = []; try { for (var _d = true, generator_2 = __asyncValues(generator), generator_2_1; generator_2_1 = yield generator_2.next(), _a = generator_2_1.done, !_a; _d = true) { _c = generator_2_1.value; _d = false; const value = _c; result.push(value); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (!_d && !_a && (_b = generator_2.return)) yield _b.call(generator_2); } finally { if (e_2) throw e_2.error; } } expect(result).toEqual([null]); })); it("should handle object values", () => __awaiter(void 0, void 0, void 0, function* () { var _a, e_3, _b, _c; const testObj = { id: 1, name: "test" }; const generator = (0, StreamUtil_1.toAsyncGenerator)(testObj); const result = []; try { for (var _d = true, generator_3 = __asyncValues(generator), generator_3_1; generator_3_1 = yield generator_3.next(), _a = generator_3_1.done, !_a; _d = true) { _c = generator_3_1.value; _d = false; const value = _c; result.push(value); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (!_d && !_a && (_b = generator_3.return)) yield _b.call(generator_3); } finally { if (e_3) throw e_3.error; } } expect(result).toEqual([testObj]); })); }); describe("streamDefaultReaderToAsyncGenerator", () => { it("should convert stream reader to async generator", () => __awaiter(void 0, void 0, void 0, function* () { var _a, e_4, _b, _c; const stream = createNumberStream(1, 5); const reader = stream.getReader(); const generator = (0, StreamUtil_1.streamDefaultReaderToAsyncGenerator)(reader); const result = []; try { for (var _d = true, generator_4 = __asyncValues(generator), generator_4_1; generator_4_1 = yield generator_4.next(), _a = generator_4_1.done, !_a; _d = true) { _c = generator_4_1.value; _d = false; const value = _c; result.push(value); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (!_d && !_a && (_b = generator_4.return)) yield _b.call(generator_4); } finally { if (e_4) throw e_4.error; } } expect(result).toEqual([1, 2, 3, 4, 5]); })); it("should handle empty stream", () => __awaiter(void 0, void 0, void 0, function* () { var _a, e_5, _b, _c; const stream = createEmptyStream(); const reader = stream.getReader(); const generator = (0, StreamUtil_1.streamDefaultReaderToAsyncGenerator)(reader); const result = []; try { for (var _d = true, generator_5 = __asyncValues(generator), generator_5_1; generator_5_1 = yield generator_5.next(), _a = generator_5_1.done, !_a; _d = true) { _c = generator_5_1.value; _d = false; const value = _c; result.push(value); } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (!_d && !_a && (_b = generator_5.return)) yield _b.call(generator_5); } finally { if (e_5) throw e_5.error; } } expect(result).toEqual([]); })); it("should handle null or undefined values in stream", () => __awaiter(void 0, void 0, void 0, function* () { var _a, e_6, _b, _c; const stream = createTestStream([1, null, 3, undefined, 5]); const reader = stream.getReader(); const generator = (0, StreamUtil_1.streamDefaultReaderToAsyncGenerator)(reader); const result = []; try { for (var _d = true, generator_6 = __asyncValues(generator), generator_6_1; generator_6_1 = yield generator_6.next(), _a = generator_6_1.done, !_a; _d = true) { _c = generator_6_1.value; _d = false; const value = _c; result.push(value); } } catch (e_6_1) { e_6 = { error: e_6_1 }; } finally { try { if (!_d && !_a && (_b = generator_6.return)) yield _b.call(generator_6); } finally { if (e_6) throw e_6.error; } } expect(result).toEqual([1, null, 3, undefined, 5]); })); it("should handle error in stream", () => __awaiter(void 0, void 0, void 0, function* () { var _a, e_7, _b, _c; const stream = new ReadableStream({ start(controller) { controller.enqueue(1); controller.enqueue(2); delay(1000).then(() => controller.error(new Error("Stream error"))).catch(() => { }); }, }); const reader = stream.getReader(); const generator = (0, StreamUtil_1.streamDefaultReaderToAsyncGenerator)(reader); const result = []; try { try { for (var _d = true, generator_7 = __asyncValues(generator), generator_7_1; generator_7_1 = yield generator_7.next(), _a = generator_7_1.done, !_a; _d = true) { _c = generator_7_1.value; _d = false; const value = _c; result.push(value); } } catch (e_7_1) { e_7 = { error: e_7_1 }; } finally { try { if (!_d && !_a && (_b = generator_7.return)) yield _b.call(generator_7); } finally { if (e_7) throw e_7.error; } } // Should not reach here expect(true).toBe(false); } catch (error) { console.error(error); expect(error).toBeInstanceOf(Error); expect(error.message).toBe("Stream error"); expect(result).toEqual([1, 2]); } })); }); }); //# sourceMappingURL=StreamUtil.spec.js.map