@promptbook/cli 0.84.0 → 0.85.0-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 (33) hide show
  1. package/README.md +6 -5
  2. package/esm/index.es.js +638 -164
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/src/_packages/core.index.d.ts +0 -2
  5. package/esm/typings/src/_packages/types.index.d.ts +14 -2
  6. package/esm/typings/src/_packages/utils.index.d.ts +0 -2
  7. package/esm/typings/src/cli/cli-commands/_boilerplate.d.ts +13 -0
  8. package/esm/typings/src/cli/cli-commands/start-server.d.ts +13 -0
  9. package/esm/typings/src/conversion/compilePipelineOnRemoteServer.d.ts +1 -1
  10. package/esm/typings/src/execution/AbstractTaskResult.d.ts +25 -0
  11. package/esm/typings/src/execution/ExecutionTask.d.ts +71 -0
  12. package/esm/typings/src/execution/PipelineExecutor.d.ts +2 -5
  13. package/esm/typings/src/execution/PipelineExecutorResult.d.ts +2 -15
  14. package/esm/typings/src/execution/PromptbookFetch.d.ts +8 -1
  15. package/esm/typings/src/execution/{assertsExecutionSuccessful.d.ts → assertsTaskSuccessful.d.ts} +2 -3
  16. package/esm/typings/src/execution/createPipelineExecutor/00-createPipelineExecutor.d.ts +0 -3
  17. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +2 -6
  18. package/esm/typings/src/execution/createPipelineExecutor/20-executeTask.d.ts +3 -6
  19. package/esm/typings/src/prepare/preparePipelineOnRemoteServer.d.ts +1 -1
  20. package/esm/typings/src/remote-server/startRemoteServer.d.ts +1 -0
  21. package/esm/typings/src/types/typeAliases.d.ts +2 -0
  22. package/esm/typings/src/utils/environment/$isRunningInBrowser.d.ts +2 -2
  23. package/esm/typings/src/utils/environment/$isRunningInJest.d.ts +2 -2
  24. package/esm/typings/src/utils/environment/$isRunningInNode.d.ts +2 -2
  25. package/esm/typings/src/utils/environment/$isRunningInWebWorker.d.ts +1 -1
  26. package/esm/typings/src/utils/random/$randomSeed.d.ts +2 -1
  27. package/esm/typings/src/utils/random/$randomToken.d.ts +13 -0
  28. package/esm/typings/src/wizzard/wizzard.d.ts +2 -3
  29. package/package.json +5 -1
  30. package/umd/index.umd.js +639 -168
  31. package/umd/index.umd.js.map +1 -1
  32. package/esm/typings/src/remote-server/socket-types/_common/PromptbookServer_Progress.d.ts +0 -10
  33. package/esm/typings/src/types/TaskProgress.d.ts +0 -43
