@langchain/langgraph 0.0.12 → 0.0.13

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.
Files changed (134) hide show
  1. package/dist/channels/any_value.cjs +57 -0
  2. package/dist/channels/any_value.d.ts +16 -0
  3. package/dist/channels/any_value.js +53 -0
  4. package/dist/channels/base.cjs +19 -28
  5. package/dist/channels/base.d.ts +13 -19
  6. package/dist/channels/base.js +17 -24
  7. package/dist/channels/binop.cjs +4 -3
  8. package/dist/channels/binop.d.ts +1 -1
  9. package/dist/channels/binop.js +3 -2
  10. package/dist/channels/dynamic_barrier_value.cjs +88 -0
  11. package/dist/channels/dynamic_barrier_value.d.ts +26 -0
  12. package/dist/channels/dynamic_barrier_value.js +84 -0
  13. package/dist/channels/ephemeral_value.cjs +64 -0
  14. package/dist/channels/ephemeral_value.d.ts +14 -0
  15. package/dist/channels/ephemeral_value.js +60 -0
  16. package/dist/channels/index.cjs +1 -3
  17. package/dist/channels/index.d.ts +1 -1
  18. package/dist/channels/index.js +1 -1
  19. package/dist/channels/last_value.cjs +11 -5
  20. package/dist/channels/last_value.d.ts +5 -1
  21. package/dist/channels/last_value.js +9 -3
  22. package/dist/channels/named_barrier_value.cjs +71 -0
  23. package/dist/channels/named_barrier_value.d.ts +18 -0
  24. package/dist/channels/named_barrier_value.js +66 -0
  25. package/dist/channels/topic.cjs +5 -3
  26. package/dist/channels/topic.d.ts +3 -3
  27. package/dist/channels/topic.js +5 -3
  28. package/dist/checkpoint/base.cjs +30 -12
  29. package/dist/checkpoint/base.d.ts +39 -22
  30. package/dist/checkpoint/base.js +28 -11
  31. package/dist/checkpoint/id.cjs +40 -0
  32. package/dist/checkpoint/id.d.ts +2 -0
  33. package/dist/checkpoint/id.js +35 -0
  34. package/dist/checkpoint/index.cjs +2 -2
  35. package/dist/checkpoint/index.d.ts +2 -2
  36. package/dist/checkpoint/index.js +2 -2
  37. package/dist/checkpoint/memory.cjs +63 -49
  38. package/dist/checkpoint/memory.d.ts +7 -10
  39. package/dist/checkpoint/memory.js +62 -47
  40. package/dist/checkpoint/sqlite.cjs +170 -0
  41. package/dist/checkpoint/sqlite.d.ts +14 -0
  42. package/dist/checkpoint/sqlite.js +163 -0
  43. package/dist/constants.cjs +3 -1
  44. package/dist/constants.d.ts +2 -0
  45. package/dist/constants.js +2 -0
  46. package/dist/errors.cjs +31 -0
  47. package/dist/errors.d.ts +12 -0
  48. package/dist/errors.js +24 -0
  49. package/dist/graph/graph.cjs +235 -95
  50. package/dist/graph/graph.d.ts +52 -23
  51. package/dist/graph/graph.js +234 -96
  52. package/dist/graph/index.cjs +2 -2
  53. package/dist/graph/index.d.ts +2 -2
  54. package/dist/graph/index.js +2 -2
  55. package/dist/graph/message.cjs +4 -3
  56. package/dist/graph/message.d.ts +4 -1
  57. package/dist/graph/message.js +4 -3
  58. package/dist/graph/state.cjs +237 -102
  59. package/dist/graph/state.d.ts +41 -18
  60. package/dist/graph/state.js +238 -104
  61. package/dist/index.cjs +6 -2
  62. package/dist/index.d.ts +3 -2
  63. package/dist/index.js +2 -1
  64. package/dist/prebuilt/agent_executor.cjs +22 -36
  65. package/dist/prebuilt/agent_executor.d.ts +7 -10
  66. package/dist/prebuilt/agent_executor.js +23 -37
  67. package/dist/prebuilt/chat_agent_executor.cjs +13 -13
  68. package/dist/prebuilt/chat_agent_executor.d.ts +3 -1
  69. package/dist/prebuilt/chat_agent_executor.js +15 -15
  70. package/dist/prebuilt/index.cjs +4 -1
  71. package/dist/prebuilt/index.d.ts +1 -0
  72. package/dist/prebuilt/index.js +1 -0
  73. package/dist/prebuilt/tool_node.cjs +59 -0
  74. package/dist/prebuilt/tool_node.d.ts +17 -0
  75. package/dist/prebuilt/tool_node.js +54 -0
  76. package/dist/pregel/debug.cjs +6 -8
  77. package/dist/pregel/debug.d.ts +2 -2
  78. package/dist/pregel/debug.js +5 -7
  79. package/dist/pregel/index.cjs +406 -236
  80. package/dist/pregel/index.d.ts +77 -41
  81. package/dist/pregel/index.js +408 -241
  82. package/dist/pregel/io.cjs +117 -30
  83. package/dist/pregel/io.d.ts +11 -3
  84. package/dist/pregel/io.js +111 -28
  85. package/dist/pregel/read.cjs +126 -46
  86. package/dist/pregel/read.d.ts +27 -18
  87. package/dist/pregel/read.js +125 -45
  88. package/dist/pregel/types.cjs +2 -0
  89. package/dist/pregel/types.d.ts +32 -0
  90. package/dist/pregel/types.js +1 -0
  91. package/dist/pregel/validate.cjs +58 -51
  92. package/dist/pregel/validate.d.ts +14 -13
  93. package/dist/pregel/validate.js +56 -50
  94. package/dist/pregel/write.cjs +46 -30
  95. package/dist/pregel/write.d.ts +18 -8
  96. package/dist/pregel/write.js +45 -29
  97. package/dist/serde/base.cjs +2 -0
  98. package/dist/serde/base.d.ts +4 -0
  99. package/dist/serde/base.js +1 -0
  100. package/dist/setup/async_local_storage.cjs +2 -2
  101. package/dist/setup/async_local_storage.js +1 -1
  102. package/dist/tests/channels.test.d.ts +1 -0
  103. package/dist/tests/channels.test.js +151 -0
  104. package/dist/tests/chatbot.int.test.d.ts +1 -0
  105. package/dist/tests/chatbot.int.test.js +61 -0
  106. package/dist/tests/checkpoints.test.d.ts +1 -0
  107. package/dist/tests/checkpoints.test.js +190 -0
  108. package/dist/tests/graph.test.d.ts +1 -0
  109. package/dist/tests/graph.test.js +15 -0
  110. package/dist/tests/prebuilt.int.test.d.ts +1 -0
  111. package/dist/tests/prebuilt.int.test.js +101 -0
  112. package/dist/tests/prebuilt.test.d.ts +1 -0
  113. package/dist/tests/prebuilt.test.js +195 -0
  114. package/dist/tests/pregel.io.test.d.ts +1 -0
  115. package/dist/tests/pregel.io.test.js +332 -0
  116. package/dist/tests/pregel.read.test.d.ts +1 -0
  117. package/dist/tests/pregel.read.test.js +109 -0
  118. package/dist/tests/pregel.test.d.ts +1 -0
  119. package/dist/tests/pregel.test.js +1879 -0
  120. package/dist/tests/pregel.validate.test.d.ts +1 -0
  121. package/dist/tests/pregel.validate.test.js +198 -0
  122. package/dist/tests/pregel.write.test.d.ts +1 -0
  123. package/dist/tests/pregel.write.test.js +44 -0
  124. package/dist/tests/tracing.int.test.d.ts +1 -0
  125. package/dist/tests/tracing.int.test.js +449 -0
  126. package/dist/tests/utils.d.ts +22 -0
  127. package/dist/tests/utils.js +76 -0
  128. package/dist/utils.cjs +74 -0
  129. package/dist/utils.d.ts +18 -0
  130. package/dist/utils.js +70 -0
  131. package/package.json +11 -7
  132. package/dist/pregel/reserved.cjs +0 -6
  133. package/dist/pregel/reserved.d.ts +0 -3
  134. package/dist/pregel/reserved.js +0 -3
