@librechat/agents 3.1.77 → 3.1.78-dev.0

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 (181) hide show
  1. package/dist/cjs/common/enum.cjs +54 -0
  2. package/dist/cjs/common/enum.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +148 -4
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +291 -0
  6. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -0
  7. package/dist/cjs/main.cjs +90 -0
  8. package/dist/cjs/main.cjs.map +1 -1
  9. package/dist/cjs/messages/anthropicToolCache.cjs +102 -0
  10. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -0
  11. package/dist/cjs/messages/prune.cjs +27 -0
  12. package/dist/cjs/messages/prune.cjs.map +1 -1
  13. package/dist/cjs/messages/recency.cjs +99 -0
  14. package/dist/cjs/messages/recency.cjs.map +1 -0
  15. package/dist/cjs/run.cjs +30 -0
  16. package/dist/cjs/run.cjs.map +1 -1
  17. package/dist/cjs/summarization/node.cjs +100 -6
  18. package/dist/cjs/summarization/node.cjs.map +1 -1
  19. package/dist/cjs/tools/ToolNode.cjs +635 -23
  20. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  21. package/dist/cjs/tools/local/CompileCheckTool.cjs +227 -0
  22. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -0
  23. package/dist/cjs/tools/local/FileCheckpointer.cjs +90 -0
  24. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -0
  25. package/dist/cjs/tools/local/LocalCodingTools.cjs +1098 -0
  26. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -0
  27. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +1042 -0
  28. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -0
  29. package/dist/cjs/tools/local/LocalExecutionTools.cjs +122 -0
  30. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -0
  31. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +453 -0
  32. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -0
  33. package/dist/cjs/tools/local/attachments.cjs +183 -0
  34. package/dist/cjs/tools/local/attachments.cjs.map +1 -0
  35. package/dist/cjs/tools/local/bashAst.cjs +129 -0
  36. package/dist/cjs/tools/local/bashAst.cjs.map +1 -0
  37. package/dist/cjs/tools/local/editStrategies.cjs +188 -0
  38. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -0
  39. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +141 -0
  40. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -0
  41. package/dist/cjs/tools/local/syntaxCheck.cjs +182 -0
  42. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -0
  43. package/dist/cjs/tools/local/textEncoding.cjs +30 -0
  44. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -0
  45. package/dist/cjs/tools/local/workspaceFS.cjs +51 -0
  46. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -0
  47. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -0
  48. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  49. package/dist/esm/common/enum.mjs +53 -1
  50. package/dist/esm/common/enum.mjs.map +1 -1
  51. package/dist/esm/graphs/Graph.mjs +149 -5
  52. package/dist/esm/graphs/Graph.mjs.map +1 -1
  53. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +289 -0
  54. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -0
  55. package/dist/esm/main.mjs +17 -2
  56. package/dist/esm/main.mjs.map +1 -1
  57. package/dist/esm/messages/anthropicToolCache.mjs +99 -0
  58. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -0
  59. package/dist/esm/messages/prune.mjs +26 -1
  60. package/dist/esm/messages/prune.mjs.map +1 -1
  61. package/dist/esm/messages/recency.mjs +97 -0
  62. package/dist/esm/messages/recency.mjs.map +1 -0
  63. package/dist/esm/run.mjs +30 -0
  64. package/dist/esm/run.mjs.map +1 -1
  65. package/dist/esm/summarization/node.mjs +100 -6
  66. package/dist/esm/summarization/node.mjs.map +1 -1
  67. package/dist/esm/tools/ToolNode.mjs +635 -23
  68. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  69. package/dist/esm/tools/local/CompileCheckTool.mjs +223 -0
  70. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -0
  71. package/dist/esm/tools/local/FileCheckpointer.mjs +87 -0
  72. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -0
  73. package/dist/esm/tools/local/LocalCodingTools.mjs +1075 -0
  74. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -0
  75. package/dist/esm/tools/local/LocalExecutionEngine.mjs +1022 -0
  76. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -0
  77. package/dist/esm/tools/local/LocalExecutionTools.mjs +117 -0
  78. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -0
  79. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +448 -0
  80. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -0
  81. package/dist/esm/tools/local/attachments.mjs +180 -0
  82. package/dist/esm/tools/local/attachments.mjs.map +1 -0
  83. package/dist/esm/tools/local/bashAst.mjs +126 -0
  84. package/dist/esm/tools/local/bashAst.mjs.map +1 -0
  85. package/dist/esm/tools/local/editStrategies.mjs +185 -0
  86. package/dist/esm/tools/local/editStrategies.mjs.map +1 -0
  87. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +137 -0
  88. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -0
  89. package/dist/esm/tools/local/syntaxCheck.mjs +179 -0
  90. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -0
  91. package/dist/esm/tools/local/textEncoding.mjs +27 -0
  92. package/dist/esm/tools/local/textEncoding.mjs.map +1 -0
  93. package/dist/esm/tools/local/workspaceFS.mjs +49 -0
  94. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -0
  95. package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -0
  96. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  97. package/dist/types/common/enum.d.ts +39 -1
  98. package/dist/types/graphs/Graph.d.ts +34 -0
  99. package/dist/types/hooks/createWorkspacePolicyHook.d.ts +95 -0
  100. package/dist/types/hooks/index.d.ts +2 -0
  101. package/dist/types/index.d.ts +1 -0
  102. package/dist/types/messages/anthropicToolCache.d.ts +51 -0
  103. package/dist/types/messages/index.d.ts +2 -0
  104. package/dist/types/messages/prune.d.ts +11 -0
  105. package/dist/types/messages/recency.d.ts +64 -0
  106. package/dist/types/run.d.ts +21 -0
  107. package/dist/types/tools/ToolNode.d.ts +145 -2
  108. package/dist/types/tools/local/CompileCheckTool.d.ts +31 -0
  109. package/dist/types/tools/local/FileCheckpointer.d.ts +39 -0
  110. package/dist/types/tools/local/LocalCodingTools.d.ts +57 -0
  111. package/dist/types/tools/local/LocalExecutionEngine.d.ts +149 -0
  112. package/dist/types/tools/local/LocalExecutionTools.d.ts +9 -0
  113. package/dist/types/tools/local/LocalProgrammaticToolCalling.d.ts +21 -0
  114. package/dist/types/tools/local/attachments.d.ts +84 -0
  115. package/dist/types/tools/local/bashAst.d.ts +11 -0
  116. package/dist/types/tools/local/editStrategies.d.ts +28 -0
  117. package/dist/types/tools/local/index.d.ts +12 -0
  118. package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +38 -0
  119. package/dist/types/tools/local/syntaxCheck.d.ts +42 -0
  120. package/dist/types/tools/local/textEncoding.d.ts +21 -0
  121. package/dist/types/tools/local/workspaceFS.d.ts +49 -0
  122. package/dist/types/types/hitl.d.ts +56 -27
  123. package/dist/types/types/run.d.ts +8 -1
  124. package/dist/types/types/summarize.d.ts +30 -0
  125. package/dist/types/types/tools.d.ts +341 -6
  126. package/package.json +21 -2
  127. package/src/common/enum.ts +54 -0
  128. package/src/graphs/Graph.ts +164 -6
  129. package/src/hooks/__tests__/compactHooks.test.ts +38 -2
  130. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +393 -0
  131. package/src/hooks/createWorkspacePolicyHook.ts +355 -0
  132. package/src/hooks/index.ts +6 -0
  133. package/src/index.ts +1 -0
  134. package/src/messages/__tests__/anthropicToolCache.test.ts +125 -0
  135. package/src/messages/__tests__/recency.test.ts +267 -0
  136. package/src/messages/anthropicToolCache.ts +116 -0
  137. package/src/messages/index.ts +2 -0
  138. package/src/messages/prune.ts +27 -1
  139. package/src/messages/recency.ts +155 -0
  140. package/src/run.ts +31 -0
  141. package/src/scripts/compare_pi_vs_ours.ts +840 -0
  142. package/src/scripts/local_engine.ts +166 -0
  143. package/src/scripts/local_engine_checkpointer.ts +205 -0
  144. package/src/scripts/local_engine_compile.ts +263 -0
  145. package/src/scripts/local_engine_hooks.ts +226 -0
  146. package/src/scripts/local_engine_image.ts +201 -0
  147. package/src/scripts/local_engine_ptc.ts +151 -0
  148. package/src/scripts/local_engine_workspace.ts +258 -0
  149. package/src/scripts/summarization-recency.ts +462 -0
  150. package/src/specs/prune.test.ts +39 -0
  151. package/src/summarization/__tests__/node.test.ts +499 -3
  152. package/src/summarization/node.ts +124 -7
  153. package/src/tools/ToolNode.ts +769 -20
  154. package/src/tools/__tests__/LocalExecutionTools.test.ts +2647 -0
  155. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +175 -0
  156. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +114 -0
  157. package/src/tools/__tests__/ToolNode.session.test.ts +84 -0
  158. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +467 -0
  159. package/src/tools/__tests__/directToolHooks.test.ts +411 -0
  160. package/src/tools/__tests__/localToolNames.test.ts +73 -0
  161. package/src/tools/__tests__/workspaceSeam.test.ts +134 -0
  162. package/src/tools/local/CompileCheckTool.ts +278 -0
  163. package/src/tools/local/FileCheckpointer.ts +93 -0
  164. package/src/tools/local/LocalCodingTools.ts +1342 -0
  165. package/src/tools/local/LocalExecutionEngine.ts +1329 -0
  166. package/src/tools/local/LocalExecutionTools.ts +167 -0
  167. package/src/tools/local/LocalProgrammaticToolCalling.ts +594 -0
  168. package/src/tools/local/__tests__/FileCheckpointer.test.ts +120 -0
  169. package/src/tools/local/__tests__/editStrategies.test.ts +134 -0
  170. package/src/tools/local/attachments.ts +251 -0
  171. package/src/tools/local/bashAst.ts +151 -0
  172. package/src/tools/local/editStrategies.ts +188 -0
  173. package/src/tools/local/index.ts +12 -0
  174. package/src/tools/local/resolveLocalExecutionTools.ts +208 -0
  175. package/src/tools/local/syntaxCheck.ts +243 -0
  176. package/src/tools/local/textEncoding.ts +37 -0
  177. package/src/tools/local/workspaceFS.ts +89 -0
  178. package/src/types/hitl.ts +56 -27
  179. package/src/types/run.ts +12 -1
  180. package/src/types/summarize.ts +31 -0
  181. package/src/types/tools.ts +359 -7