package/umd/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('waitasecond'), require('path'), require('fs/promises'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('dotenv'), require('child_process'), require('prettier'), require('prettier/parser-html'), require('papaparse'), require('crypto-js'), require('mime-types'), require('glob-promise'), require('prompts'), require('moment'), require('socket.io-client'), require('@anthropic-ai/sdk'), require('@azure/openai'), require('openai'), require('@mozilla/readability'), require('jsdom'), require('showdown')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'waitasecond', 'path', 'fs/promises', 'crypto-js/enc-hex', 'crypto-js/sha256', 'dotenv', 'child_process', 'prettier', 'prettier/parser-html', 'papaparse', 'crypto-js', 'mime-types', 'glob-promise', 'prompts', 'moment', 'socket.io-client', '@anthropic-ai/sdk', '@azure/openai', 'openai', '@mozilla/readability', 'jsdom', 'showdown'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global.spaceTrim, global.waitasecond, global.path, global.promises, global.hexEncoder, global.sha256, global.dotenv, global.child_process, global.prettier, global.parserHtml, global.papaparse, global.cryptoJs, global.mimeTypes, global.glob, global.prompts, global.moment, global.socket_ioClient, global.Anthropic, global.openai, global.OpenAI, global.readability, global.jsdom, global.showdown));
5
- })(this, (function (exports, colors, commander, spaceTrim, waitasecond, path, promises, hexEncoder, sha256, dotenv, child_process, prettier, parserHtml, papaparse, cryptoJs, mimeTypes, glob, prompts, moment, socket_ioClient, Anthropic, openai, OpenAI, readability, jsdom, showdown) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('waitasecond'), require('path'), require('fs/promises'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('dotenv'), require('child_process'), require('prettier'), require('prettier/parser-html'), require('rxjs'), require('crypto'), require('papaparse'), require('crypto-js'), require('mime-types'), require('glob-promise'), require('prompts'), require('moment'), require('express'), require('http'), require('socket.io'), require('socket.io-client'), require('@anthropic-ai/sdk'), require('@azure/openai'), require('openai'), require('@mozilla/readability'), require('jsdom'), require('showdown')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'waitasecond', 'path', 'fs/promises', 'crypto-js/enc-hex', 'crypto-js/sha256', 'dotenv', 'child_process', 'prettier', 'prettier/parser-html', 'rxjs', 'crypto', 'papaparse', 'crypto-js', 'mime-types', 'glob-promise', 'prompts', 'moment', 'express', 'http', 'socket.io', 'socket.io-client', '@anthropic-ai/sdk', '@azure/openai', 'openai', '@mozilla/readability', 'jsdom', 'showdown'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global.spaceTrim, global.waitasecond, global.path, global.promises, global.hexEncoder, global.sha256, global.dotenv, global.child_process, global.prettier, global.parserHtml, global.rxjs, global.crypto, global.papaparse, global.cryptoJs, global.mimeTypes, global.glob, global.prompts, global.moment, global.express, global.http, global.socket_io, global.socket_ioClient, global.Anthropic, global.openai, global.OpenAI, global.readability, global.jsdom, global.showdown));
5
+ })(this, (function (exports, colors, commander, spaceTrim, waitasecond, path, promises, hexEncoder, sha256, dotenv, child_process, prettier, parserHtml, rxjs, crypto, papaparse, cryptoJs, mimeTypes, glob, prompts, moment, express, http, socket_io, socket_ioClient, Anthropic, openai, OpenAI, readability, jsdom, showdown) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -34,6 +34,8 @@
34
34
  var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
35
35
  var prompts__default = /*#__PURE__*/_interopDefaultLegacy(prompts);
36
36
  var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
37
+ var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
38
+ var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
37
39
  var Anthropic__default = /*#__PURE__*/_interopDefaultLegacy(Anthropic);
38
40
  var OpenAI__default = /*#__PURE__*/_interopDefaultLegacy(OpenAI);
39
41
 
@@ -51,7 +53,7 @@
51
53
  * @generated
52
54
  * @see https://github.com/webgptorg/promptbook
53
55
  */
54
- var PROMPTBOOK_ENGINE_VERSION = '0.84.0-21';
56
+ var PROMPTBOOK_ENGINE_VERSION = '0.84.0';
55
57
  /**
56
58
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
57
59
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -459,7 +461,7 @@
459
461
  */
460
462
  var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
461
463
  /**
462
- * TODO: []
464
+ * TODO: [🎺]
463
465
  */
464
466
 
465
467
  /**
@@ -471,7 +473,7 @@
471
473
  */
472
474
  var $isRunningInBrowser = new Function("\n try {\n return this === window;\n } catch (e) {\n return false;\n }\n");
473
475
  /**
474
- * TODO: []
476
+ * TODO: [🎺]
475
477
  */
476
478
 
477
479
  /**
@@ -483,7 +485,7 @@
483
485
  */
484
486
  var $isRunningInJest = new Function("\n try {\n return process.env.JEST_WORKER_ID !== undefined;\n } catch (e) {\n return false;\n }\n");
485
487
  /**
486
- * TODO: []
488
+ * TODO: [🎺]
487
489
  */
488
490
 
489
491
  /**
@@ -495,7 +497,7 @@
495
497
  */
496
498
  var $isRunningInWebWorker = new Function("\n try {\n if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {\n return true;\n } else {\n return false;\n }\n } catch (e) {\n return false;\n }\n");
497
499
  /**
498
- * TODO: []
500
+ * TODO: [🎺]
499
501
  */
500
502
 
501
503
  /**
@@ -508,7 +510,7 @@
508
510
  function $initializeAboutCommand(program) {
509
511
  var _this = this;
510
512
  var makeCommand = program.command('about');
511
- makeCommand.description(spaceTrim__default["default"]("\n Tells about Promptbook CLI and its abilities\n "));
513
+ makeCommand.description(spaceTrim__default["default"]("\n Tells about Promptbook CLI and its abilities\n "));
512
514
  makeCommand.action(function () { return __awaiter(_this, void 0, void 0, function () {
513
515
  return __generator(this, function (_a) {
514
516
  console.info(colors__default["default"].bold(colors__default["default"].blue("Promptbook: ".concat(CLAIM))));
@@ -517,7 +519,7 @@
517
519
  if ($isRunningInNode()) {
518
520
  console.info(colors__default["default"].cyan("Environment: Node.js"));
519
521
  console.info(colors__default["default"].cyan("Node.js version: ".concat(process.version)));
520
- // <- TODO: [🧠][] Make robust system to check platform requirements like browser/node environment, version of node, available memory, disk space, ...
522
+ // <- TODO: [🧠][🎺] Make robust system to check platform requirements like browser/node environment, version of node, available memory, disk space, ...
521
523
  console.info(colors__default["default"].cyan("Platform type: ".concat(process.platform)));
522
524
  console.info(colors__default["default"].cyan("Platform architecture: ".concat(process.arch)));
523
525
  // console.info(colors.cyan(`Available memory: ${process.availableMemory()}`));
@@ -557,7 +559,7 @@
557
559
  function $initializeHelloCommand(program) {
558
560
  var _this = this;
559
561
  var helloCommand = program.command('hello');
560
- helloCommand.description(spaceTrim__default["default"]("\n Just command for testing\n "));
562
+ helloCommand.description(spaceTrim__default["default"]("\n Just command for testing\n "));
561
563
  helloCommand.argument('[name]', 'Your name', 'Paul');
562
564
  helloCommand.option('-g, --greeting <greeting>', "Greeting", 'Hello');
563
565
  helloCommand.action(function (name, _a) {
@@ -2930,7 +2932,7 @@
2930
2932
  function $initializeListModelsCommand(program) {
2931
2933
  var _this = this;
2932
2934
  var listModelsCommand = program.command('list-models');
2933
- listModelsCommand.description(spaceTrim__default["default"]("\n List all available and configured LLM models\n "));
2935
+ listModelsCommand.description(spaceTrim__default["default"]("\n List all available and configured LLM models\n "));
2934
2936
  listModelsCommand.action(function () { return __awaiter(_this, void 0, void 0, function () {
2935
2937
  var llm;
2936
2938
  return __generator(this, function (_a) {
@@ -3615,7 +3617,7 @@
3615
3617
  function $initializeListScrapersCommand(program) {
3616
3618
  var _this = this;
3617
3619
  var listModelsCommand = program.command('list-scrapers');
3618
- listModelsCommand.description(spaceTrim__default["default"]("\n List all available and configured scrapers and executables\n "));
3620
+ listModelsCommand.description(spaceTrim__default["default"]("\n List all available and configured scrapers and executables\n "));
3619
3621
  listModelsCommand.action(function () { return __awaiter(_this, void 0, void 0, function () {
3620
3622
  var scrapers, executables;
3621
3623
  return __generator(this, function (_a) {
@@ -4644,6 +4646,58 @@
4644
4646
  return MissingToolsError;
4645
4647
  }(Error));
4646
4648
 
4649
+ /**
4650
+ * Determine if the pipeline is fully prepared
4651
+ *
4652
+ * @see https://github.com/webgptorg/promptbook/discussions/196
4653
+ *
4654
+ * @public exported from `@promptbook/core`
4655
+ */
4656
+ function isPipelinePrepared(pipeline) {
4657
+ // Note: Ignoring `pipeline.preparations` @@@
4658
+ // Note: Ignoring `pipeline.knowledgePieces` @@@
4659
+ if (pipeline.title === undefined || pipeline.title === '' || pipeline.title === DEFAULT_BOOK_TITLE) {
4660
+ return false;
4661
+ }
4662
+ if (!pipeline.personas.every(function (persona) { return persona.modelRequirements !== undefined; })) {
4663
+ return false;
4664
+ }
4665
+ if (!pipeline.knowledgeSources.every(function (knowledgeSource) { return knowledgeSource.preparationIds !== undefined; })) {
4666
+ return false;
4667
+ }
4668
+ /*
4669
+ TODO: [🧠][🍫] `tasks` can not be determined if they are fully prepared SO ignoring them
4670
+ > if (!pipeline.tasks.every(({ preparedContent }) => preparedContent === undefined)) {
4671
+ > return false;
4672
+ > }
4673
+ */
4674
+ return true;
4675
+ }
4676
+ /**
4677
+ * TODO: [🔃][main] If the pipeline was prepared with different version or different set of models, prepare it once again
4678
+ * TODO: [🐠] Maybe base this on `makeValidator`
4679
+ * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
4680
+ * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
4681
+ * - [🏍] ? Is context in each task
4682
+ * - [♨] Are examples prepared
4683
+ * - [♨] Are tasks prepared
4684
+ */
4685
+
4686
+ /**
4687
+ * Generates random token
4688
+ *
4689
+ * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
4690
+ *
4691
+ * @private internal helper function
4692
+ * @returns secure random token
4693
+ */
4694
+ function $randomToken(randomness) {
4695
+ return crypto.randomBytes(randomness).toString('hex');
4696
+ }
4697
+ /**
4698
+ * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
4699
+ */
4700
+
4647
4701
  /**
4648
4702
  * This error indicates problems parsing the format value
4649
4703
  *
@@ -4829,9 +4883,9 @@
4829
4883
  *
4830
4884
  * @param executionResult - The partial result of the Promptbook execution
4831
4885
  * @throws {PipelineExecutionError} If the execution is not successful or if multiple errors occurred
4832
- * @public exported from `@promptbook/core`
4886
+ * @private internal helper function of `asPromise` method of `ExecutionTask`
4833
4887
  */
4834
- function assertsExecutionSuccessful(executionResult) {
4888
+ function assertsTaskSuccessful(executionResult) {
4835
4889
  var e_1, _a;
4836
4890
  var isSuccessful = executionResult.isSuccessful, errors = executionResult.errors, warnings = executionResult.warnings;
4837
4891
  try {
@@ -4866,47 +4920,72 @@
4866
4920
  }
4867
4921
  }
4868
4922
  /**
4869
- * TODO: [🐚] This function should be removed OR changed OR be completely rewritten
4870
4923
  * TODO: [🧠] Can this return type be better typed than void
4871
4924
  */
4872
4925
 
4873
4926
  /**
4874
- * Determine if the pipeline is fully prepared
4875
- *
4876
- * @see https://github.com/webgptorg/promptbook/discussions/196
4927
+ * Helper to create a new task
4877
4928
  *
4878
- * @public exported from `@promptbook/core`
4929
+ * @private internal helper function
4879
4930
  */
4880
- function isPipelinePrepared(pipeline) {
4881
- // Note: Ignoring `pipeline.preparations` @@@
4882
- // Note: Ignoring `pipeline.knowledgePieces` @@@
4883
- if (pipeline.title === undefined || pipeline.title === '' || pipeline.title === DEFAULT_BOOK_TITLE) {
4884
- return false;
4885
- }
4886
- if (!pipeline.personas.every(function (persona) { return persona.modelRequirements !== undefined; })) {
4887
- return false;
4888
- }
4889
- if (!pipeline.knowledgeSources.every(function (knowledgeSource) { return knowledgeSource.preparationIds !== undefined; })) {
4890
- return false;
4931
+ function createTask(options) {
4932
+ var taskType = options.taskType, taskProcessCallback = options.taskProcessCallback;
4933
+ var taskId = "".concat(taskType.toLowerCase(), "-").concat($randomToken(256 /* <- TODO: !!! To global config */));
4934
+ var resultSubject = new rxjs.BehaviorSubject({});
4935
+ var finalResultPromise = /* not await */ taskProcessCallback(function (newOngoingResult) {
4936
+ resultSubject.next(newOngoingResult);
4937
+ });
4938
+ function asPromise(options) {
4939
+ return __awaiter(this, void 0, void 0, function () {
4940
+ var _a, isCrashedOnError, finalResult;
4941
+ return __generator(this, function (_b) {
4942
+ switch (_b.label) {
4943
+ case 0:
4944
+ _a = (options || {}).isCrashedOnError, isCrashedOnError = _a === void 0 ? true : _a;
4945
+ return [4 /*yield*/, finalResultPromise];
4946
+ case 1:
4947
+ finalResult = _b.sent();
4948
+ if (isCrashedOnError) {
4949
+ assertsTaskSuccessful(finalResult);
4950
+ }
4951
+ return [2 /*return*/, finalResult];
4952
+ }
4953
+ });
4954
+ });
4891
4955
  }
4892
- /*
4893
- TODO: [🧠][🍫] `tasks` can not be determined if they are fully prepared SO ignoring them
4894
- > if (!pipeline.tasks.every(({ preparedContent }) => preparedContent === undefined)) {
4895
- > return false;
4896
- > }
4897
- */
4898
- return true;
4956
+ return {
4957
+ taskType: taskType,
4958
+ taskId: taskId,
4959
+ asPromise: asPromise,
4960
+ asObservable: function () {
4961
+ return rxjs.concat(resultSubject.asObservable(), rxjs.from(asPromise({
4962
+ isCrashedOnError: true,
4963
+ })));
4964
+ },
4965
+ };
4899
4966
  }
4900
4967
  /**
4901
- * TODO: [🔃][main] If the pipeline was prepared with different version or different set of models, prepare it once again
4902
- * TODO: [🐠] Maybe base this on `makeValidator`
4903
- * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
4904
- * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
4905
- * - [🏍] ? Is context in each task
4906
- * - [♨] Are examples prepared
4907
- * - [♨] Are tasks prepared
4968
+ * TODO: Maybe allow to terminate the task and add getter `isFinished` or `status`
4969
+ * TODO: [🐚] Split into more files and make `PrepareTask` & `RemoteTask` + split the function
4908
4970
  */
4909
4971
 
4972
+ /**
4973
+ * Serializes an error into a [🚉] JSON-serializable object
4974
+ *
4975
+ * @public exported from `@promptbook/utils`
4976
+ */
4977
+ function serializeError(error) {
4978
+ var name = error.name, message = error.message, stack = error.stack;
4979
+ if (!Object.keys(ALL_ERRORS).includes(name)) {
4980
+ console.error(spaceTrim__default["default"](function (block) { return "\n \n Cannot serialize error with name \"".concat(name, "\"\n\n ").concat(block(stack || message), "\n \n "); }));
4981
+ }
4982
+ return {
4983
+ name: name,
4984
+ message: message,
4985
+ stack: stack,
4986
+ };
4987
+ }
4988
+
4910
4989
  /**
4911
4990
  * Format either small or big number
4912
4991
  *
@@ -4982,23 +5061,6 @@
4982
5061
  }
4983
5062
  }
4984
5063
 
4985
- /**
4986
- * Serializes an error into a [🚉] JSON-serializable object
4987
- *
4988
- * @public exported from `@promptbook/utils`
4989
- */
4990
- function serializeError(error) {
4991
- var name = error.name, message = error.message, stack = error.stack;
4992
- if (!Object.keys(ALL_ERRORS).includes(name)) {
4993
- console.error(spaceTrim__default["default"](function (block) { return "\n \n Cannot serialize error with name \"".concat(name, "\"\n\n ").concat(block(stack || message), "\n \n "); }));
4994
- }
4995
- return {
4996
- name: name,
4997
- message: message,
4998
- stack: stack,
4999
- };
5000
- }
5001
-
5002
5064
  /**
5003
5065
  * Parses the given script and returns the list of all used variables that are not defined in the script
5004
5066
  *
@@ -6462,27 +6524,20 @@
6462
6524
  */
6463
6525
  function executeTask(options) {
6464
6526
  return __awaiter(this, void 0, void 0, function () {
6465
- var currentTask, preparedPipeline, parametersToPass, tools, onProgress, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled, isNotPreparedWarningSupressed, name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_1, _d, _e, parameterName, maxAttempts, jokerParameterNames, preparedContent, resultString;
6466
- var e_1, _f, _g;
6467
- return __generator(this, function (_h) {
6468
- switch (_h.label) {
6527
+ var currentTask, preparedPipeline, parametersToPass, tools, onProgress, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled, isNotPreparedWarningSupressed, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_1, _d, _e, parameterName, maxAttempts, jokerParameterNames, preparedContent, resultString;
6528
+ var _f, e_1, _g, _h, _j;
6529
+ return __generator(this, function (_k) {
6530
+ switch (_k.label) {
6469
6531
  case 0:
6470
6532
  currentTask = options.currentTask, preparedPipeline = options.preparedPipeline, parametersToPass = options.parametersToPass, tools = options.tools, onProgress = options.onProgress, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification, maxExecutionAttempts = options.maxExecutionAttempts, maxParallelCount = options.maxParallelCount, csvSettings = options.csvSettings, isVerbose = options.isVerbose, rootDirname = options.rootDirname, cacheDirname = options.cacheDirname, intermediateFilesStrategy = options.intermediateFilesStrategy, isAutoInstalled = options.isAutoInstalled, isNotPreparedWarningSupressed = options.isNotPreparedWarningSupressed;
6471
- name = "pipeline-executor-frame-".concat(currentTask.name);
6472
- title = currentTask.title;
6473
6533
  priority = preparedPipeline.tasks.length - preparedPipeline.tasks.indexOf(currentTask);
6474
6534
  return [4 /*yield*/, onProgress({
6475
- name: name,
6476
- title: title,
6477
- isStarted: false,
6478
- isDone: false,
6479
- taskType: currentTask.taskType,
6480
- parameterName: currentTask.resultingParameterName,
6481
- parameterValue: null,
6482
- // <- [🍸]
6535
+ outputParameters: (_f = {},
6536
+ _f[currentTask.resultingParameterName] = '',
6537
+ _f),
6483
6538
  })];
6484
6539
  case 1:
6485
- _h.sent();
6540
+ _k.sent();
6486
6541
  usedParameterNames = extractParameterNamesFromTask(currentTask);
6487
6542
  dependentParameterNames = new Set(currentTask.dependentParameterNames);
6488
6543
  // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
@@ -6501,7 +6556,7 @@
6501
6556
  pipelineIdentification: pipelineIdentification,
6502
6557
  })];
6503
6558
  case 2:
6504
- definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_h.sent())])), parametersToPass])]);
6559
+ definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_k.sent())])), parametersToPass])]);
6505
6560
  definedParameterNames = new Set(Object.keys(definedParameters));
