@promptbook/cli 0.88.0-1 → 0.88.0-9

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/README.md CHANGED
@@ -112,8 +112,6 @@ Rest of the documentation is common for **entire promptbook ecosystem**:
112
112
 
113
113
  During the computer revolution, we have seen [multiple generations of computer languages](https://github.com/webgptorg/promptbook/discussions/180), from the physical rewiring of the vacuum tubes through low-level machine code to the high-level languages like Python or JavaScript. And now, we're on the edge of the **next revolution**!
114
114
 
115
-
116
-
117
115
  It's a revolution of writing software in **plain human language** that is understandable and executable by both humans and machines – and it's going to change everything!
118
116
 
119
117
  The incredible growth in power of microprocessors and the Moore's Law have been the driving force behind the ever-more powerful languages, and it's been an amazing journey! Similarly, the large language models (like GPT or Claude) are the next big thing in language technology, and they're set to transform the way we interact with computers.
@@ -176,21 +174,16 @@ We also have a community of developers and users of **Promptbook**:
176
174
  - [Landing page `ptbk.io`](https://ptbk.io)
177
175
  - [Github discussions](https://github.com/webgptorg/promptbook/discussions)
178
176
  - [LinkedIn `Promptbook`](https://linkedin.com/company/promptbook)
179
- - [Facebook `Promptbook`](https://www.facebook.com/61560776453536)
177
+ - [Facebook `Promptbook`](https://www.facebook.com/61560776453536)
180
178
 
181
179
  And **Promptbook.studio** branded socials:
182
180
 
183
-
184
-
185
181
  - [Instagram `@promptbook.studio`](https://www.instagram.com/promptbook.studio/)
186
182
 
187
183
  And **Promptujeme** sub-brand:
188
184
 
189
185
  _/Subbrand for Czech clients/_
190
186
 
191
-
192
-
193
-
194
187
  - [Promptujeme.cz](https://www.promptujeme.cz/)
195
188
  - [Facebook `Promptujeme`](https://www.facebook.com/promptujeme/)
196
189
 
@@ -208,8 +201,6 @@ _/Sub-brand for images and graphics generated via Promptbook prompting/_
208
201
 
209
202
  ## 💙 The Book language
210
203
 
211
-
212
-
213
204
  Following is the documentation and blueprint of the [Book language](https://github.com/webgptorg/book).
214
205
 
215
206
  Book is a language that can be used to write AI applications, agents, workflows, automations, knowledgebases, translators, sheet processors, email automations and more. It allows you to harness the power of AI models in human-like terms, without the need to know the specifics and technicalities of the models.
@@ -259,8 +250,6 @@ Personas can have access to different knowledge, tools and actions. They can als
259
250
 
260
251
  - [PERSONA](https://github.com/webgptorg/promptbook/blob/main/documents/commands/PERSONA.md)
261
252
 
262
-
263
-
264
253
  ### **How:** Knowledge, Instruments and Actions
265
254
 
266
255
  The resources used by the personas are used to do the work.
@@ -336,11 +325,6 @@ Or you can install them separately:
336
325
 
337
326
  ## 📚 Dictionary
338
327
 
339
-
340
-
341
-
342
-
343
-
344
328
  ### 📚 Dictionary
345
329
 
346
330
  The following glossary is used to clarify certain concepts:
@@ -356,12 +340,8 @@ The following glossary is used to clarify certain concepts:
356
340
  - **Retrieval-augmented generation** is a machine learning paradigm where a model generates text by retrieving relevant information from a large database of text. This approach combines the benefits of generative models and retrieval models.
357
341
  - **Longtail** refers to non-common or rare events, items, or entities that are not well-represented in the training data of machine learning models. Longtail items are often challenging for models to predict accurately.
358
342
 
359
-
360
-
361
343
  _Note: Thos section is not complete dictionary, more list of general AI / LLM terms that has connection with Promptbook_
362
344
 
363
-
364
-
365
345
  #### 💯 Core concepts
366
346
 
367
347
  - [📚 Collection of pipelines](https://github.com/webgptorg/promptbook/discussions/65)
@@ -390,8 +370,6 @@ _Note: Thos section is not complete dictionary, more list of general AI / LLM te
390
370
  - [👮 Agent adversary expectations](https://github.com/webgptorg/promptbook/discussions/39)
391
371
  - [view more](https://github.com/webgptorg/promptbook/discussions/categories/concepts)
392
372
 
393
-
394
-
395
373
  ### Terms specific to Promptbook TypeScript implementation
396
374
 
397
375
  - Anonymous mode
@@ -399,10 +377,9 @@ _Note: Thos section is not complete dictionary, more list of general AI / LLM te
399
377
 
400
378
 
401
379
 
402
- ## 🔌 Usage in Typescript / Javascript
380
+ ## 🚂 Promptbook Engine
403
381
 
404
- - [Simple usage](./examples/usage/simple-script)
405
- - [Usage with client and remote server](./examples/usage/remote)
382
+ ![Schema of Promptbook Engine](./documents/promptbook-engine.svg)
406
383
 
407
384
  ## ➕➖ When to use Promptbook?
408
385
 
package/esm/index.es.js CHANGED
@@ -11,7 +11,7 @@ import { spawn } from 'child_process';
11
11
  import JSZip from 'jszip';
12
12
  import { format } from 'prettier';
13
13
  import parserHtml from 'prettier/parser-html';
14
- import { BehaviorSubject } from 'rxjs';
14
+ import { Subject } from 'rxjs';
15
15
  import { randomBytes } from 'crypto';
16
16
  import { parse, unparse } from 'papaparse';
17
17
  import { SHA256 } from 'crypto-js';
@@ -44,7 +44,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
44
44
  * @generated
45
45
  * @see https://github.com/webgptorg/promptbook
46
46
  */
47
- const PROMPTBOOK_ENGINE_VERSION = '0.88.0-1';
47
+ const PROMPTBOOK_ENGINE_VERSION = '0.88.0-9';
48
48
  /**
49
49
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
50
50
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -397,6 +397,30 @@ const $isRunningInWebWorker = new Function(`
397
397
  * TODO: [🎺]
398
398
  */
399
399
 
400
+ /**
401
+ * Wraps action to handle error console logging and exit process with error code
402
+ *
403
+ * @param action Action to be wrapped in error handling
404
+ * @returns Wrapped action
405
+ * @private internal helper function for CLI commands
406
+ */
407
+ function handleActionErrors(action) {
408
+ return async (...args) => {
409
+ try {
410
+ await action(...args);
411
+ return process.exit(0);
412
+ }
413
+ catch (error) {
414
+ if (!(error instanceof Error)) {
415
+ throw error;
416
+ }
417
+ // console.error(colors.bgRed(error.name));
418
+ console.error(colors.red(/* error.stack || */ error.message));
419
+ return process.exit(1);
420
+ }
421
+ };
422
+ }
423
+
400
424
  /**
401
425
  * Initializes `about` command for Promptbook CLI utilities
402
426
  *
@@ -409,7 +433,7 @@ function $initializeAboutCommand(program) {
409
433
  makeCommand.description(spaceTrim(`
410
434
  Tells about Promptbook CLI and its abilities
411
435
  `));
412
- makeCommand.action(async () => {
436
+ makeCommand.action(handleActionErrors(async () => {
413
437
  console.info(colors.bold(colors.blue(`Promptbook: ${CLAIM}`)));
414
438
  console.info(colors.cyan(`Book language version: ${BOOK_LANGUAGE_VERSION}`));
415
439
  console.info(colors.cyan(`Promptbook engine version: ${PROMPTBOOK_ENGINE_VERSION}`));
@@ -436,7 +460,7 @@ function $initializeAboutCommand(program) {
436
460
  console.info(colors.gray(`https://github.com/webgptorg/promptbook`));
437
461
  console.info(colors.gray(`https://ptbk.io`));
438
462
  return process.exit(0);
439
- });
463
+ }));
440
464
  }
441
465
  /**
442
466
  * TODO: [🗽] Unite branding and make single place for it
@@ -459,12 +483,12 @@ function $initializeHelloCommand(program) {
459
483
  helloCommand.alias('hi');
460
484
  helloCommand.argument('[name]', 'Your name', 'Paul');
461
485
  helloCommand.option('-g, --greeting <greeting>', `Greeting`, 'Hello');
462
- helloCommand.action(async (name, { greeting }) => {
486
+ helloCommand.action(handleActionErrors(async (name, { greeting }) => {
463
487
  console.info(colors.cyan(`${greeting} ${name}`));
464
488
  await forTime(1000);
465
489
  console.info(colors.rainbow(`Nice to meet you!`));
466
490
  return process.exit(0);
467
- });
491
+ }));
468
492
  }
469
493
  /**
470
494
  * TODO: [🧠][🐣] Make here some easter egg with generated hello greeting via LLM models
@@ -2553,13 +2577,13 @@ function $initializeListModelsCommand(program) {
2553
2577
  `));
2554
2578
  listModelsCommand.alias('models');
2555
2579
  listModelsCommand.alias('llm');
2556
- listModelsCommand.action(async () => {
2580
+ listModelsCommand.action(handleActionErrors(async () => {
2557
2581
  const llm = await $provideLlmToolsForWizzardOrCli({});
2558
2582
  $sideEffect(llm);
2559
2583
  // <- Note: Providing LLM tools will make a side effect of registering all available LLM tools to show the message
2560
2584
  console.info($registeredLlmToolsMessage());
2561
2585
  return process.exit(0);
2562
- });
2586
+ }));
2563
2587
  }
2564
2588
  /**
2565
2589
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -3085,7 +3109,7 @@ function $initializeListScrapersCommand(program) {
3085
3109
  List all available and configured scrapers and executables
3086
3110
  `));
3087
3111
  listModelsCommand.alias('scrapers');
3088
- listModelsCommand.action(async () => {
3112
+ listModelsCommand.action(handleActionErrors(async () => {
3089
3113
  const scrapers = await $provideScrapersForNode({});
3090
3114
  const executables = await $provideExecutablesForNode();
3091
3115
  console.info(spaceTrim((block) => `
@@ -3102,7 +3126,7 @@ function $initializeListScrapersCommand(program) {
3102
3126
  .join('\n'))}
3103
3127
  `));
3104
3128
  return process.exit(0);
3105
- });
3129
+ }));
3106
3130
  }
3107
3131
  /**
3108
3132
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -4064,6 +4088,36 @@ function $randomToken(randomness) {
4064
4088
  * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
4065
4089
  */
4066
4090
 
4091
+ /**
4092
+ * Recursively converts JSON strings to JSON objects
4093
+
4094
+ * @public exported from `@promptbook/utils`
4095
+ */
4096
+ function jsonStringsToJsons(object) {
4097
+ if (object === null) {
4098
+ return object;
4099
+ }
4100
+ if (Array.isArray(object)) {
4101
+ return object.map(jsonStringsToJsons);
4102
+ }
4103
+ if (typeof object !== 'object') {
4104
+ return object;
4105
+ }
4106
+ const newObject = { ...object };
4107
+ for (const [key, value] of Object.entries(object)) {
4108
+ if (typeof value === 'string' && isValidJsonString(value)) {
4109
+ newObject[key] = JSON.parse(value);
4110
+ }
4111
+ else {
4112
+ newObject[key] = jsonStringsToJsons(value);
4113
+ }
4114
+ }
4115
+ return newObject;
4116
+ }
4117
+ /**
4118
+ * TODO: Type the return type correctly
4119
+ */
4120
+
4067
4121
  /**
4068
4122
  * This error indicates problems parsing the format value
4069
4123
  *
@@ -4280,21 +4334,43 @@ function assertsTaskSuccessful(executionResult) {
4280
4334
  function createTask(options) {
4281
4335
  const { taskType, taskProcessCallback } = options;
4282
4336
  const taskId = `${taskType.toLowerCase().substring(0, 4)}-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid simmilar char conflicts */)}`;
4283
- const partialResultSubject = new BehaviorSubject({});
4337
+ let status = 'RUNNING';
4338
+ const createdAt = new Date();
4339
+ let updatedAt = createdAt;
4340
+ const errors = [];
4341
+ const warnings = [];
4342
+ let currentValue = {};
4343
+ const partialResultSubject = new Subject();
4344
+ // <- Note: Not using `BehaviorSubject` because on error we can't access the last value
4284
4345
  const finalResultPromise = /* not await */ taskProcessCallback((newOngoingResult) => {
4346
+ Object.assign(currentValue, newOngoingResult);
4347
+ // <- TODO: assign deep
4285
4348
  partialResultSubject.next(newOngoingResult);
4286
4349
  });
4287
4350
  finalResultPromise
4288
4351
  .catch((error) => {
4352
+ errors.push(error);
4289
4353
  partialResultSubject.error(error);
4290
4354
  })
4291
- .then((value) => {
4292
- if (value) {
4355
+ .then((executionResult) => {
4356
+ if (executionResult) {
4293
4357
  try {
4294
- assertsTaskSuccessful(value);
4295
- partialResultSubject.next(value);
4358
+ updatedAt = new Date();
4359
+ errors.push(...executionResult.errors);
4360
+ warnings.push(...executionResult.warnings);
4361
+ // <- TODO: !!! Only unique errors and warnings should be added (or filtered)
4362
+ // TODO: [🧠] !!! errors, warning, isSuccessful are redundant both in `ExecutionTask` and `ExecutionTask.currentValue`
4363
+ // Also maybe move `ExecutionTask.currentValue.usage` -> `ExecutionTask.usage`
4364
+ // And delete `ExecutionTask.currentValue.preparedPipeline`
4365
+ assertsTaskSuccessful(executionResult);
4366
+ status = 'FINISHED';
4367
+ currentValue = jsonStringsToJsons(executionResult);
4368
+ // <- TODO: Convert JSON values in string to JSON objects
4369
+ partialResultSubject.next(executionResult);
4296
4370
  }
4297
4371
  catch (error) {
4372
+ status = 'ERROR';
4373
+ errors.push(error);
4298
4374
  partialResultSubject.error(error);
4299
4375
  }
4300
4376
  }
@@ -4311,12 +4387,33 @@ function createTask(options) {
4311
4387
  return {
4312
4388
  taskType,
4313
4389
  taskId,
4390
+ get status() {
4391
+ return status;
4392
+ // <- Note: [1] Theese must be getters to allow changing the value in the future
4393
+ },
4394
+ get createdAt() {
4395
+ return createdAt;
4396
+ // <- Note: [1]
4397
+ },
4398
+ get updatedAt() {
4399
+ return updatedAt;
4400
+ // <- Note: [1]
4401
+ },
4314
4402
  asPromise,
4315
4403
  asObservable() {
4316
4404
  return partialResultSubject.asObservable();
4317
4405
  },
4406
+ get errors() {
4407
+ return errors;
4408
+ // <- Note: [1]
4409
+ },
4410
+ get warnings() {
4411
+ return warnings;
4412
+ // <- Note: [1]
4413
+ },
4318
4414
  get currentValue() {
4319
- return partialResultSubject.value;
4415
+ return currentValue;
4416
+ // <- Note: [1]
4320
4417
  },
4321
4418
  };
4322
4419
  }
@@ -5512,7 +5609,7 @@ async function executeAttempts(options) {
5512
5609
  Last result:
5513
5610
  ${block($ongoingTaskResult.$resultString === null
5514
5611
  ? 'null'
5515
- : $ongoingTaskResult.$resultString
5612
+ : spaceTrim$1($ongoingTaskResult.$resultString)
5516
5613
  .split('\n')
5517
5614
  .map((line) => `> ${line}`)
5518
5615
  .join('\n'))}
@@ -11229,7 +11326,7 @@ function $initializeMakeCommand(program) {
11229
11326
  Note: This can be used only with "javascript" or "typescript" format
11230
11327
 
11231
11328
  `), DEFAULT_GET_PIPELINE_COLLECTION_FUNCTION_NAME);
11232
- makeCommand.action(async (path, { projectName, rootUrl, format, functionName, validation, reload: isCacheReloaded, verbose: isVerbose, output, }) => {
11329
+ makeCommand.action(handleActionErrors(async (path, { projectName, rootUrl, format, functionName, validation, reload: isCacheReloaded, verbose: isVerbose, output, }) => {
11233
11330
  if (!isValidJavascriptName(functionName)) {
11234
11331
  console.error(colors.red(`Function name "${functionName}" is not valid javascript name`));
11235
11332
  return process.exit(1);
@@ -11256,9 +11353,9 @@ function $initializeMakeCommand(program) {
11256
11353
  isVerbose,
11257
11354
  isCacheReloaded,
11258
11355
  }; /* <- TODO: ` satisfies PrepareAndScrapeOptions` */
11259
- const fs = $provideFilesystemForNode();
11356
+ const fs = $provideFilesystemForNode(prepareAndScrapeOptions);
11260
11357
  const llm = await $provideLlmToolsForWizzardOrCli(prepareAndScrapeOptions);
11261
- const executables = await $provideExecutablesForNode();
11358
+ const executables = await $provideExecutablesForNode(prepareAndScrapeOptions);
11262
11359
  const tools = {
11263
11360
  llm,
11264
11361
  fs,
@@ -11416,7 +11513,7 @@ function $initializeMakeCommand(program) {
11416
11513
  console.info(colors.cyan(usageToHuman(llm.getTotalUsage())));
11417
11514
  }
11418
11515
  return process.exit(0);
11419
- });
11516
+ }));
11420
11517
  }
11421
11518
  /**
11422
11519
  * TODO: [🥃][main] !!3 Allow `ptbk make` without configuring any llm tools
@@ -11523,7 +11620,7 @@ function $initializePrettifyCommand(program) {
11523
11620
  'Pipelines to prettify as glob pattern');
11524
11621
  prettifyCommand.option('-i, --ignore <glob>', `Ignore as glob pattern`);
11525
11622
  prettifyCommand.option('-v, --verbose', `Is output verbose`, false);
11526
- prettifyCommand.action(async (filesGlob, { ignore, verbose: isVerbose }) => {
11623
+ prettifyCommand.action(handleActionErrors(async (filesGlob, { ignore, verbose: isVerbose }) => {
11527
11624
  const filenames = await glob(filesGlob, { ignore });
11528
11625
  // <- TODO: [😶]
11529
11626
  for (const filename of filenames) {
@@ -11555,7 +11652,7 @@ function $initializePrettifyCommand(program) {
11555
11652
  }
11556
11653
  console.info(colors.green(`All pipelines are prettified`));
11557
11654
  return process.exit(0);
11558
- });
11655
+ }));
11559
11656
  }
11560
11657
  /**
11561
11658
  * TODO: [😶] Unite floder listing
@@ -12129,7 +12226,7 @@ function $initializeRunCommand(program) {
12129
12226
  runCommand.option('--no-formfactor', `When set, behavior of the interactive mode is not changed by the formfactor of the pipeline`);
12130
12227
  runCommand.option('-j, --json <json>', `Pass all or some input parameters as JSON record, if used the output is also returned as JSON`);
12131
12228
  runCommand.option('-s, --save-report <path>', `Save report to file`);
12132
- runCommand.action(async (pipelineSource, options) => {
12229
+ runCommand.action(handleActionErrors(async (pipelineSource, options) => {
12133
12230
  const { reload: isCacheReloaded, interactive: isInteractive, formfactor: isFormfactorUsed, json, verbose: isVerbose, saveReport, } = options;
12134
12231
  if (pipelineSource.includes('-') && normalizeToKebabCase(pipelineSource) === pipelineSource) {
12135
12232
  console.error(colors.red(`""${pipelineSource}" is not a valid command or book. See 'ptbk --help'.`));
@@ -12152,7 +12249,7 @@ function $initializeRunCommand(program) {
12152
12249
  if (isVerbose) {
12153
12250
  console.info(colors.gray('--- Preparing tools ---'));
12154
12251
  }
12155
- const fs = $provideFilesystemForNode();
12252
+ const fs = $provideFilesystemForNode(prepareAndScrapeOptions);
12156
12253
  let llm;
12157
12254
  try {
12158
12255
  llm = await $provideLlmToolsForWizzardOrCli(prepareAndScrapeOptions);
@@ -12206,7 +12303,7 @@ function $initializeRunCommand(program) {
12206
12303
  if (isVerbose) {
12207
12304
  console.info(colors.gray('--- Getting the tools ---'));
12208
12305
  }
12209
- const executables = await $provideExecutablesForNode();
12306
+ const executables = await $provideExecutablesForNode(prepareAndScrapeOptions);
12210
12307
  const tools = {
12211
12308
  llm,
12212
12309
  fs,
@@ -12355,7 +12452,7 @@ function $initializeRunCommand(program) {
12355
12452
  console.info(JSON.stringify(outputParameters, null, 4));
12356
12453
  }
12357
12454
  return process.exit(0);
12358
- });
12455
+ }));
12359
12456
  }
12360
12457
  /**
12361
12458
  * TODO: !!5 Catch and wrap all errors from CLI
@@ -12543,8 +12640,35 @@ function startRemoteServer(options) {
12543
12640
  .send({ error: serializeError(error) });
12544
12641
  }
12545
12642
  });
12643
+ function exportExecutionTask(executionTask, isFull) {
12644
+ // <- TODO: [🧠] This should be maybe method of `ExecutionTask` itself
12645
+ const { taskType, taskId, status, errors, warnings, createdAt, updatedAt, currentValue } = executionTask;
12646
+ if (isFull) {
12647
+ return {
12648
+ nonce: '✨',
12649
+ taskId,
12650
+ taskType,
12651
+ status,
12652
+ errors: errors.map(serializeError),
12653
+ warnings: warnings.map(serializeError),
12654
+ createdAt,
12655
+ updatedAt,
12656
+ currentValue,
12657
+ };
12658
+ }
12659
+ else {
12660
+ return {
12661
+ nonce: '✨',
12662
+ taskId,
12663
+ taskType,
12664
+ status,
12665
+ createdAt,
12666
+ updatedAt,
12667
+ };
12668
+ }
12669
+ }
12546
12670
  app.get(`${rootPath}/executions`, async (request, response) => {
12547
- response.send(runningExecutionTasks);
12671
+ response.send(runningExecutionTasks.map((runningExecutionTask) => exportExecutionTask(runningExecutionTask, false)));
12548
12672
  });
12549
12673
  app.get(`${rootPath}/executions/last`, async (request, response) => {
12550
12674
  // TODO: [🤬] Filter only for user
@@ -12552,20 +12676,20 @@ function startRemoteServer(options) {
12552
12676
  response.status(404).send('No execution tasks found');
12553
12677
  return;
12554
12678
  }
12555
- const lastExecution = runningExecutionTasks[runningExecutionTasks.length - 1];
12556
- response.send(lastExecution);
12679
+ const lastExecutionTask = runningExecutionTasks[runningExecutionTasks.length - 1];
12680
+ response.send(exportExecutionTask(lastExecutionTask, true));
12557
12681
  });
12558
12682
  app.get(`${rootPath}/executions/:taskId`, async (request, response) => {
12559
12683
  const { taskId } = request.params;
12560
12684
  // TODO: [🤬] Filter only for user
12561
- const execution = runningExecutionTasks.find((executionTask) => executionTask.taskId === taskId);
12562
- if (execution === undefined) {
12685
+ const executionTask = runningExecutionTasks.find((executionTask) => executionTask.taskId === taskId);
12686
+ if (executionTask === undefined) {
12563
12687
  response
12564
12688
  .status(404)
12565
12689
  .send(`Execution "${taskId}" not found`);
12566
12690
  return;
12567
12691
  }
12568
- response.send(execution.currentValue);
12692
+ response.send(exportExecutionTask(executionTask, true));
12569
12693
  });
12570
12694
  app.post(`${rootPath}/executions/new`, async (request, response) => {
12571
12695
  try {
@@ -12799,7 +12923,7 @@ function $initializeStartServerCommand(program) {
12799
12923
  Starts a remote server to execute books
12800
12924
  `));
12801
12925
  startServerCommand.alias('server');
12802
- startServerCommand.action(async (path, { port: portRaw, url: rawUrl, allowAnonymous: isAnonymousModeAllowed, reload: isCacheReloaded, verbose: isVerbose, }) => {
12926
+ startServerCommand.action(handleActionErrors(async (path, { port: portRaw, url: rawUrl, allowAnonymous: isAnonymousModeAllowed, reload: isCacheReloaded, verbose: isVerbose, }) => {
12803
12927
  if (rawUrl && !isValidUrl(rawUrl)) {
12804
12928
  console.error(colors.red(`Invalid URL: ${rawUrl}`));
12805
12929
  return process.exit(1);
@@ -12826,9 +12950,9 @@ function $initializeStartServerCommand(program) {
12826
12950
  isVerbose,
12827
12951
  isCacheReloaded,
12828
12952
  }; /* <- TODO: ` satisfies PrepareAndScrapeOptions` */
12829
- const fs = $provideFilesystemForNode();
12953
+ const fs = $provideFilesystemForNode(prepareAndScrapeOptions);
12830
12954
  const llm = await $provideLlmToolsForWizzardOrCli(prepareAndScrapeOptions);
12831
- const executables = await $provideExecutablesForNode();
12955
+ const executables = await $provideExecutablesForNode(prepareAndScrapeOptions);
12832
12956
  const tools = {
12833
12957
  llm,
12834
12958
  fs,
@@ -12845,20 +12969,23 @@ function $initializeStartServerCommand(program) {
12845
12969
  // <- TODO: [🍖] Add `intermediateFilesStrategy`
12846
12970
  });
12847
12971
  // console.log(path, await collection.listPipelines());
12848
- startRemoteServer({
12972
+ const server = startRemoteServer({
12849
12973
  rootPath,
12850
12974
  port,
12851
12975
  isAnonymousModeAllowed,
12852
12976
  isApplicationModeAllowed: true,
12853
12977
  collection,
12854
12978
  createLlmExecutionTools(options) {
12979
+ const { appId, userId } = options;
12980
+ TODO_USE({ appId, userId });
12855
12981
  return llm;
12856
12982
  },
12857
12983
  });
12984
+ keepUnused(server);
12858
12985
  // Note: Already logged by `startRemoteServer`
12859
12986
  // console.error(colors.green(`Server started on port ${port}`));
12860
12987
  return await forEver();
12861
- });
12988
+ }));
12862
12989
  }
12863
12990
  /**
12864
12991
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -12885,7 +13012,7 @@ function $initializeTestCommand(program) {
12885
13012
  testCommand.option('--no-prepare', `Do not prepare the pipelines, ideal when no LLM tools or scrapers available`, true);
12886
13013
  testCommand.option('-r, --reload', `Call LLM models even if same prompt with result is in the cache `, false);
12887
13014
  testCommand.option('-v, --verbose', `Is output verbose`, false);
12888
- testCommand.action(async (filesGlob, { ignore: ignoreRaw = '', validation: isValidated, prepare: isPrepared, reload: isCacheReloaded, verbose: isVerbose, }) => {
13015
+ testCommand.action(handleActionErrors(async (filesGlob, { ignore: ignoreRaw = '', validation: isValidated, prepare: isPrepared, reload: isCacheReloaded, verbose: isVerbose, }) => {
12889
13016
  let tools = undefined;
12890
13017
  if (isPrepared) {
12891
13018
  // TODO: DRY [◽]
@@ -12893,9 +13020,9 @@ function $initializeTestCommand(program) {
12893
13020
  isVerbose,
12894
13021
  isCacheReloaded,
12895
13022
  }; /* <- TODO: ` satisfies PrepareAndScrapeOptions` */
12896
- const fs = $provideFilesystemForNode();
13023
+ const fs = $provideFilesystemForNode(prepareAndScrapeOptions);
12897
13024
  const llm = await $provideLlmToolsForWizzardOrCli(prepareAndScrapeOptions);
12898
- const executables = await $provideExecutablesForNode();
13025
+ const executables = await $provideExecutablesForNode(prepareAndScrapeOptions);
12899
13026
  tools = {
12900
13027
  llm,
12901
13028
  fs,
@@ -12944,7 +13071,7 @@ function $initializeTestCommand(program) {
12944
13071
  }
12945
13072
  console.info(colors.green(`All pipelines are valid`));
12946
13073
  return process.exit(0);
12947
- });
13074
+ }));
12948
13075
  }
12949
13076
  /**
12950
13077
  * TODO: [😶] Unite floder listing