@@ -1,10 +1,12 @@
1
1
  import { StructuredTool } from "@langchain/core/tools";
2
2
  import { BaseMessage } from "@langchain/core/messages";
3
3
  import { ToolExecutor } from "./tool_executor.js";
4
+ import { CompiledStateGraph } from "../graph/state.js";
5
+ import { START } from "../index.js";
4
6
  export type FunctionCallingExecutorState = {
5
7
  messages: Array<BaseMessage>;
6
8
  };
7
9
  export declare function createFunctionCallingExecutor<Model extends object>({ model, tools, }: {
8
10
  model: Model;
9
11
  tools: Array<StructuredTool> | ToolExecutor;
10
- }): import("../pregel/index.js").Pregel;
12
+ }): CompiledStateGraph<FunctionCallingExecutorState, Partial<FunctionCallingExecutorState>, typeof START | "agent" | "action">;
@@ -2,8 +2,8 @@ import { convertToOpenAIFunction } from "@langchain/core/utils/function_calling"
2
2
  import { FunctionMessage } from "@langchain/core/messages";
3
3
  import { RunnableLambda } from "@langchain/core/runnables";
4
4
  import { ToolExecutor } from "./tool_executor.js";
5
- import { StateGraph } from "../graph/state.js";
6
- import { END } from "../index.js";
5
+ import { StateGraph, } from "../graph/state.js";
6
+ import { END, START } from "../index.js";
7
7
  export function createFunctionCallingExecutor({ model, tools, }) {
8
8
  let toolExecutor;
9
9
  let toolClasses;
@@ -90,15 +90,15 @@ export function createFunctionCallingExecutor({ model, tools, }) {
90
90
  // Define a new graph
91
91
  const workflow = new StateGraph({
92
92
  channels: schema,
93
- });
94
- // Define the two nodes we will cycle between
95
- workflow.addNode("agent", new RunnableLambda({ func: callModel }));
96
- workflow.addNode("action", new RunnableLambda({ func: callTool }));
97
- // Set the entrypoint as `agent`
98
- // This means that this node is the first one called
99
- workflow.setEntryPoint("agent");
100
- // We now add a conditional edge
101
- workflow.addConditionalEdges(
93
+ })
94
+ // Define the two nodes we will cycle between
95
+ .addNode("agent", new RunnableLambda({ func: callModel }))
96
+ .addNode("action", new RunnableLambda({ func: callTool }))
97
+ // Set the entrypoint as `agent`
98
+ // This means that this node is the first one called
99
+ .addEdge(START, "agent")
100
+ // We now add a conditional edge
101
+ .addConditionalEdges(
102
102
  // First, we define the start node. We use `agent`.
103
103
  // This means these are the edges taken after the `agent` node is called.
104
104
  "agent",
@@ -115,10 +115,10 @@ export function createFunctionCallingExecutor({ model, tools, }) {
115
115
  continue: "action",
116
116
  // Otherwise we finish.
117
117
  end: END,
118
- });
119
- // We now add a normal edge from `tools` to `agent`.
120
- // This means that after `tools` is called, `agent` node is called next.
121
- workflow.addEdge("action", "agent");
118
+ })
119
+ // We now add a normal edge from `tools` to `agent`.
120
+ // This means that after `tools` is called, `agent` node is called next.
121
+ .addEdge("action", "agent");
122
122
  // Finally, we compile it!