6506
6561
  parameters = {};
6507
6562
  _loop_1 = function (parameterName) {
@@ -6529,7 +6584,7 @@
6529
6584
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
6530
6585
  finally {
6531
6586
  try {
6532
- if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
6587
+ if (_e && !_e.done && (_g = _d.return)) _g.call(_d);
6533
6588
  }
6534
6589
  finally { if (e_1) throw e_1.error; }
6535
6590
  }
@@ -6560,24 +6615,19 @@
6560
6615
  isNotPreparedWarningSupressed: isNotPreparedWarningSupressed,
6561
6616
  })];
6562
6617
  case 3:
6563
- resultString = _h.sent();
6618
+ resultString = _k.sent();
6564
6619
  return [4 /*yield*/, onProgress({
6565
- name: name,
6566
- title: title,
6567
- isStarted: true,
6568
- isDone: true,
6569
- taskType: currentTask.taskType,
6570
- parameterName: currentTask.resultingParameterName,
6571
- parameterValue: resultString,
6572
- // <- [🍸]
6620
+ outputParameters: (_h = {},
6621
+ _h[currentTask.resultingParameterName] = resultString,
6622
+ _h),
6573
6623
  })];
6574
6624
  case 4:
6575
- _h.sent();
6576
- return [2 /*return*/, Object.freeze((_g = {},
6577
- _g[currentTask.resultingParameterName] =
6625
+ _k.sent();
6626
+ return [2 /*return*/, Object.freeze((_j = {},
6627
+ _j[currentTask.resultingParameterName] =
6578
6628
  // <- Note: [👩‍👩‍👧] No need to detect parameter collision here because pipeline checks logic consistency during construction
6579
6629
  resultString,
6580
- _g))];
6630
+ _j))];
6581
6631
  }
6582
6632
  });
6583
6633
  });
@@ -6585,9 +6635,6 @@
6585
6635
  /**
6586
6636
  * TODO: [🤹‍♂️]
6587
6637
  */
6588
- /**
6589
- * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
6590
- */
6591
6638
 
6592
6639
  /**
6593
6640
  * @@@
@@ -6849,15 +6896,15 @@
6849
6896
  return [3 /*break*/, 4];
6850
6897
  case 3:
6851
6898
  unresovedTasks_1 = unresovedTasks_1.filter(function (task) { return task !== currentTask; });