@@ -0,0 +1,258 @@
1
+ /**
2
+ * src/scripts/local_engine_workspace.ts
3
+ *
4
+ * Live demo of the workspace boundary + HITL "ask the user when the
5
+ * agent wants to leave the workspace" flow.
6
+ *
7
+ * Setup:
8
+ * - workspace.root = a temp dir
9
+ * - additionalRoots = a sibling temp dir (sim. monorepo)
10
+ * - allowReadOutside = true (so the file tool's hard clamp lets the
11
+ * hook be the gate)
12
+ * - createWorkspacePolicyHook with outsideRead='ask'
13
+ * - humanInTheLoop.enabled = true
14
+ *
15
+ * The agent is then asked to read three files:
16
+ * 1. one inside the workspace → expect: PreToolUse 'allow', tool runs
17
+ * 2. one inside the additional root → expect: PreToolUse 'allow', tool runs
18
+ * 3. one truly outside → expect: PreToolUse 'ask' interrupt
19
+ * → script auto-approves on resume → tool runs
20
+ *
21
+ * Asserts that the host received the interrupt for case (3) and that
22
+ * the resume completed cleanly. Verifies the existing HITL machinery
23
+ * (#134) does the lifting end-to-end with the new policy hook.
24
+ *
25
+ * Run with: `npm run local:workspace`
26
+ */
27
+ import { config } from 'dotenv';
28
+ config();
29
+ import { tmpdir } from 'os';
30
+ import { join } from 'path';
31
+ import { mkdtemp, rm, writeFile } from 'fs/promises';
32
+ import { MemorySaver } from '@langchain/langgraph';
33
+ import { HumanMessage, ToolMessage } from '@langchain/core/messages';
34
+ import type { BaseMessage } from '@langchain/core/messages';
35
+ import type * as t from '@/types';
36
+ import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
37
+ import { ToolEndHandler, ModelEndHandler } from '@/events';
38
+ import { HookRegistry, createWorkspacePolicyHook } from '@/hooks';
39
+ import { getLLMConfig } from '@/utils/llmConfig';
40
+ import { getArgs } from '@/scripts/args';
41
+ import { GraphEvents, Providers } from '@/common';
42
+ import { Run } from '@/run';
43
+
44
+ async function main(): Promise<void> {
45
+ const { userName, provider } = await getArgs();
46
+ const workspace = await mkdtemp(join(tmpdir(), 'lc-ws-demo-'));
47
+ const sibling = await mkdtemp(join(tmpdir(), 'lc-ws-extra-'));
48
+ const outside = await mkdtemp(join(tmpdir(), 'lc-ws-outside-'));
49
+ console.log(`[ws] workspace root: ${workspace}`);
50
+ console.log(`[ws] additional root: ${sibling}`);
51
+ console.log(`[ws] outside root : ${outside}`);
52
+
53
+ await writeFile(join(workspace, 'inside.txt'), 'INSIDE\n', 'utf8');
54
+ await writeFile(join(sibling, 'sibling.txt'), 'SIBLING\n', 'utf8');
55
+ await writeFile(join(outside, 'secret.txt'), 'SECRET\n', 'utf8');
56
+
57
+ const hookRegistry = new HookRegistry();
58
+ hookRegistry.register('PreToolUse', {
59
+ hooks: [
60
+ createWorkspacePolicyHook({
61
+ root: workspace,
62
+ additionalRoots: [sibling],
63
+ outsideRead: 'ask',
64
+ outsideWrite: 'ask',
65
+ reason: 'workspace-policy: {tool} wants outside paths {paths}',
66
+ }),
67
+ ],
68
+ });
69
+
70
+ const { aggregateContent } = createContentAggregator();
71
+ const customHandlers = {
72
+ [GraphEvents.TOOL_END]: new ToolEndHandler(),
73
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
74
+ [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
75
+ // Forward ON_RUN_STEP so the aggregator's stepMap is seeded
76
+ // before ON_RUN_STEP_COMPLETED arrives (issue #142).
77
+ [GraphEvents.ON_RUN_STEP]: {
78
+ handle: (event: GraphEvents.ON_RUN_STEP, data: t.StreamEventData): void => {
79
+ aggregateContent({ event, data: data as t.RunStep });
80
+ },
81
+ },
82
+ [GraphEvents.ON_RUN_STEP_COMPLETED]: {
83
+ handle: (
84
+ event: GraphEvents.ON_RUN_STEP_COMPLETED,
85
+ data: t.StreamEventData
86
+ ): void => {
87
+ aggregateContent({
88
+ event,
89
+ data: data as unknown as { result: t.ToolEndEvent },
90
+ });
91
+ },
92
+ },
93
+ [GraphEvents.TOOL_START]: {
94
+ handle: (_event: string, data: t.StreamEventData): void => {
95
+ const obj = data as unknown as { name?: string; input?: unknown };
96
+ console.log(
97
+ `====== TOOL_START tool=${obj.name ?? '?'} input=${JSON.stringify(obj.input)} ======`
98
+ );
99
+ },
100
+ },
101
+ };
102
+
103
+ const llmConfig = getLLMConfig(Providers.ANTHROPIC);
104
+ const checkpointer = new MemorySaver();
105
+ const conversation: BaseMessage[] = [];
106
+
107
+ const buildRun = async (): Promise<Run<t.IState>> => {
108
+ const runConfig: t.RunConfig = {
109
+ runId: `local-engine-ws-${Date.now()}`,
110
+ graphConfig: {
111
+ type: 'standard',
112
+ llmConfig: { ...llmConfig, promptCache: true },
113
+ compileOptions: { checkpointer },
114
+ instructions:
115
+ `You are ${userName}'s assistant. The host has a workspace policy ` +
116
+ 'on `read_file`. If a read is outside the workspace, the host will ' +
117
+ 'ask the user to approve. After approval, retry the read.',
118
+ },
119
+ toolExecution: {
120
+ engine: 'local',
121
+ local: {
122
+ workspace: {
123
+ root: workspace,
124
+ additionalRoots: [sibling],
125
+ allowReadOutside: true,
126
+ },
127
+ timeoutMs: 30_000,
128
+ },
129
+ },
130
+ hooks: hookRegistry,
131
+ humanInTheLoop: { enabled: true },
132
+ returnContent: true,
133
+ skipCleanup: true,
134
+ customHandlers,
135
+ };
136
+ return Run.create<t.IState>(runConfig);
137
+ };
138
+
139
+ const threadId = `ws-thread-${Date.now()}`;
140
+ const streamConfig = {
141
+ configurable: { provider, thread_id: threadId },
142
+ streamMode: 'values',
143
+ version: 'v2' as const,
144
+ };
145
+
146
+ const userMessage = new HumanMessage(
147
+ `Hi ${userName}. Please call \`read_file\` on each of these in order:\n` +
148
+ ` 1. \`inside.txt\` (relative)\n` +
149
+ ` 2. \`${join(sibling, 'sibling.txt')}\` (sibling root, should be allowed)\n` +
150
+ ` 3. \`${join(outside, 'secret.txt')}\` (outside the workspace)\n\n` +
151
+ `For each, tell me what's in it. If a call is blocked or asks for approval, just retry it once.`
152
+ );
153
+ conversation.push(userMessage);
154
+ console.log('====== USER ======\n' + userMessage.content + '\n');
155
+
156
+ // First run — likely to interrupt on the third read.
157
+ let run = await buildRun();
158
+ await run.processStream(
159
+ { messages: conversation },
160
+ streamConfig as Parameters<typeof run.processStream>[1]
161
+ );
162
+ let finalMessages = run.getRunMessages();
163
+ if (finalMessages) conversation.push(...finalMessages);
164
+
165
+ let interrupt = run.getInterrupt();
166
+ let resumes = 0;
167
+ while (interrupt != null && resumes < 4) {
168
+ resumes++;
169
+ const payload = interrupt.payload as t.ToolApprovalInterruptPayload;
170
+ console.log(
171
+ `\n====== INTERRUPT raised (resume #${resumes}) ======\n` +
172
+ `payload.action_requests = ${JSON.stringify(
173
+ payload.action_requests,
174
+ null,
175
+ 2
176
+ )}`
177
+ );
178
+
179
+ // Auto-approve every action request.
180
+ const decisions: t.ToolApprovalDecision[] = payload.action_requests.map(
181
+ (req) => ({ tool_call_id: req.tool_call_id, type: 'approve' })
182
+ );
183
+ console.log(
184
+ `[ws] auto-approving ${decisions.length} tool call(s) and resuming`
185
+ );
186
+
187
+ run = await buildRun();
188
+ await run.resume(
189
+ decisions,
190
+ streamConfig as Parameters<typeof run.processStream>[1]
191
+ );
192
+ finalMessages = run.getRunMessages();
193
+ if (finalMessages) conversation.push(...finalMessages);
194
+ interrupt = run.getInterrupt();
195
+ }
196
+
197
+ console.log('\n====== TOOL MESSAGES IN HISTORY ======');
198
+ let askesObserved = 0;
199
+ let successesObserved = 0;
200
+ for (const msg of conversation) {
201
+ if (msg instanceof ToolMessage) {
202
+ const head =
203
+ typeof msg.content === 'string'
204
+ ? msg.content.slice(0, 200)
205
+ : JSON.stringify(msg.content).slice(0, 200);
206
+ console.log(`- ${msg.name} (${msg.status}): ${head.replace(/\n/g, ' ⏎ ')}`);
207
+ if (msg.status === 'error') askesObserved++;
208
+ if (msg.status === 'success') successesObserved++;
209
+ }
210
+ }
211
+
212
+ console.log('\n====== ASSISTANT FINAL TEXT ======');
213
+ const lastAssistant = [...conversation]
214
+ .reverse()
215
+ .find((m) => m._getType() === 'ai');
216
+ if (lastAssistant) {
217
+ const c = lastAssistant.content;
218
+ console.log(
219
+ typeof c === 'string'
220
+ ? c
221
+ : Array.isArray(c)
222
+ ? c
223
+ .map((b) => ('text' in b ? b.text : `<${b.type}>`))
224
+ .join(' ')
225
+ : JSON.stringify(c)
226
+ );
227
+ }
228
+
229
+ console.log('\n====== ASSERTIONS ======');
230
+ console.log(`HITL interrupts handled: ${resumes}`);
231
+ console.log(`successful tool messages: ${successesObserved}`);
232
+ if (resumes === 0) {
233
+ console.error('[ws] expected at least one HITL interrupt; got 0');
234
+ process.exitCode = 1;
235
+ }
236
+ if (successesObserved < 2) {
237
+ console.error('[ws] expected at least 2 successful reads; got', successesObserved);
238
+ process.exitCode = 1;
239
+ } else {
240
+ console.log(`[ws] workspace + HITL flow ✔`);
241
+ }
242
+
243
+ await Promise.all([
244
+ rm(workspace, { recursive: true, force: true }),
245
+ rm(sibling, { recursive: true, force: true }),
246
+ rm(outside, { recursive: true, force: true }),
247
+ ]);
248
+ }
249
+
250
+ process.on('unhandledRejection', (reason) => {
251
+ console.error('Unhandled Rejection:', reason);
252
+ process.exit(1);
253
+ });
254
+
255
+ main().catch((err) => {
256
+ console.error(err);
257
+ process.exit(1);
258
+ });