123
123
  // This compiles it into a LangChain Runnable,
124
124
  // meaning you can use it as you would any other runnable
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ToolExecutor = exports.createFunctionCallingExecutor = exports.createAgentExecutor = void 0;
3
+ exports.toolsCondition = exports.ToolNode = exports.ToolExecutor = exports.createFunctionCallingExecutor = exports.createAgentExecutor = void 0;
4
4
  var agent_executor_js_1 = require("./agent_executor.cjs");
5
5
  Object.defineProperty(exports, "createAgentExecutor", { enumerable: true, get: function () { return agent_executor_js_1.createAgentExecutor; } });
6
6
  var chat_agent_executor_js_1 = require("./chat_agent_executor.cjs");
7
7
  Object.defineProperty(exports, "createFunctionCallingExecutor", { enumerable: true, get: function () { return chat_agent_executor_js_1.createFunctionCallingExecutor; } });
8
8
  var tool_executor_js_1 = require("./tool_executor.cjs");
9
9
  Object.defineProperty(exports, "ToolExecutor", { enumerable: true, get: function () { return tool_executor_js_1.ToolExecutor; } });
10
+ var tool_node_js_1 = require("./tool_node.cjs");
11
+ Object.defineProperty(exports, "ToolNode", { enumerable: true, get: function () { return tool_node_js_1.ToolNode; } });
12
+ Object.defineProperty(exports, "toolsCondition", { enumerable: true, get: function () { return tool_node_js_1.toolsCondition; } });
@@ -1,3 +1,4 @@
1
1
  export { type AgentExecutorState, createAgentExecutor, } from "./agent_executor.js";