6852
- work_1 = executeTask(__assign(__assign({}, options), { currentTask: currentTask, preparedPipeline: preparedPipeline, parametersToPass: parametersToPass, tools: tools, onProgress: function (progress) {
6899
+ work_1 = executeTask(__assign(__assign({}, options), { currentTask: currentTask, preparedPipeline: preparedPipeline, parametersToPass: parametersToPass, tools: tools, onProgress: function (newOngoingResult) {
6853
6900
  if (isReturned) {
6854
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Can not call `onProgress` after pipeline execution is finished\n\n ".concat(block(pipelineIdentification), "\n\n ").concat(block(JSON.stringify(progress, null, 4)
6901
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Can not call `onProgress` after pipeline execution is finished\n\n ".concat(block(pipelineIdentification), "\n\n ").concat(block(JSON.stringify(newOngoingResult, null, 4)
6855
6902
  .split('\n')
6856
6903
  .map(function (line) { return "> ".concat(line); })
6857
6904
  .join('\n')), "\n "); }));
6858
6905
  }
6859
6906
  if (onProgress) {
6860
- onProgress(progress);
6907
+ onProgress(newOngoingResult);
6861
6908
  }
6862
6909
  }, $executionReport: executionReport, pipelineIdentification: spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Task name: ").concat(currentTask.name, "\n Task title: ").concat(currentTask.title, "\n "); }) }))
6863
6910
  .then(function (newParametersToPass) {
@@ -6960,9 +7007,6 @@
6960
7007
  });
6961
7008
  });
6962
7009
  }
6963
- /**
6964
- * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
6965
- */
6966
7010
 
6967
7011
  /**
6968
7012
  * Creates executor function from pipeline and execution tools.
@@ -6994,7 +7038,7 @@
6994
7038
  console.warn(spaceTrim.spaceTrim(function (block) { return "\n Pipeline is not prepared\n\n ".concat(block(pipelineIdentification), "\n\n It will be prepared ad-hoc before the first execution and **returned as `preparedPipeline` in `PipelineExecutorResult`**\n But it is recommended to prepare the pipeline during collection preparation\n\n @see more at https://ptbk.io/prepare-pipeline\n "); }));
6995
7039
  }
6996
7040
  var runCount = 0;
6997
- var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
7041
+ var pipelineExecutorWithCallback = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
6998
7042
  return __generator(this, function (_a) {
6999
7043
  runCount++;
7000
7044
  return [2 /*return*/, /* not await */ executePipeline({
@@ -7019,11 +7063,23 @@
7019
7063
  })];
7020
7064
  });
7021
7065
  }); };
7066
+ var pipelineExecutor = function (inputParameters) {
7067
+ return createTask({
7068
+ taskType: 'EXECUTION',
7069
+ taskProcessCallback: function (updateOngoingResult) {
7070
+ var _this = this;
7071
+ return pipelineExecutorWithCallback(inputParameters, function (newOngoingResult) { return __awaiter(_this, void 0, void 0, function () {
7072
+ return __generator(this, function (_a) {
7073
+ updateOngoingResult(newOngoingResult);
7074
+ return [2 /*return*/];
7075
+ });
7076
+ }); });
7077
+ },
7078
+ });
7079
+ };
7080
+ // <- TODO: Make types such as there is no need to do `as` for `createTask`
7022
7081
  return pipelineExecutor;
7023
7082
  }
7024
- /**
7025
- * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
7026
- */
7027
7083
 
7028
7084
  /**
7029
7085
  * Async version of Array.forEach
@@ -7141,10 +7197,9 @@
7141
7197
  return modelName;
7142
7198
  })
7143
7199
  .join(',');
7144
- return [4 /*yield*/, preparePersonaExecutor({ availableModelNames: availableModelNames, personaDescription: personaDescription })];
7200
+ return [4 /*yield*/, preparePersonaExecutor({ availableModelNames: availableModelNames, personaDescription: personaDescription }).asPromise()];
7145
7201
  case 3:
7146
7202
  result = _d.sent();
7147
- assertsExecutionSuccessful(result);
7148
7203
  outputParameters = result.outputParameters;
7149
7204
  modelRequirementsRaw = outputParameters.modelRequirements;
7150
7205
  modelRequirements = JSON.parse(modelRequirementsRaw);
@@ -7659,10 +7714,9 @@
7659
7714
  var content = _a.content;
7660
7715
  return content;
7661
7716
  }).join('\n\n'),
7662
- })];
7717
+ }).asPromise()];
7663
7718
  case 2:
7664
7719
  result = _e.sent();
7665
- assertsExecutionSuccessful(result);
7666
7720
  outputParameters = result.outputParameters;
7667
7721
  titleRaw = outputParameters.title;
7668
7722
  if (isVerbose) {
@@ -12244,7 +12298,7 @@
12244
12298
  function $initializeMakeCommand(program) {
12245
12299
  var _this = this;
12246
12300
  var makeCommand = program.command('make');
12247
- makeCommand.description(spaceTrim__default["default"]("\n Makes a new pipeline collection in given folder\n "));
12301
+ makeCommand.description(spaceTrim__default["default"]("\n Makes a new pipeline collection in given folder\n "));
12248
12302
  // TODO: [🧅] DRY command arguments
12249
12303
  makeCommand.argument('[path]',
12250
12304
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
@@ -12541,7 +12595,7 @@
12541
12595
  function $initializePrettifyCommand(program) {
12542
12596
  var _this = this;
12543
12597
  var prettifyCommand = program.command('prettify');
12544
- prettifyCommand.description(spaceTrim__default["default"]("\n Iterates over `.book.md` files and does multiple enhancing operations on them:\n\n 1) Adds Mermaid graph\n 2) Prettifies the markdown\n "));
12598
+ prettifyCommand.description(spaceTrim__default["default"]("\n Iterates over `.book.md` files and does multiple enhancing operations on them:\n\n 1) Adds Mermaid graph\n 2) Prettifies the markdown\n "));
12545
12599
  prettifyCommand.argument('<filesGlob>',
12546
12600
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
12547
12601
  'Pipelines to prettify as glob pattern');
@@ -13192,10 +13246,9 @@
13192
13246
  previousConversationSummary: conversationSummary_1,
13193
13247
  userMessage: userMessage_1,
13194
13248
  };
13195
- return [4 /*yield*/, pipelineExecutor(inputParameters)];
13249
+ return [4 /*yield*/, pipelineExecutor(inputParameters).asPromise()];
13196
13250
  case 3:
13197
13251
  result_1 = _c.sent();
13198
- assertsExecutionSuccessful(result_1);
13199
13252
  console.info("\n");
13200
13253
  console.info(spaceTrim__default["default"](function (block) { return "\n\n ".concat(colors__default["default"].bold(colors__default["default"].green('Chatbot:')), "\n ").concat(block(colors__default["default"].green(result_1.outputParameters.chatbotResponse)), "\n\n "); }));
13201
13254
  ongoingParameters = result_1.outputParameters;
@@ -13242,7 +13295,7 @@
13242
13295
  function $initializeRunCommand(program) {
13243
13296
  var _this = this;
13244
13297
  var runCommand = program.command('run', { isDefault: true });
13245
- runCommand.description(spaceTrim__default["default"]("\n Runs a pipeline\n "));
13298
+ runCommand.description(spaceTrim__default["default"]("\n Runs a pipeline\n "));
13246
13299
  // TODO: [🧅] DRY command arguments
13247
13300
  runCommand.argument('[pipelineSource]', 'Path to book file OR URL to book file, if not provided it will be asked');
13248
13301
  runCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
@@ -13252,10 +13305,10 @@
13252
13305
  runCommand.option('-j, --json <json>', "Pass all or some input parameters as JSON record, if used the output is also returned as JSON");
13253
13306
  runCommand.option('-s, --save-report <path>', "Save report to file");
13254
13307
  runCommand.action(function (pipelineSource, options) { return __awaiter(_this, void 0, void 0, function () {
13255
- var isCacheReloaded, isInteractive, isFormfactorUsed, json, isVerbose, saveReport, inputParameters, prepareAndScrapeOptions, fs, llm, error_1, response_1, executables, tools, pipeline, error_2, pipelineExecutor, questions, response, result, isSuccessful, errors, warnings, outputParameters, executionReport, executionReportString, _a, _b, error, _c, _d, warning, _e, _f, key, value, separator;
13256
- var _g, e_1, _h, e_2, _j, e_3, _k;
13257
- return __generator(this, function (_l) {
13258
- switch (_l.label) {
13308
+ var isCacheReloaded, isInteractive, isFormfactorUsed, json, isVerbose, saveReport, inputParameters, prepareAndScrapeOptions, fs, llm, error_1, response_1, executables, tools, pipeline, error_2, pipelineExecutor, questions, response, executionTask, _a, isSuccessful, errors, warnings, outputParameters, executionReport, usage, executionReportString, _b, _c, error, _d, _e, warning, _f, _g, key, value, separator;
13309
+ var _h, e_1, _j, e_2, _k, e_3, _l;
13310
+ return __generator(this, function (_m) {
13311
+ switch (_m.label) {
13259
13312
  case 0:
13260
13313
  isCacheReloaded = options.reload, isInteractive = options.interactive, isFormfactorUsed = options.formfactor, json = options.json, isVerbose = options.verbose, saveReport = options.saveReport;
13261
13314
  if (saveReport && !saveReport.endsWith('.json') && !saveReport.endsWith('.md')) {
@@ -13275,15 +13328,15 @@
13275
13328
  console.info(colors__default["default"].gray('--- Preparing tools ---'));
13276
13329
  }
13277
13330
  fs = $provideFilesystemForNode(prepareAndScrapeOptions);
13278
- _l.label = 1;
13331
+ _m.label = 1;
13279
13332
  case 1:
13280
- _l.trys.push([1, 3, , 7]);
13333
+ _m.trys.push([1, 3, , 7]);
13281
13334
  return [4 /*yield*/, $provideLlmToolsForWizzardOrCli(prepareAndScrapeOptions)];
13282
13335
  case 2:
13283
- llm = _l.sent();
13336
+ llm = _m.sent();
13284
13337
  return [3 /*break*/, 7];
13285
13338
  case 3:
13286
- error_1 = _l.sent();
13339
+ error_1 = _m.sent();
13287
13340
  if (!(error_1 instanceof Error)) {
13288
13341
  throw error_1;
13289
13342
  }
@@ -13299,7 +13352,7 @@
13299
13352
  .join('\n')), "\n\n ").concat(block($registeredLlmToolsMessage()), "\n "); })));
13300
13353
  return [4 /*yield*/, isFileExisting('.env', fs)];
13301
13354
  case 4:
13302
- if (!!(_l.sent())) return [3 /*break*/, 6];
13355
+ if (!!(_m.sent())) return [3 /*break*/, 6];
13303
13356
  return [4 /*yield*/, promises.writeFile(path.join(process.cwd(), '.env'), $llmToolsMetadataRegister
13304
13357
  .list()
13305
13358
  .flatMap(function (_a) {
@@ -13310,8 +13363,8 @@
13310
13363
  })
13311
13364
  .join('\n'), 'utf8')];
13312
13365
  case 5:
13313
- _l.sent();
13314
- _l.label = 6;
13366
+ _m.sent();
13367
+ _m.label = 6;
13315
13368
  case 6:
13316
13369
  // TODO: If the cwd is git repository, auto-create .gitignore and add .env to it
13317
13370
  return [2 /*return*/, process.exit(1)];
@@ -13324,44 +13377,44 @@
13324
13377
  validate: function (value) { return (value.length > 0 ? true : 'Pipeline source is required'); },
13325
13378
  })];
13326
13379
  case 8:
13327
- response_1 = _l.sent();
13380
+ response_1 = _m.sent();
13328
13381
  if (!response_1.pipelineSource) {
13329
13382
  console.error(colors__default["default"].red('Pipeline source is required'));
13330
13383
  return [2 /*return*/, process.exit(1)];
13331
13384
  }
13332
13385
  pipelineSource = response_1.pipelineSource;
13333
- _l.label = 9;
13386
+ _m.label = 9;
13334
13387
  case 9:
13335
13388
  if (isVerbose) {
13336
13389
  console.info(colors__default["default"].gray('--- Getting the tools ---'));
13337
13390
  }
13338
13391
  return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
13339
13392
  case 10:
13340
- executables = _l.sent();
13341
- _g = {
13393
+ executables = _m.sent();
13394
+ _h = {
13342
13395
  llm: llm,
13343
13396
  fs: fs,
13344
13397
  fetch: scraperFetch
13345
13398
  };
13346
13399
  return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
13347
13400
  case 11:
13348
- tools = (_g.scrapers = _l.sent(),
13349
- _g.script = [
13401
+ tools = (_h.scrapers = _m.sent(),
13402
+ _h.script = [
13350
13403
  /*new JavascriptExecutionTools(options)*/
13351
13404
  ],
13352
- _g);
13405
+ _h);
13353
13406
  if (isVerbose) {
13354
13407
  console.info(colors__default["default"].gray('--- Getting the book ---'));
13355
13408
  }
13356
- _l.label = 12;
13409
+ _m.label = 12;
13357
13410
  case 12:
13358
- _l.trys.push([12, 14, , 15]);
13411
+ _m.trys.push([12, 14, , 15]);
13359
13412
  return [4 /*yield*/, $getCompiledBook(tools, pipelineSource, prepareAndScrapeOptions)];
13360
13413
  case 13:
13361
- pipeline = _l.sent();
13414
+ pipeline = _m.sent();
13362
13415
  return [3 /*break*/, 15];
13363
13416
  case 14:
13364
- error_2 = _l.sent();
13417
+ error_2 = _m.sent();
13365
13418
  if (!(error_2 instanceof ParseError)) {
13366
13419
  throw error_2;
13367
13420
  }
@@ -13454,80 +13507,85 @@
13454
13507
  }
13455
13508
  return [4 /*yield*/, prompts__default["default"](questions)];
13456
13509
  case 16:
13457
- response = _l.sent();
13510
+ response = _m.sent();
13458
13511
  // <- TODO: [🧠][🍼] Change behavior according to the formfactor
13459
13512
  inputParameters = __assign(__assign({}, inputParameters), response);
13460
13513
  // TODO: Maybe do some validation of the response (and --json argument which is passed)
13461
13514
  if (isVerbose) {
13462
13515
  console.info(colors__default["default"].gray('--- Executing ---'));
13463
13516
  }
13464
- return [4 /*yield*/, pipelineExecutor(inputParameters, function (taskProgress) {
13465
- if (isVerbose) {
13466
- console.info(colors__default["default"].gray('--- Progress ---'));
13467
- console.info(taskProgress);
13468
- }
13469
- })];
13517
+ return [4 /*yield*/, pipelineExecutor(inputParameters)];
13470
13518
  case 17:
13471
- result = _l.sent();
13472
- isSuccessful = result.isSuccessful, errors = result.errors, warnings = result.warnings, outputParameters = result.outputParameters, executionReport = result.executionReport;
13519
+ executionTask = _m.sent();
13520
+ if (isVerbose) {
13521
+ executionTask.asObservable().subscribe(function (progress) {
13522
+ console.info(colors__default["default"].gray('--- Progress ---'));
13523
+ console.info(progress);
13524
+ });
13525
+ }
13526
+ return [4 /*yield*/, executionTask.asPromise({
13527
+ isCrashedOnError: false,
13528
+ })];
13529
+ case 18:
13530
+ _a = _m.sent(), isSuccessful = _a.isSuccessful, errors = _a.errors, warnings = _a.warnings, outputParameters = _a.outputParameters, executionReport = _a.executionReport, usage = _a.usage;
13473
13531
  if (isVerbose) {
13474
13532
  console.info(colors__default["default"].gray('--- Detailed Result ---'));
13475
13533
  console.info({ isSuccessful: isSuccessful, errors: errors, warnings: warnings, outputParameters: outputParameters, executionReport: executionReport });
13476
13534
  }
13477
- if (!(saveReport && saveReport.endsWith('.json'))) return [3 /*break*/, 19];
13535
+ if (!(saveReport && saveReport.endsWith('.json'))) return [3 /*break*/, 20];
13478
13536
  return [4 /*yield*/, promises.writeFile(saveReport, JSON.stringify(executionReport, null, 4) + '\n', 'utf-8')];
13479
- case 18:
13480
- _l.sent();
13481
- return [3 /*break*/, 21];
13482
13537
  case 19:
13483
- if (!(saveReport && saveReport.endsWith('.md'))) return [3 /*break*/, 21];
13538
+ _m.sent();
13539
+ return [3 /*break*/, 22];
13540
+ case 20:
13541
+ if (!(saveReport && saveReport.endsWith('.md'))) return [3 /*break*/, 22];
13484
13542
  executionReportString = executionReportJsonToString(executionReport);
13485
13543
  return [4 /*yield*/, promises.writeFile(saveReport, executionReportString, 'utf-8')];
13486
- case 20:
13487
- _l.sent();
13488
- _l.label = 21;
13489
13544
  case 21:
13545
+ _m.sent();
13546
+ _m.label = 22;
13547
+ case 22:
13490
13548
  if (saveReport && isVerbose) {
13491
13549
  console.info(colors__default["default"].green("Report saved to ".concat(saveReport)));
13492
13550
  }
13493
13551
  if (isVerbose) {
13494
13552
  console.info(colors__default["default"].gray('--- Usage ---'));
13495
- console.info(colors__default["default"].cyan(usageToHuman(result.usage)));
13553
+ console.info(colors__default["default"].cyan(usageToHuman(usage)));
13496
13554
  }
13497
13555
  if (json === undefined || isVerbose === true) {
13498
13556
  console.info(colors__default["default"].gray('--- Result ---'));
13499
13557
  }
13500
13558
  try {
13501
13559
  // TODO: [🧠] Should be errors or warnings shown first
13502
- for (_a = __values(errors || []), _b = _a.next(); !_b.done; _b = _a.next()) {
13503
- error = _b.value;
13560
+ for (_b = __values(errors || []), _c = _b.next(); !_c.done; _c = _b.next()) {
13561
+ error = _c.value;
13504
13562
  console.error(colors__default["default"].red(colors__default["default"].bold(error.name) + ': ' + error.message));
13505
13563
  }
13506
13564
  }
13507
13565
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
13508
13566
  finally {
13509
13567
  try {
13510
- if (_b && !_b.done && (_h = _a.return)) _h.call(_a);
13568
+ if (_c && !_c.done && (_j = _b.return)) _j.call(_b);
13511
13569
  }
13512
13570
  finally { if (e_1) throw e_1.error; }
13513
13571
  }
13514
13572
  try {
13515
- for (_c = __values(warnings || []), _d = _c.next(); !_d.done; _d = _c.next()) {
13516
- warning = _d.value;
13573
+ for (_d = __values(warnings || []), _e = _d.next(); !_e.done; _e = _d.next()) {
13574
+ warning = _e.value;
13517
13575
  console.error(colors__default["default"].red(colors__default["default"].bold(warning.name) + ': ' + warning.message));
13518
13576
  }
13519
13577
  }
13520
13578
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
13521
13579
  finally {
13522
13580
  try {
13523
- if (_d && !_d.done && (_j = _c.return)) _j.call(_c);
13581
+ if (_e && !_e.done && (_k = _d.return)) _k.call(_d);
13524
13582
  }
13525
13583
  finally { if (e_2) throw e_2.error; }
13526
13584
  }
13527
13585
  if (json === undefined) {
13528
13586
  try {
13529
- for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
13530
- key = _f.value;
13587
+ for (_f = __values(Object.keys(outputParameters)), _g = _f.next(); !_g.done; _g = _f.next()) {
13588
+ key = _g.value;
13531
13589
  value = outputParameters[key] || colors__default["default"].grey(colors__default["default"].italic('(nothing)'));
13532
13590
  separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
13533
13591
  console.info(colors__default["default"].green(colors__default["default"].bold(key) + separator + value));
@@ -13536,7 +13594,7 @@
13536
13594
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
13537
13595
  finally {
13538
13596
  try {
13539
- if (_f && !_f.done && (_k = _e.return)) _k.call(_e);
13597
+ if (_g && !_g.done && (_l = _f.return)) _l.call(_f);
13540
13598
  }
13541
13599
  finally { if (e_3) throw e_3.error; }
13542
13600
  }
@@ -13687,6 +13745,419 @@
13687
13745
  * Note: This is named "test-command.ts" to avoid name collision with jest unit test files
13688
13746
  */
13689
13747
 
13748
+ /**
13749
+ * Remote server is a proxy server that uses its execution tools internally and exposes the executor interface externally.
13750
+ *
13751
+ * You can simply use `RemoteExecutionTools` on client-side javascript and connect to your remote server.
13752
+ * This is useful to make all logic on browser side but not expose your API keys or no need to use customer's GPU.
13753
+ *
13754
+ * @see https://github.com/webgptorg/promptbook#remote-server
13755
+ * @public exported from `@promptbook/remote-server`
13756
+ */
13757
+ function startRemoteServer(options) {
13758
+ var _this = this;
13759
+ var _a = __assign({ isAnonymousModeAllowed: false, isApplicationModeAllowed: false, collection: null, createLlmExecutionTools: null }, options), port = _a.port, path = _a.path, collection = _a.collection, createLlmExecutionTools = _a.createLlmExecutionTools, isAnonymousModeAllowed = _a.isAnonymousModeAllowed, isApplicationModeAllowed = _a.isApplicationModeAllowed, _b = _a.isVerbose, isVerbose = _b === void 0 ? DEFAULT_IS_VERBOSE : _b;
13760
+ // <- TODO: [🦪] Some helper type to be able to use discriminant union types with destructuring
13761
+ var app = express__default["default"]();
13762
+ app.use(express__default["default"].json());
13763
+ app.get('/', function (request, response) { return __awaiter(_this, void 0, void 0, function () {
13764
+ var _a, _b;
13765
+ var _this = this;
13766
+ var _c;
13767
+ return __generator(this, function (_d) {
13768
+ switch (_d.label) {
13769
+ case 0:
13770
+ if ((_c = request.url) === null || _c === void 0 ? void 0 : _c.includes('socket.io')) {
13771
+ return [2 /*return*/];
13772
+ }
13773
+ _b = (_a = response).send;
13774
+ // TODO: !!!!!! Make this either valid html or text - http://localhost:4460/
13775
+ return [4 /*yield*/, spaceTrim.spaceTrim(function (block) { return __awaiter(_this, void 0, void 0, function () {
13776
+ var _a, _b, _c, _d, _e;
13777
+ return __generator(this, function (_f) {
13778
+ switch (_f.label) {
13779
+ case 0:
13780
+ _b = (_a = "\n Server for processing promptbook remote requests is running.\n\n Version: ".concat(PROMPTBOOK_ENGINE_VERSION, "\n Socket.io path: ").concat(path, "/socket.io\n Anonymouse mode: ").concat(isAnonymousModeAllowed ? 'enabled' : 'disabled', "\n Application mode: ").concat(isApplicationModeAllowed ? 'enabled' : 'disabled', "\n ")).concat;
13781
+ _c = block;
13782
+ if (!(!isApplicationModeAllowed || collection === null)) return [3 /*break*/, 1];
13783
+ _d = '';
13784
+ return [3 /*break*/, 3];
13785
+ case 1:
13786
+ _e = 'Pipelines in collection:\n';
13787
+ return [4 /*yield*/, collection.listPipelines()];
13788
+ case 2:
13789
+ _d = _e +
13790
+ (_f.sent())
13791
+ .map(function (pipelineUrl) { return "- ".concat(pipelineUrl); })
13792
+ .join('\n');
13793
+ _f.label = 3;
13794
+ case 3: return [2 /*return*/, _b.apply(_a, [_c.apply(void 0, [_d]), "\n\n For more information look at:\n https://github.com/webgptorg/promptbook\n "])];
13795
+ }
13796
+ });
13797
+ }); })];
13798
+ case 1:
13799
+ _b.apply(_a, [
13800
+ // TODO: !!!!!! Make this either valid html or text - http://localhost:4460/
13801
+ _d.sent()]);
13802
+ return [2 /*return*/];
13803
+ }
13804
+ });
13805
+ }); });
13806
+ var runningExecutionTasks = [];
13807
+ // TODO: !!!!!! Do here some garbage collection of finished tasks
13808
+ app.get('/executions', function (request, response) { return __awaiter(_this, void 0, void 0, function () {
13809
+ return __generator(this, function (_a) {
13810
+ response.send(runningExecutionTasks);
13811
+ return [2 /*return*/];
13812
+ });
13813
+ }); });
13814
+ app.get('/executions/:taskId', function (request, response) { return __awaiter(_this, void 0, void 0, function () {
13815
+ var taskId, execution;
13816
+ return __generator(this, function (_a) {
13817
+ taskId = request.query.taskId;
13818
+ execution = runningExecutionTasks.find(function (executionTask) { return executionTask.taskId === taskId; });
13819
+ if (execution === undefined) {
13820
+ response.status(404).send("Execution \"".concat(taskId, "\" not found"));
13821
+ return [2 /*return*/];
13822
+ }
13823
+ response.send(execution);
13824
+ return [2 /*return*/];
13825
+ });
13826
+ }); });
13827
+ app.post('/executions/new', function (request, response) { return __awaiter(_this, void 0, void 0, function () {
13828
+ var _a, pipelineUrl, inputParameters, pipeline, llm, fs, executables, tools, pipelineExecutor, executionTask;
13829
+ var _b;
13830
+ return __generator(this, function (_c) {
13831
+ switch (_c.label) {
13832
+ case 0:
13833
+ _a = request.body, pipelineUrl = _a.pipelineUrl, inputParameters = _a.inputParameters;
13834
+ return [4 /*yield*/, (collection === null || collection === void 0 ? void 0 : collection.getPipelineByUrl(pipelineUrl))];
13835
+ case 1:
13836
+ pipeline = _c.sent();
13837
+ if (pipeline === undefined) {
13838
+ response.status(404).send("Pipeline \"".concat(pipelineUrl, "\" not found"));
13839
+ return [2 /*return*/];
13840
+ }
13841
+ return [4 /*yield*/, createLlmExecutionTools({
13842
+ appId: '!!!!',
13843
+ userId: '!!!!',
13844
+ customOptions: {},
13845
+ })];
13846
+ case 2:
13847
+ llm = _c.sent();
13848
+ fs = $provideFilesystemForNode();
13849
+ return [4 /*yield*/, $provideExecutablesForNode()];
13850
+ case 3:
13851
+ executables = _c.sent();
13852
+ _b = {
13853
+ llm: llm,
13854
+ fs: fs
13855
+ };
13856
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables })];
13857
+ case 4:
13858
+ tools = (_b.scrapers = _c.sent(),
13859
+ _b);
13860
+ pipelineExecutor = createPipelineExecutor(__assign({ pipeline: pipeline, tools: tools }, options));
13861
+ executionTask = pipelineExecutor(inputParameters);
13862
+ runningExecutionTasks.push(executionTask);
13863
+ response.send(executionTask);
13864
+ return [2 /*return*/];
13865
+ }
13866
+ });
13867
+ }); });
13868
+ var httpServer = http__default["default"].createServer(app);
13869
+ var server = new socket_io.Server(httpServer, {
13870
+ path: path,
13871
+ transports: [/*'websocket', <- TODO: [🌬] Make websocket transport work */ 'polling'],
13872
+ cors: {
13873
+ origin: '*',
13874
+ methods: ['GET', 'POST'],
13875
+ },
13876
+ });
13877
+ server.on('connection', function (socket) {
13878
+ if (isVerbose) {
13879
+ console.info(colors__default["default"].gray("Client connected"), socket.id);
13880
+ }
13881
+ var getExecutionToolsFromIdentification = function (identification) { return __awaiter(_this, void 0, void 0, function () {
13882
+ var isAnonymous, llm, llmToolsConfiguration, appId, userId, customOptions, fs, executables, tools;
13883
+ var _a;
13884
+ return __generator(this, function (_b) {
13885
+ switch (_b.label) {
13886
+ case 0:
13887
+ isAnonymous = identification.isAnonymous;
13888
+ if (isAnonymous === true && !isAnonymousModeAllowed) {
13889
+ throw new PipelineExecutionError("Anonymous mode is not allowed"); // <- TODO: [main] !!3 Test
13890
+ }
13891
+ if (isAnonymous === false && !isApplicationModeAllowed) {
13892
+ throw new PipelineExecutionError("Application mode is not allowed"); // <- TODO: [main] !!3 Test
13893
+ }
13894
+ if (!(isAnonymous === true)) return [3 /*break*/, 1];
13895
+ llmToolsConfiguration = identification.llmToolsConfiguration;
13896
+ llm = createLlmToolsFromConfiguration(llmToolsConfiguration, { isVerbose: isVerbose });
13897
+ return [3 /*break*/, 4];
13898
+ case 1:
13899
+ if (!(isAnonymous === false && createLlmExecutionTools !== null)) return [3 /*break*/, 3];
13900
+ appId = identification.appId, userId = identification.userId, customOptions = identification.customOptions;
13901
+ return [4 /*yield*/, createLlmExecutionTools({
13902
+ appId: appId,
13903
+ userId: userId,
13904
+ customOptions: customOptions,
13905
+ })];
13906
+ case 2:
13907
+ llm = _b.sent();
13908
+ return [3 /*break*/, 4];
13909
+ case 3: throw new PipelineExecutionError("You must provide either llmToolsConfiguration or non-anonymous mode must be propperly configured");
13910
+ case 4:
13911
+ fs = $provideFilesystemForNode();
13912
+ return [4 /*yield*/, $provideExecutablesForNode()];
13913
+ case 5:
13914
+ executables = _b.sent();
13915
+ _a = {
13916
+ llm: llm,
13917
+ fs: fs
13918
+ };
13919
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables })];
13920
+ case 6:
13921
+ tools = (_a.scrapers = _b.sent(),
13922
+ _a);
13923
+ return [2 /*return*/, tools];
13924
+ }
13925
+ });
13926
+ }); };
13927
+ // -----------
13928
+ socket.on('prompt-request', function (request) { return __awaiter(_this, void 0, void 0, function () {
13929
+ var identification, prompt, executionTools, llm, _a, promptResult, _b, error_1;
13930
+ return __generator(this, function (_c) {
13931
+ switch (_c.label) {
13932
+ case 0:
13933
+ identification = request.identification, prompt = request.prompt;
13934
+ if (isVerbose) {
13935
+ console.info(colors__default["default"].bgWhite("Prompt:"), colors__default["default"].gray(JSON.stringify(request, null, 4)));
13936
+ }
13937
+ _c.label = 1;
13938
+ case 1:
13939
+ _c.trys.push([1, 13, 14, 15]);
13940
+ return [4 /*yield*/, getExecutionToolsFromIdentification(identification)];
13941
+ case 2:
13942
+ executionTools = _c.sent();
13943
+ llm = executionTools.llm;
13944
+ _a = identification.isAnonymous === false &&
13945
+ collection !== null;
13946
+ if (!_a) return [3 /*break*/, 4];
13947
+ return [4 /*yield*/, collection.isResponsibleForPrompt(prompt)];
13948
+ case 3:
13949
+ _a = !(_c.sent());
13950
+ _c.label = 4;
13951
+ case 4:
13952
+ if (_a) {
13953
+ throw new PipelineExecutionError("Pipeline is not in the collection of this server");
13954
+ }
13955
+ promptResult = void 0;
13956
+ _b = prompt.modelRequirements.modelVariant;
13957
+ switch (_b) {
13958
+ case 'CHAT': return [3 /*break*/, 5];
13959
+ case 'COMPLETION': return [3 /*break*/, 7];
13960
+ case 'EMBEDDING': return [3 /*break*/, 9];
13961
+ }
13962
+ return [3 /*break*/, 11];
13963
+ case 5:
13964
+ if (llm.callChatModel === undefined) {
13965
+ // Note: [0] This check should not be a thing
13966
+ throw new PipelineExecutionError("Chat model is not available");
13967
+ }
13968
+ return [4 /*yield*/, llm.callChatModel(prompt)];
13969
+ case 6:
13970
+ promptResult = _c.sent();
13971
+ return [3 /*break*/, 12];
13972
+ case 7:
13973
+ if (llm.callCompletionModel === undefined) {
13974
+ // Note: [0] This check should not be a thing
13975
+ throw new PipelineExecutionError("Completion model is not available");
13976
+ }
13977
+ return [4 /*yield*/, llm.callCompletionModel(prompt)];
13978
+ case 8:
13979
+ promptResult = _c.sent();
13980
+ return [3 /*break*/, 12];
13981
+ case 9:
13982
+ if (llm.callEmbeddingModel === undefined) {
13983
+ // Note: [0] This check should not be a thing
13984
+ throw new PipelineExecutionError("Embedding model is not available");
13985
+ }
13986
+ return [4 /*yield*/, llm.callEmbeddingModel(prompt)];
13987
+ case 10:
13988
+ promptResult = _c.sent();
13989
+ return [3 /*break*/, 12];
13990
+ case 11: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
13991
+ case 12:
13992
+ if (isVerbose) {
13993
+ console.info(colors__default["default"].bgGreen("PromptResult:"), colors__default["default"].green(JSON.stringify(promptResult, null, 4)));
13994
+ }
13995
+ socket.emit('prompt-response', { promptResult: promptResult } /* <- Note: [🤛] */);
13996
+ return [3 /*break*/, 15];
13997
+ case 13:
13998
+ error_1 = _c.sent();
13999
+ if (!(error_1 instanceof Error)) {
14000
+ throw error_1;
14001
+ }
14002
+ socket.emit('error', serializeError(error_1) /* <- Note: [🤛] */);
14003
+ return [3 /*break*/, 15];
14004
+ case 14:
14005
+ socket.disconnect();
14006
+ return [7 /*endfinally*/];
14007
+ case 15: return [2 /*return*/];
14008
+ }
14009
+ });
14010
+ }); });
14011
+ // -----------
14012
+ // TODO: [👒] Listing models (and checking configuration) probbably should go through REST API not Socket.io
14013
+ socket.on('listModels-request', function (request) { return __awaiter(_this, void 0, void 0, function () {
14014
+ var identification, executionTools, llm, models, error_2;
14015
+ return __generator(this, function (_a) {
14016
+ switch (_a.label) {
14017
+ case 0:
14018
+ identification = request.identification;
14019
+ if (isVerbose) {
14020
+ console.info(colors__default["default"].bgWhite("Listing models"));
14021
+ }
14022
+ _a.label = 1;
14023
+ case 1:
14024
+ _a.trys.push([1, 4, 5, 6]);
14025
+ return [4 /*yield*/, getExecutionToolsFromIdentification(identification)];
14026
+ case 2:
14027
+ executionTools = _a.sent();
14028
+ llm = executionTools.llm;
14029
+ return [4 /*yield*/, llm.listModels()];
14030
+ case 3:
14031
+ models = _a.sent();
14032
+ socket.emit('listModels-response', { models: models } /* <- Note: [🤛] */);
14033
+ return [3 /*break*/, 6];
14034
+ case 4:
14035
+ error_2 = _a.sent();
14036
+ if (!(error_2 instanceof Error)) {
14037
+ throw error_2;
14038
+ }
14039
+ socket.emit('error', serializeError(error_2));
14040
+ return [3 /*break*/, 6];
14041
+ case 5:
14042
+ socket.disconnect();
14043
+ return [7 /*endfinally*/];
14044
+ case 6: return [2 /*return*/];
14045
+ }
14046
+ });
14047
+ }); });
14048
+ // -----------
14049
+ // TODO: [👒] Listing models (and checking configuration) probbably should go through REST API not Socket.io
14050
+ socket.on('preparePipeline-request', function (request) { return __awaiter(_this, void 0, void 0, function () {
14051
+ var identification, pipeline, executionTools, preparedPipeline, error_3;
14052
+ return __generator(this, function (_a) {
14053
+ switch (_a.label) {
14054
+ case 0:
14055
+ identification = request.identification, pipeline = request.pipeline;
14056
+ if (isVerbose) {
14057
+ console.info(colors__default["default"].bgWhite("Prepare pipeline"));
14058
+ }
14059
+ _a.label = 1;
14060
+ case 1:
14061
+ _a.trys.push([1, 4, 5, 6]);
14062
+ return [4 /*yield*/, getExecutionToolsFromIdentification(identification)];
14063
+ case 2:
14064
+ executionTools = _a.sent();
14065
+ return [4 /*yield*/, preparePipeline(pipeline, executionTools, options)];
14066
+ case 3:
14067
+ preparedPipeline = _a.sent();
14068
+ socket.emit('preparePipeline-response', { preparedPipeline: preparedPipeline } /* <- Note: [🤛] */);
14069
+ return [3 /*break*/, 6];
14070
+ case 4:
14071
+ error_3 = _a.sent();
14072
+ if (!(error_3 instanceof Error)) {
14073
+ throw error_3;
14074
+ }
14075
+ socket.emit('error', serializeError(error_3));
14076
+ return [3 /*break*/, 6];
14077
+ case 5:
14078
+ socket.disconnect();
14079
+ return [7 /*endfinally*/];
14080
+ case 6: return [2 /*return*/];
14081
+ }
14082
+ });
14083
+ }); });
14084
+ // -----------
14085
+ socket.on('disconnect', function () {
14086
+ // TODO: Destroy here executionToolsForClient
14087
+ if (isVerbose) {
14088
+ console.info(colors__default["default"].gray("Client disconnected"), socket.id);
14089
+ }
14090
+ });
14091
+ });
14092
+ httpServer.listen(port);
14093
+ // Note: We want to log this also in non-verbose mode
14094
+ console.info(colors__default["default"].bgGreen("PROMPTBOOK server listening on port ".concat(port)));
14095
+ if (isVerbose) {
14096
+ console.info(colors__default["default"].gray("Verbose mode is enabled"));
14097
+ }
14098
+ var isDestroyed = false;
14099
+ return {
14100
+ get isDestroyed() {
14101
+ return isDestroyed;
14102
+ },
14103
+ destroy: function () {
14104
+ if (isDestroyed) {
14105
+ return;
14106
+ }
14107
+ isDestroyed = true;
14108
+ httpServer.close();
14109
+ server.close();
14110
+ },
14111
+ };
14112
+ }
14113
+ /**
14114
+ * TODO: [👩🏾‍🤝‍🧑🏾] Allow to pass custom fetch function here - PromptbookFetch
14115
+ * TODO: Split this file into multiple functions - handler for each request
14116
+ * TODO: Maybe use `$exportJson`
14117
+ * TODO: [🧠][🛍] Maybe not `isAnonymous: boolean` BUT `mode: 'ANONYMOUS'|'COLLECTION'`
14118
+ * TODO: [⚖] Expose the collection to be able to connect to same collection via createCollectionFromUrl
14119
+ * TODO: Handle progress - support streaming
14120
+ * TODO: [🗯] Do not hang up immediately but wait until client closes OR timeout
14121
+ * TODO: [🗯] Timeout on chat to free up resources
14122
+ * TODO: [🃏] Pass here some security token to prevent malitious usage and/or DDoS
14123
+ * TODO: [0] Set unavailable models as undefined in `RemoteLlmExecutionTools` NOT throw error here
14124
+ * TODO: Allow to constrain anonymous mode for specific models / providers
14125
+ */
14126
+
14127
+ /**
14128
+ * Initializes `start-server` command for Promptbook CLI utilities
14129
+ *
14130
+ * Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI
14131
+ *
14132
+ * @private internal function of `promptbookCli`
14133
+ */
14134
+ function $initializeStartServerCommand(program) {
14135
+ var _this = this;
14136
+ var startServerCommand = program.command('start-server');
14137
+ startServerCommand.option('--port <port>', "Port to start the server on", '4460');
14138
+ startServerCommand.description(spaceTrim__default["default"]("\n @@@\n "));
14139
+ startServerCommand.action(function (_a) {
14140
+ var port = _a.port;
14141
+ return __awaiter(_this, void 0, void 0, function () {
14142
+ return __generator(this, function (_b) {
14143
+ startRemoteServer({
14144
+ path: '/promptbook',
14145
+ port: parseInt(port, 10),
14146
+ isAnonymousModeAllowed: true,
14147
+ isApplicationModeAllowed: true,
14148
+ // <- TODO: !!!!!!
14149
+ });
14150
+ console.error(colors__default["default"].green("Server started on port ".concat(port)));
14151
+ return [2 /*return*/];
14152
+ });
14153
+ });
14154
+ });
14155
+ }
14156
+ /**
14157
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14158
+ * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
14159
+ */
14160
+
13690
14161
  /**
13691
14162
  * Runs CLI utilities of Promptbook package
13692
14163
  *
@@ -13717,6 +14188,7 @@
13717
14188
  $initializeTestCommand(program);
13718
14189
  $initializeListModelsCommand(program);
13719
14190
  $initializeListScrapersCommand(program);
14191
+ $initializeStartServerCommand(program);
13720
14192
  program.parse(process.argv);
13721
14193
  return [2 /*return*/];
13722
14194
  });
@@ -16602,10 +17074,9 @@
16602
17074
  return [4 /*yield*/, source.asText()];
16603
17075
  case 4:
16604
17076
  knowledgeContent = _k.sent();
16605
- return [4 /*yield*/, prepareKnowledgeFromMarkdownExecutor({ knowledgeContent: knowledgeContent })];
17077
+ return [4 /*yield*/, prepareKnowledgeFromMarkdownExecutor({ knowledgeContent: knowledgeContent }).asPromise()];
16606
17078
  case 5:
16607
17079
  result = _k.sent();
16608
- assertsExecutionSuccessful(result);
16609
17080
  outputParameters = result.outputParameters;
16610
17081
  knowledgePiecesRaw = outputParameters.knowledgePieces;
16611
17082
  knowledgeTextPieces = (knowledgePiecesRaw || '').split('\n---\n');
@@ -16628,13 +17099,13 @@
16628
17099
  _c.label = 1;
16629
17100
  case 1:
16630
17101
  _c.trys.push([1, 7, , 8]);
16631
- return [4 /*yield*/, prepareTitleExecutor({ knowledgePieceContent: knowledgePieceContent })];
17102
+ return [4 /*yield*/, prepareTitleExecutor({ knowledgePieceContent: knowledgePieceContent }).asPromise()];
16632
17103
  case 2:
16633
17104
  titleResult = _c.sent();
16634
17105
  _a = titleResult.outputParameters.title, titleRaw = _a === void 0 ? 'Untitled' : _a;
16635
17106
  title = spaceTrim__default["default"](titleRaw) /* <- TODO: Maybe do in pipeline */;
16636
17107
  name = titleToName(title);
16637
- return [4 /*yield*/, prepareKeywordsExecutor({ knowledgePieceContent: knowledgePieceContent })];
17108
+ return [4 /*yield*/, prepareKeywordsExecutor({ knowledgePieceContent: knowledgePieceContent }).asPromise()];
16638
17109
  case 3:
16639
17110
  keywordsResult = _c.sent();
16640
17111
  _b = keywordsResult.outputParameters.keywords, keywordsRaw = _b === void 0 ? '' : _b;