2
2
  export { type FunctionCallingExecutorState, createFunctionCallingExecutor, } from "./chat_agent_executor.js";
3
3
  export { type ToolExecutorArgs, type ToolInvocationInterface, ToolExecutor, } from "./tool_executor.js";
4
+ export { ToolNode, toolsCondition } from "./tool_node.js";
@@ -1,3 +1,4 @@
1
1
  export { createAgentExecutor, } from "./agent_executor.js";
2
2
  export { createFunctionCallingExecutor, } from "./chat_agent_executor.js";
3
3
  export { ToolExecutor, } from "./tool_executor.js";
4
+ export { ToolNode, toolsCondition } from "./tool_node.js";
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toolsCondition = exports.ToolNode = void 0;
4
+ const messages_1 = require("@langchain/core/messages");
5
+ const utils_js_1 = require("../utils.cjs");
6
+ const graph_js_1 = require("../graph/graph.cjs");
7
+ class ToolNode extends utils_js_1.RunnableCallable {
8
+ constructor(tools, name = "tools", tags = []) {
9
+ super({ name, tags, func: (input, config) => this.run(input, config) });
10
+ /**
11
+ A node that runs the tools requested in the last AIMessage. It can be used
12
+ either in StateGraph with a "messages" key or in MessageGraph. If multiple
13
+ tool calls are requested, they will be run in parallel. The output will be
14
+ a list of ToolMessages, one for each tool call.
15
+ */
16
+ Object.defineProperty(this, "tools", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: void 0
21
+ });
22
+ this.tools = tools;
23
+ }
24
+ async run(input, config) {
25
+ const message = Array.isArray(input)
26
+ ? input[input.length - 1]
27
+ : input.messages[input.messages.length - 1];
28
+ if (message._getType() !== "ai") {
29
+ throw new Error("ToolNode only accepts AIMessages as input.");
30
+ }
31
+ const outputs = await Promise.all(message.tool_calls?.map(async (call) => {
32
+ const tool = this.tools.find((tool) => tool.name === call.name);
33
+ if (tool === undefined) {
34
+ throw new Error(`Tool ${call.name} not found.`);
35
+ }
36
+ const output = await tool.invoke(call.args, config);
37
+ return new messages_1.ToolMessage({
38
+ name: tool.name,
39
+ content: typeof output === "string" ? output : JSON.stringify(output),
40
+ tool_call_id: call.id,
41
+ });
42
+ }) ?? []);
43
+ return Array.isArray(input) ? outputs : { messages: outputs };
44
+ }
45
+ }
46
+ exports.ToolNode = ToolNode;
47
+ function toolsCondition(state) {
48
+ const message = Array.isArray(state)
49
+ ? state[state.length - 1]
50
+ : state.messages[state.messages.length - 1];
51
+ if ("tool_calls" in message &&
52
+ (message.tool_calls?.length ?? 0) > 0) {
53
+ return "tools";
54
+ }
55
+ else {
56
+ return graph_js_1.END;
57
+ }
58
+ }
59
+ exports.toolsCondition = toolsCondition;
@@ -0,0 +1,17 @@
1
+ import { BaseMessage } from "@langchain/core/messages";
2
+ import { Tool } from "@langchain/core/tools";
3
+ import { RunnableCallable } from "../utils.js";
4
+ import { END } from "../graph/graph.js";
5
+ import { MessagesState } from "../graph/message.js";
6
+ export declare class ToolNode extends RunnableCallable<BaseMessage[] | MessagesState, BaseMessage[] | MessagesState> {
7
+ /**
8
+ A node that runs the tools requested in the last AIMessage. It can be used
9
+ either in StateGraph with a "messages" key or in MessageGraph. If multiple
10
+ tool calls are requested, they will be run in parallel. The output will be
11
+ a list of ToolMessages, one for each tool call.
12
+ */
13
+ tools: Tool[];
14
+ constructor(tools: Tool[], name?: string, tags?: string[]);
15
+ private run;
16
+ }
17
+ export declare function toolsCondition(state: BaseMessage[] | MessagesState): "tools" | typeof END;
@@ -0,0 +1,54 @@
1
+ import { ToolMessage } from "@langchain/core/messages";
2
+ import { RunnableCallable } from "../utils.js";
3
+ import { END } from "../graph/graph.js";
4
+ export class ToolNode extends RunnableCallable {
5
+ constructor(tools, name = "tools", tags = []) {
6
+ super({ name, tags, func: (input, config) => this.run(input, config) });
7
+ /**
8
+ A node that runs the tools requested in the last AIMessage. It can be used
9
+ either in StateGraph with a "messages" key or in MessageGraph. If multiple
10
+ tool calls are requested, they will be run in parallel. The output will be
11
+ a list of ToolMessages, one for each tool call.
12
+ */
13
+ Object.defineProperty(this, "tools", {
14
+ enumerable: true,
15
+ configurable: true,
16
+ writable: true,
17
+ value: void 0
18
+ });
19
+ this.tools = tools;
20
+ }
21
+ async run(input, config) {
22
+ const message = Array.isArray(input)
23
+ ? input[input.length - 1]
24
+ : input.messages[input.messages.length - 1];
25
+ if (message._getType() !== "ai") {
26
+ throw new Error("ToolNode only accepts AIMessages as input.");
27
+ }
28
+ const outputs = await Promise.all(message.tool_calls?.map(async (call) => {
29
+ const tool = this.tools.find((tool) => tool.name === call.name);
30
+ if (tool === undefined) {
31
+ throw new Error(`Tool ${call.name} not found.`);
32
+ }
33
+ const output = await tool.invoke(call.args, config);
34
+ return new ToolMessage({
35
+ name: tool.name,
36
+ content: typeof output === "string" ? output : JSON.stringify(output),
37
+ tool_call_id: call.id,
38
+ });
39
+ }) ?? []);
40
+ return Array.isArray(input) ? outputs : { messages: outputs };
41
+ }
42
+ }
43
+ export function toolsCondition(state) {
44
+ const message = Array.isArray(state)
45
+ ? state[state.length - 1]
46
+ : state.messages[state.messages.length - 1];
47
+ if ("tool_calls" in message &&
48
+ (message.tool_calls?.length ?? 0) > 0) {
49
+ return "tools";
50
+ }
51
+ else {
52
+ return END;
53
+ }
54
+ }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.printCheckpoint = exports.printStepStart = void 0;
4
- const base_js_1 = require("../channels/base.cjs");
4
+ const errors_js_1 = require("../errors.cjs");
5
5
  const COLORS_MAP = {
6
6
  blue: {
7
7
  start: "\x1b[34m",
@@ -12,17 +12,15 @@ const COLORS_MAP = {
12
12
  * Wrap some text in a color for printing to the console.
13
13
  */
14
14
  const wrap = (color, text) => `${color.start}${text}${color.end}`;
15
- function printStepStart(step,
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
- nextTasks) {
15
+ function printStepStart(step, nextTasks) {
18
16
  const nTasks = nextTasks.length;
19
- console.log(`${wrap(COLORS_MAP.blue, "[pregel/step]")}`, `Starting step ${step} with ${nTasks} task${nTasks === 1 ? "" : "s"}. Next tasks:\n`, `\n${nextTasks
20
- .map(([_, val, name]) => `- ${name}(${JSON.stringify(val, null, 2)})`)
17
+ console.log(`${wrap(COLORS_MAP.blue, "[langgraph/step]")}`, `Starting step ${step} with ${nTasks} task${nTasks === 1 ? "" : "s"}. Next tasks:\n`, `\n${nextTasks
18
+ .map((task) => `${String(task.name)}(${JSON.stringify(task.input, null, 2)})`)
21
19
  .join("\n")}`);
22
20
  }
23
21
  exports.printStepStart = printStepStart;
24
22
  function printCheckpoint(step, channels) {
25
- console.log(`${wrap(COLORS_MAP.blue, "[pregel/checkpoint]")}`, `Finishing step ${step}. Channel values:\n`, `\n${JSON.stringify(Object.fromEntries(_readChannels(channels)), null, 2)}`);
23
+ console.log(`${wrap(COLORS_MAP.blue, "[langgraph/checkpoint]")}`, `Finishing step ${step}. Channel values:\n`, `\n${JSON.stringify(Object.fromEntries(_readChannels(channels)), null, 2)}`);
26
24
  }
27
25
  exports.printCheckpoint = printCheckpoint;
28
26
  function* _readChannels(channels
@@ -34,7 +32,7 @@ function* _readChannels(channels
34
32
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
33
  }
36
34
  catch (error) {
37
- if (error.name === base_js_1.EmptyChannelError.name) {
35
+ if (error.name === errors_js_1.EmptyChannelError.name) {
38
36
  // Skip the channel if it's empty
39
37
  continue;
40
38
  }
@@ -1,4 +1,4 @@
1
- import { Runnable } from "@langchain/core/runnables";
2
1
  import { BaseChannel } from "../channels/base.js";
3
- export declare function printStepStart(step: number, nextTasks: Array<[Runnable, any, string]>): void;
2
+ import { PregelExecutableTask } from "./types.js";
3
+ export declare function printStepStart<N extends PropertyKey, C extends PropertyKey>(step: number, nextTasks: readonly PregelExecutableTask<N, C>[]): void;
4
4
  export declare function printCheckpoint<Value>(step: number, channels: Record<string, BaseChannel<Value>>): void;
@@ -1,4 +1,4 @@
1
- import { EmptyChannelError } from "../channels/base.js";
1
+ import { EmptyChannelError } from "../errors.js";
2
2
  const COLORS_MAP = {
3
3
  blue: {
4
4
  start: "\x1b[34m",
@@ -9,16 +9,14 @@ const COLORS_MAP = {
9
9
  * Wrap some text in a color for printing to the console.
10
10
  */
11
11
  const wrap = (color, text) => `${color.start}${text}${color.end}`;
12
- export function printStepStart(step,
13
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- nextTasks) {
12
+ export function printStepStart(step, nextTasks) {
15
13
  const nTasks = nextTasks.length;
16
- console.log(`${wrap(COLORS_MAP.blue, "[pregel/step]")}`, `Starting step ${step} with ${nTasks} task${nTasks === 1 ? "" : "s"}. Next tasks:\n`, `\n${nextTasks
17
- .map(([_, val, name]) => `- ${name}(${JSON.stringify(val, null, 2)})`)
14
+ console.log(`${wrap(COLORS_MAP.blue, "[langgraph/step]")}`, `Starting step ${step} with ${nTasks} task${nTasks === 1 ? "" : "s"}. Next tasks:\n`, `\n${nextTasks
15
+ .map((task) => `${String(task.name)}(${JSON.stringify(task.input, null, 2)})`)
18
16
  .join("\n")}`);
19
17
  }
20
18
  export function printCheckpoint(step, channels) {
21
- console.log(`${wrap(COLORS_MAP.blue, "[pregel/checkpoint]")}`, `Finishing step ${step}. Channel values:\n`, `\n${JSON.stringify(Object.fromEntries(_readChannels(channels)), null, 2)}`);
19
+ console.log(`${wrap(COLORS_MAP.blue, "[langgraph/checkpoint]")}`, `Finishing step ${step}. Channel values:\n`, `\n${JSON.stringify(Object.fromEntries(_readChannels(channels)), null, 2)}`);
22
20
  }
23
21
  function* _readChannels(channels
24
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any