@promptbook/cli 0.59.0-24 → 0.59.0-26

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/umd/index.umd.js CHANGED
@@ -1,16 +1,16 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('commander'), require('spacetrim'), require('colors'), require('waitasecond'), require('fs/promises'), require('glob-promise'), require('prettier'), require('prettier/parser-html')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'commander', 'spacetrim', 'colors', 'waitasecond', 'fs/promises', 'glob-promise', 'prettier', 'prettier/parser-html'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.commander, global.spaceTrim, global.colors, global.waitasecond, global.promises, global.glob, global.prettier, global.parserHtml));
5
- })(this, (function (exports, commander, spaceTrim, colors, waitasecond, promises, glob, prettier, parserHtml) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('commander'), require('spacetrim'), require('colors'), require('waitasecond'), require('fs/promises'), require('path'), require('prettier'), require('prettier/parser-html'), require('glob-promise')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'commander', 'spacetrim', 'colors', 'waitasecond', 'fs/promises', 'path', 'prettier', 'prettier/parser-html', 'glob-promise'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.commander, global.spaceTrim, global.colors, global.waitasecond, global.promises, global.path, global.prettier, global.parserHtml, global.glob));
5
+ })(this, (function (exports, commander, spaceTrim, colors, waitasecond, promises, path, prettier, parserHtml, glob) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
9
  var commander__default = /*#__PURE__*/_interopDefaultLegacy(commander);
10
10
  var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
11
11
  var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
12
- var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
13
12
  var parserHtml__default = /*#__PURE__*/_interopDefaultLegacy(parserHtml);
13
+ var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
14
14
 
15
15
  /*! *****************************************************************************
16
16
  Copyright (c) Microsoft Corporation.
@@ -147,7 +147,7 @@
147
147
  /**
148
148
  * The version of the Promptbook library
149
149
  */
150
- var PROMPTBOOK_VERSION = '0.59.0-23';
150
+ var PROMPTBOOK_VERSION = '0.59.0-25';
151
151
 
152
152
  /**
153
153
  * Initializes testing `hello` command for Promptbook CLI utilities
@@ -180,94 +180,27 @@
180
180
  }
181
181
 
182
182
  /**
183
- * Initializes `make` command for Promptbook CLI utilities
184
- *
185
- * @private part of `promptbookCli`
186
- */
187
- function initializeMake(program) {
188
- var _this = this;
189
- var helloCommand = program.command('make <path>');
190
- helloCommand.description(spaceTrim__default["default"]("\n Makes a new promptbook library in given folder\n "));
191
- helloCommand.argument('<path>', 'Path to promptbook folder');
192
- helloCommand.option('-f, --format <format>', "Output format of builded library \"js\", \"ts\" or \"json\"", 'js');
193
- helloCommand.option('-v, --validate', "Validate logic of promptbook", true);
194
- // TODO: !!! Auto-detect AI api keys + explicit api keys as argv
195
- helloCommand.action(function (path, _a) {
196
- var format = _a.format, validate = _a.validate;
197
- return __awaiter(_this, void 0, void 0, function () {
198
- return __generator(this, function (_b) {
199
- console.info({ path: path, format: format, validate: validate });
200
- // TODO: !!! Implement
201
- // TODO: !!! Validate logic
202
- process.exit(0);
203
- return [2 /*return*/];
204
- });
205
- });
206
- });
207
- }
208
-
209
- /**
210
- * Removes HTML or Markdown comments from a string.
211
- *
212
- * @param {string} content - The string to remove comments from.
213
- * @returns {string} The input string with all comments removed.
183
+ * The maximum number of iterations for a loops
214
184
  */
215
- function removeContentComments(content) {
216
- return spaceTrim.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
217
- }
218
-
185
+ var LOOP_LIMIT = 1000;
219
186
  /**
220
- * Add or modify an auto-generated section in a markdown file
221
- *
222
- * @private within the library
187
+ * The name of the builded promptbook library made by CLI `promptbook make` and for lookup in `createLibraryFromDirectory`
223
188
  */
224
- function addAutoGeneratedSection(content, options) {
225
- var sectionName = options.sectionName, sectionContent = options.sectionContent;
226
- var warningLine = "<!-- \u26A0\uFE0F WARNING: This section was auto-generated -->";
227
- var sectionRegex = new RegExp("<!--".concat(sectionName, "-->([\\s\\S]*?)<!--/").concat(sectionName, "-->"), 'g');
228
- var sectionMatch = content.match(sectionRegex);
229
- if (sectionMatch) {
230
- return content.replace(sectionRegex, spaceTrim.spaceTrim(function (block) { return "\n <!--".concat(sectionName, "-->\n ").concat(block(warningLine), "\n ").concat(block(sectionContent), "\n <!--/").concat(sectionName, "-->\n "); }));
231
- }
232
- var placeForSection = removeContentComments(content).match(/^##.*$/im);
233
- if (!placeForSection) {
234
- throw new Error("No place where to put the section <!--".concat(sectionName, "-->"));
235
- }
236
- var _a = __read(placeForSection, 1), heading = _a[0];
237
- return content.replace(heading, "<!--".concat(sectionName, "-->\n").concat(warningLine, "\n").concat(sectionContent, "\n<!--/").concat(sectionName, "-->\n\n").concat(heading));
238
- }
189
+ var PROMPTBOOK_MAKED_BASE_FILENAME = "promptbook-library";
239
190
 
240
191
  /**
241
- * Prettify the html code
242
- *
243
- * @param content raw html code
244
- * @returns formatted html code
192
+ * This error indicates that the promptbook object has valid syntax but contains logical errors (like circular dependencies)
245
193
  */
246
- function prettifyMarkdown(content) {
247
- try {
248
- return prettier.format(content, {
249
- parser: 'markdown',
250
- plugins: [parserHtml__default["default"]],
251
- // TODO: DRY - make some import or auto-copy of .prettierrc
252
- endOfLine: 'lf',
253
- tabWidth: 4,
254
- singleQuote: true,
255
- trailingComma: 'all',
256
- arrowParens: 'always',
257
- printWidth: 120,
258
- htmlWhitespaceSensitivity: 'ignore',
259
- jsxBracketSameLine: false,
260
- bracketSpacing: true,
261
- });
262
- }
263
- catch (error) {
264
- console.error('There was an error with prettifying the markdown, using the original as the fallback', {
265
- error: error,
266
- html: content,
267
- });
268
- return content;
194
+ var PromptbookLogicError = /** @class */ (function (_super) {
195
+ __extends(PromptbookLogicError, _super);
196
+ function PromptbookLogicError(message) {
197
+ var _this = _super.call(this, message) || this;
198
+ _this.name = 'PromptbookLogicError';
199
+ Object.setPrototypeOf(_this, PromptbookLogicError.prototype);
200
+ return _this;
269
201
  }
270
- }
202
+ return PromptbookLogicError;
203
+ }(Error));
271
204
 
272
205
  /**
273
206
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -283,66 +216,6 @@
283
216
  return PromptbookSyntaxError;
284
217
  }(Error));
285
218
 
286
- var promptbookLibrary = [{title:"Prepare Knowledge from Markdown",promptbookUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.59.0-23",parameters:[{name:"content",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledge",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{name:"knowledge",title:"Knowledge",dependentParameterNames:["content"],executionType:"PROMPT_TEMPLATE",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {content}",resultingParameterName:"knowledge"}],knowledge:[]}];
287
-
288
- /**
289
- * This error indicates errors during the execution of the promptbook
290
- */
291
- var PromptbookExecutionError = /** @class */ (function (_super) {
292
- __extends(PromptbookExecutionError, _super);
293
- function PromptbookExecutionError(message) {
294
- var _this = _super.call(this, message) || this;
295
- _this.name = 'PromptbookExecutionError';
296
- Object.setPrototypeOf(_this, PromptbookExecutionError.prototype);
297
- return _this;
298
- }
299
- return PromptbookExecutionError;
300
- }(Error));
301
-
302
- /**
303
- * Asserts that the execution of a promptnook is successful
304
- *
305
- * @param executionResult - The partial result of the promptnook execution
306
- * @throws {PromptbookExecutionError} If the execution is not successful or if multiple errors occurred
307
- */
308
- function assertsExecutionSuccessful(executionResult) {
309
- var isSuccessful = executionResult.isSuccessful, errors = executionResult.errors;
310
- if (isSuccessful === true) {
311
- return;
312
- }
313
- if (errors.length === 0) {
314
- throw new PromptbookExecutionError("Promptnook Execution failed because of unknown reason");
315
- }
316
- else if (errors.length === 1) {
317
- throw errors[0];
318
- }
319
- else {
320
- throw new PromptbookExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Multiple errors occurred during promptnook execution\n\n ".concat(block(errors.map(function (error) { return '- ' + error.message; }).join('\n')), "\n "); }));
321
- }
322
- }
323
- /**
324
- * TODO: [🧠] Can this return type be better typed than void
325
- */
326
-
327
- /**
328
- * The maximum number of iterations for a loops
329
- */
330
- var LOOP_LIMIT = 1000;
331
-
332
- /**
333
- * This error indicates that the promptbook object has valid syntax but contains logical errors (like circular dependencies)
334
- */
335
- var PromptbookLogicError = /** @class */ (function (_super) {
336
- __extends(PromptbookLogicError, _super);
337
- function PromptbookLogicError(message) {
338
- var _this = _super.call(this, message) || this;
339
- _this.name = 'PromptbookLogicError';
340
- Object.setPrototypeOf(_this, PromptbookLogicError.prototype);
341
- return _this;
342
- }
343
- return PromptbookLogicError;
344
- }(Error));
345
-
346
219
  /**
347
220
  * This error type indicates that the error should not happen and its last check before crashing with some other error
348
221
  */
@@ -396,7 +269,7 @@
396
269
  * @returns the same promptbook if it is logically valid
397
270
  * @throws {PromptbookLogicError} on logical error in the promptbook
398
271
  */
399
- function validatePromptbookJson(promptbook) {
272
+ function validatePromptbook(promptbook) {
400
273
  // TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
401
274
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
402
275
  if (promptbook.promptbookUrl !== undefined) {
@@ -460,8 +333,7 @@
460
333
  throw new PromptbookLogicError("Parameter {".concat(template.resultingParameterName, "} is defined multiple times"));
461
334
  }
462
335
  definedParameters.add(template.resultingParameterName);
463
- if (template.executionType === 'PROMPT_TEMPLATE' &&
464
- (template.modelRequirements.modelVariant === undefined)) {
336
+ if (template.executionType === 'PROMPT_TEMPLATE' && template.modelRequirements.modelVariant === undefined) {
465
337
  throw new PromptbookLogicError(spaceTrim.spaceTrim("\n\n You must specify MODEL VARIANT in the prompt template \"".concat(template.title, "\"\n\n For example:\n - MODEL VARIANT Chat\n - MODEL NAME `gpt-4-1106-preview`\n\n ")));
466
338
  }
467
339
  if (template.jokers && template.jokers.length > 0) {
@@ -531,7 +403,7 @@
531
403
  var loopLimit = LOOP_LIMIT;
532
404
  var _loop_2 = function () {
533
405
  if (loopLimit-- < 0) {
534
- throw new UnexpectedError('Loop limit reached during detection of circular dependencies in `validatePromptbookJson`');
406
+ throw new UnexpectedError('Loop limit reached during detection of circular dependencies in `validatePromptbook`');
535
407
  }
536
408
  var currentlyResovedTemplates = unresovedTemplates.filter(function (template) {
537
409
  return template.dependentParameterNames.every(function (name) { return resovedParameters.includes(name); });
@@ -566,7 +438,48 @@
566
438
  * > * It checks:
567
439
  * > * - it has a valid structure
568
440
  * > * - ...
569
- * > ex port function validatePromptbookJson(promptbook: unknown): asserts promptbook is PromptbookJson {
441
+ * > ex port function validatePromptbook(promptbook: unknown): asserts promptbook is PromptbookJson {
442
+ */
443
+
444
+ var promptbookLibrary = [{title:"Prepare Knowledge from Markdown",promptbookUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.59.0-25",parameters:[{name:"content",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledge",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{name:"knowledge",title:"Knowledge",dependentParameterNames:["content"],executionType:"PROMPT_TEMPLATE",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {content}",resultingParameterName:"knowledge"}],knowledge:[]}];
445
+
446
+ /**
447
+ * This error indicates errors during the execution of the promptbook
448
+ */
449
+ var PromptbookExecutionError = /** @class */ (function (_super) {
450
+ __extends(PromptbookExecutionError, _super);
451
+ function PromptbookExecutionError(message) {
452
+ var _this = _super.call(this, message) || this;
453
+ _this.name = 'PromptbookExecutionError';
454
+ Object.setPrototypeOf(_this, PromptbookExecutionError.prototype);
455
+ return _this;
456
+ }
457
+ return PromptbookExecutionError;
458
+ }(Error));
459
+
460
+ /**
461
+ * Asserts that the execution of a promptnook is successful
462
+ *
463
+ * @param executionResult - The partial result of the promptnook execution
464
+ * @throws {PromptbookExecutionError} If the execution is not successful or if multiple errors occurred
465
+ */
466
+ function assertsExecutionSuccessful(executionResult) {
467
+ var isSuccessful = executionResult.isSuccessful, errors = executionResult.errors;
468
+ if (isSuccessful === true) {
469
+ return;
470
+ }
471
+ if (errors.length === 0) {
472
+ throw new PromptbookExecutionError("Promptnook Execution failed because of unknown reason");
473
+ }
474
+ else if (errors.length === 1) {
475
+ throw errors[0];
476
+ }
477
+ else {
478
+ throw new PromptbookExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Multiple errors occurred during promptnook execution\n\n ".concat(block(errors.map(function (error) { return '- ' + error.message; }).join('\n')), "\n "); }));
479
+ }
480
+ }
481
+ /**
482
+ * TODO: [🧠] Can this return type be better typed than void
570
483
  */
571
484
 
572
485
  /**
@@ -1144,7 +1057,7 @@
1144
1057
  var _this = this;
1145
1058
  var promptbook = options.promptbook, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
1146
1059
  var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? 3 : _b;
1147
- validatePromptbookJson(promptbook);
1060
+ validatePromptbook(promptbook);
1148
1061
  var promptbookExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
1149
1062
  function executeSingleTemplate(currentTemplate) {
1150
1063
  return __awaiter(this, void 0, void 0, function () {
@@ -1575,7 +1488,7 @@
1575
1488
  return template.dependentParameterNames.every(function (name) { return resovedParameters_1.includes(name); });
1576
1489
  });
1577
1490
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
1578
- throw new UnexpectedError(spaceTrim.spaceTrim("\n Can not resolve some parameters\n\n Note: This should be catched during validatePromptbookJson\n "));
1491
+ throw new UnexpectedError(spaceTrim.spaceTrim("\n Can not resolve some parameters\n\n Note: This should be catched during validatePromptbook\n "));
1579
1492
  case 1:
1580
1493
  if (!!currentTemplate) return [3 /*break*/, 3];
1581
1494
  /* [5] */ return [4 /*yield*/, Promise.race(resolving_1)];
@@ -1665,6 +1578,38 @@
1665
1578
  * TODO: [🧠][3] transparent = (report intermediate parameters) / opaque execution = (report only output parameters) progress reporting mode
1666
1579
  */
1667
1580
 
1581
+ /**
1582
+ * Prettify the html code
1583
+ *
1584
+ * @param content raw html code
1585
+ * @returns formatted html code
1586
+ */
1587
+ function prettifyMarkdown(content) {
1588
+ try {
1589
+ return prettier.format(content, {
1590
+ parser: 'markdown',
1591
+ plugins: [parserHtml__default["default"]],
1592
+ // TODO: DRY - make some import or auto-copy of .prettierrc
1593
+ endOfLine: 'lf',
1594
+ tabWidth: 4,
1595
+ singleQuote: true,
1596
+ trailingComma: 'all',
1597
+ arrowParens: 'always',
1598
+ printWidth: 120,
1599
+ htmlWhitespaceSensitivity: 'ignore',
1600
+ jsxBracketSameLine: false,
1601
+ bracketSpacing: true,
1602
+ });
1603
+ }
1604
+ catch (error) {
1605
+ console.error('There was an error with prettifying the markdown, using the original as the fallback', {
1606
+ error: error,
1607
+ html: content,
1608
+ });
1609
+ return content;
1610
+ }
1611
+ }
1612
+
1668
1613
  /**
1669
1614
  * Makes first letter of a string uppercase
1670
1615
  *
@@ -1930,7 +1875,7 @@
1930
1875
  if (promptbook.promptbookUrl === undefined) {
1931
1876
  throw new PromptbookReferenceError(spaceTrim.spaceTrim("\n Promptbook with name \"".concat(promptbook.title, "\" does not have defined URL\n\n Note: Promptbooks without URLs are called anonymous promptbooks\n They can be used as standalone promptbooks, but they cannot be referenced by other promptbooks\n And also they cannot be used in the promptbook library\n\n ")));
1932
1877
  }
1933
- validatePromptbookJson(promptbook);
1878
+ validatePromptbook(promptbook);
1934
1879
  // Note: [🦄]
1935
1880
  if (this.library.has(promptbook.promptbookUrl) &&
1936
1881
  promptbookJsonToString(promptbook) !==
@@ -1995,11 +1940,7 @@
1995
1940
  for (var _i = 0; _i < arguments.length; _i++) {
1996
1941
  promptbooks[_i] = arguments[_i];
1997
1942
  }
1998
- return __awaiter(this, void 0, void 0, function () {
1999
- return __generator(this, function (_a) {
2000
- return [2 /*return*/, new (SimplePromptbookLibrary.bind.apply(SimplePromptbookLibrary, __spreadArray([void 0], __read(promptbooks), false)))()];
2001
- });
2002
- });
1943
+ return new (SimplePromptbookLibrary.bind.apply(SimplePromptbookLibrary, __spreadArray([void 0], __read(promptbooks), false)))();
2003
1944
  }
2004
1945
 
2005
1946
  /* tslint:disable */
@@ -2065,9 +2006,7 @@
2065
2006
  switch (_b.label) {
2066
2007
  case 0:
2067
2008
  content = options.content, llmTools = options.llmTools, _a = options.isVerbose, isVerbose = _a === void 0 ? false : _a;
2068
- return [4 /*yield*/, createLibraryFromJson.apply(void 0, __spreadArray([], __read(promptbookLibrary), false))];
2069
- case 1:
2070
- library = _b.sent();
2009
+ library = createLibraryFromJson.apply(void 0, __spreadArray([], __read(promptbookLibrary), false));
2071
2010
  promptbook = library.getPromptbookByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md');
2072
2011
  executor = createPromptbookExecutor({
2073
2012
  promptbook: promptbook,
@@ -2079,7 +2018,7 @@
2079
2018
  },
2080
2019
  });
2081
2020
  return [4 /*yield*/, executor({ content: content })];
2082
- case 2:
2021
+ case 1:
2083
2022
  result = _b.sent();
2084
2023
  assertsExecutionSuccessful(result);
2085
2024
  outputParameters = result.outputParameters;
@@ -2118,7 +2057,7 @@
2118
2057
  }];
2119
2058
  });
2120
2059
  }); }))];
2121
- case 3:
2060
+ case 2:
2122
2061
  knowledge = _b.sent();
2123
2062
  return [2 /*return*/, knowledge];
2124
2063
  }
@@ -2359,6 +2298,16 @@
2359
2298
  * TODO: [🍓][🌻] !!! Decide of this is internal util, external util OR validator/postprocessor
2360
2299
  */
2361
2300
 
2301
+ /**
2302
+ * Removes HTML or Markdown comments from a string.
2303
+ *
2304
+ * @param {string} content - The string to remove comments from.
2305
+ * @returns {string} The input string with all comments removed.
2306
+ */
2307
+ function removeContentComments(content) {
2308
+ return spaceTrim.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
2309
+ }
2310
+
2362
2311
  /**
2363
2312
  * Creates a new set with all elements that are present in either set
2364
2313
  */
@@ -3230,6 +3179,504 @@
3230
3179
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
3231
3180
  */
3232
3181
 
3182
+ /**
3183
+ * This error indicates that the promptbook library cannot be propperly loaded
3184
+ */
3185
+ var PromptbookLibraryError = /** @class */ (function (_super) {
3186
+ __extends(PromptbookLibraryError, _super);
3187
+ function PromptbookLibraryError(message) {
3188
+ var _this = _super.call(this, message) || this;
3189
+ _this.name = 'PromptbookLibraryError';
3190
+ Object.setPrototypeOf(_this, PromptbookLibraryError.prototype);
3191
+ return _this;
3192
+ }
3193
+ return PromptbookLibraryError;
3194
+ }(Error));
3195
+
3196
+ /**
3197
+ * Constructs Promptbook from async sources
3198
+ * It can be one of the following:
3199
+ * - Promise of array of PromptbookJson or PromptbookString
3200
+ * - Factory function that returns Promise of array of PromptbookJson or PromptbookString
3201
+ *
3202
+ * Note: This is useful as internal tool for other constructor functions like
3203
+ * `createLibraryFromUrl` or `createLibraryFromDirectory`
3204
+ * Consider using those functions instead of this one
3205
+ *
3206
+ * Note: The function does NOT return promise it returns the library directly which waits for the sources to be resolved
3207
+ * when error occurs in given promise or factory function, it is thrown during `listPromptbooks` or `getPromptbookByUrl` call
3208
+ *
3209
+ * Note: Consider using `createLibraryFromDirectory` or `createLibraryFromUrl`
3210
+ *
3211
+ * @param promptbookSourcesPromiseOrFactory
3212
+ * @returns PromptbookLibrary
3213
+ * @deprecated Do not use, it will became internal tool for other constructor functions
3214
+ */
3215
+ function createLibraryFromPromise(promptbookSourcesPromiseOrFactory) {
3216
+ var library;
3217
+ function forSources() {
3218
+ return __awaiter(this, void 0, void 0, function () {
3219
+ var promptbookSources;
3220
+ return __generator(this, function (_a) {
3221
+ switch (_a.label) {
3222
+ case 0:
3223
+ if (typeof promptbookSourcesPromiseOrFactory === 'function') {
3224
+ // Note: Calling factory function only once despite multiple calls to resolveSources
3225
+ promptbookSourcesPromiseOrFactory = promptbookSourcesPromiseOrFactory();
3226
+ }
3227
+ return [4 /*yield*/, promptbookSourcesPromiseOrFactory];
3228
+ case 1:
3229
+ promptbookSources = _a.sent();
3230
+ library = createLibraryFromJson.apply(void 0, __spreadArray([], __read(promptbookSources), false));
3231
+ return [2 /*return*/];
3232
+ }
3233
+ });
3234
+ });
3235
+ }
3236
+ function listPromptbooks() {
3237
+ return __awaiter(this, void 0, void 0, function () {
3238
+ return __generator(this, function (_a) {
3239
+ switch (_a.label) {
3240
+ case 0: return [4 /*yield*/, forSources()];
3241
+ case 1:
3242
+ _a.sent();
3243
+ return [2 /*return*/, /* not await */ library.listPromptbooks()];
3244
+ }
3245
+ });
3246
+ });
3247
+ }
3248
+ function getPromptbookByUrl(url) {
3249
+ return __awaiter(this, void 0, void 0, function () {
3250
+ return __generator(this, function (_a) {
3251
+ switch (_a.label) {
3252
+ case 0: return [4 /*yield*/, forSources()];
3253
+ case 1:
3254
+ _a.sent();
3255
+ return [2 /*return*/, /* not await */ library.getPromptbookByUrl(url)];
3256
+ }
3257
+ });
3258
+ });
3259
+ }
3260
+ function isResponsibleForPrompt(prompt) {
3261
+ return __awaiter(this, void 0, void 0, function () {
3262
+ return __generator(this, function (_a) {
3263
+ switch (_a.label) {
3264
+ case 0: return [4 /*yield*/, forSources()];
3265
+ case 1:
3266
+ _a.sent();
3267
+ return [2 /*return*/, /* not await */ library.isResponsibleForPrompt(prompt)];
3268
+ }
3269
+ });
3270
+ });
3271
+ }
3272
+ return {
3273
+ listPromptbooks: listPromptbooks,
3274
+ getPromptbookByUrl: getPromptbookByUrl,
3275
+ isResponsibleForPrompt: isResponsibleForPrompt,
3276
+ };
3277
+ }
3278
+
3279
+ /**
3280
+ * Constructs Promptbook from given directory
3281
+ *
3282
+ * Note: Works only in Node.js environment because it reads the file system
3283
+ *
3284
+ * @param path - path to the directory with promptbooks
3285
+ * @param options - Misc options for the library
3286
+ * @returns PromptbookLibrary
3287
+ */
3288
+ function createLibraryFromDirectory(path$1, options) {
3289
+ return __awaiter(this, void 0, void 0, function () {
3290
+ var makedLibraryFilePath, makedLibraryFileExists, _a, _b, isRecursive, _c, isVerbose, _d, isLazyLoaded, _e, isCrashOnError, library;
3291
+ var _this = this;
3292
+ return __generator(this, function (_f) {
3293
+ switch (_f.label) {
3294
+ case 0:
3295
+ if (!isRunningInNode()) {
3296
+ throw new Error('Function `createLibraryFromDirectory` can only be run in Node.js environment because it reads the file system.');
3297
+ }
3298
+ makedLibraryFilePath = path.join(path$1, "".concat(PROMPTBOOK_MAKED_BASE_FILENAME, ".json"));
3299
+ return [4 /*yield*/, promises.access(makedLibraryFilePath, promises.constants.R_OK)
3300
+ .then(function () { return true; })
3301
+ .catch(function () { return false; })];
3302
+ case 1:
3303
+ makedLibraryFileExists = _f.sent();
3304
+ if (!makedLibraryFileExists) {
3305
+ console.info(colors__default["default"].yellow("Tip: Prebuild your promptbook library (file with supposed prebuild ".concat(makedLibraryFilePath, " not found) with CLI util \"promptbook make\" to speed up the library creation.")));
3306
+ }
3307
+ else {
3308
+ colors__default["default"].green("Using your prebuild promptbook library ".concat(makedLibraryFilePath));
3309
+ // TODO: !!!!! Implement;
3310
+ }
3311
+ _a = options || {}, _b = _a.isRecursive, isRecursive = _b === void 0 ? true : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? false : _c, _d = _a.isLazyLoaded, isLazyLoaded = _d === void 0 ? false : _d, _e = _a.isCrashOnError, isCrashOnError = _e === void 0 ? true : _e;
3312
+ library = createLibraryFromPromise(function () { return __awaiter(_this, void 0, void 0, function () {
3313
+ var fileNames, promptbooks, _loop_1, fileNames_1, fileNames_1_1, fileName, e_1_1;
3314
+ var e_1, _a;
3315
+ return __generator(this, function (_b) {
3316
+ switch (_b.label) {
3317
+ case 0:
3318
+ if (isVerbose) {
3319
+ console.info("Creating promptbook library from path ".concat(path$1));
3320
+ }
3321
+ return [4 /*yield*/, listAllFiles(path$1, isRecursive)];
3322
+ case 1:
3323
+ fileNames = _b.sent();
3324
+ if (isVerbose) {
3325
+ console.info('createLibraryFromDirectory', { path: path$1, isRecursive: isRecursive, fileNames: fileNames });
3326
+ }
3327
+ promptbooks = [];
3328
+ _loop_1 = function (fileName) {
3329
+ var promptbook, promptbookString, _c, _d, error_1, wrappedErrorMessage;
3330
+ return __generator(this, function (_e) {
3331
+ switch (_e.label) {
3332
+ case 0:
3333
+ _e.trys.push([0, 7, , 8]);
3334
+ promptbook = null;
3335
+ if (!fileName.endsWith('.ptbk.md')) return [3 /*break*/, 3];
3336
+ return [4 /*yield*/, promises.readFile(fileName, 'utf8')];
3337
+ case 1:
3338
+ promptbookString = (_e.sent());
3339
+ return [4 /*yield*/, promptbookStringToJson(promptbookString)];
3340
+ case 2:
3341
+ promptbook = _e.sent();
3342
+ return [3 /*break*/, 6];
3343
+ case 3:
3344
+ if (!fileName.endsWith('.ptbk.json')) return [3 /*break*/, 5];
3345
+ if (isVerbose) {
3346
+ console.info("Loading ".concat(fileName));
3347
+ }
3348
+ _d = (_c = JSON).parse;
3349
+ return [4 /*yield*/, promises.readFile(fileName, 'utf8')];
3350
+ case 4:
3351
+ // TODO: Handle non-valid JSON files
3352
+ promptbook = _d.apply(_c, [_e.sent()]);
3353
+ return [3 /*break*/, 6];
3354
+ case 5:
3355
+ if (isVerbose) {
3356
+ console.info("Skipping file ".concat(fileName));
3357
+ }
3358
+ _e.label = 6;
3359
+ case 6:
3360
+ // ---
3361
+ if (promptbook !== null) {
3362
+ if (!promptbook.promptbookUrl) {
3363
+ if (isVerbose) {
3364
+ console.info("Not loading ".concat(fileName, " - missing URL"));
3365
+ }
3366
+ }
3367
+ else {
3368
+ if (isVerbose) {
3369
+ console.info("Loading ".concat(fileName));
3370
+ }
3371
+ if (!isCrashOnError) {
3372
+ // Note: Validate promptbook to check if it is logically correct to not crash on invalid promptbooks
3373
+ // But be handled in current try-catch block
3374
+ validatePromptbook(promptbook);
3375
+ }
3376
+ // Note: [🦄] Promptbook with same url uniqueness will be checked automatically in SimplePromptbookLibrary
3377
+ promptbooks.push(promptbook);
3378
+ }
3379
+ }
3380
+ return [3 /*break*/, 8];
3381
+ case 7:
3382
+ error_1 = _e.sent();
3383
+ if (!(error_1 instanceof Error)) {
3384
+ throw error_1;
3385
+ }
3386
+ wrappedErrorMessage = spaceTrim__default["default"](function (block) { return "\n Error during loading promptbook from file ".concat(fileName.split('\\').join('/'), ":\n\n ").concat(block(error_1.message), "\n\n "); });
3387
+ if (isCrashOnError) {
3388
+ throw new PromptbookLibraryError(wrappedErrorMessage);
3389
+ }
3390
+ console.error(wrappedErrorMessage);
3391
+ return [3 /*break*/, 8];
3392
+ case 8: return [2 /*return*/];
3393
+ }
3394
+ });
3395
+ };
3396
+ _b.label = 2;
3397
+ case 2:
3398
+ _b.trys.push([2, 7, 8, 9]);
3399
+ fileNames_1 = __values(fileNames), fileNames_1_1 = fileNames_1.next();
3400
+ _b.label = 3;
3401
+ case 3:
3402
+ if (!!fileNames_1_1.done) return [3 /*break*/, 6];
3403
+ fileName = fileNames_1_1.value;
3404
+ return [5 /*yield**/, _loop_1(fileName)];
3405
+ case 4:
3406
+ _b.sent();
3407
+ _b.label = 5;
3408
+ case 5:
3409
+ fileNames_1_1 = fileNames_1.next();
3410
+ return [3 /*break*/, 3];
3411
+ case 6: return [3 /*break*/, 9];
3412
+ case 7:
3413
+ e_1_1 = _b.sent();
3414
+ e_1 = { error: e_1_1 };
3415
+ return [3 /*break*/, 9];
3416
+ case 8:
3417
+ try {
3418
+ if (fileNames_1_1 && !fileNames_1_1.done && (_a = fileNames_1.return)) _a.call(fileNames_1);
3419
+ }
3420
+ finally { if (e_1) throw e_1.error; }
3421
+ return [7 /*endfinally*/];
3422
+ case 9: return [2 /*return*/, promptbooks];
3423
+ }
3424
+ });
3425
+ }); });
3426
+ if (!(isLazyLoaded === false)) return [3 /*break*/, 3];
3427
+ return [4 /*yield*/, library.listPromptbooks()];
3428
+ case 2:
3429
+ _f.sent();
3430
+ _f.label = 3;
3431
+ case 3: return [2 /*return*/, library];
3432
+ }
3433
+ });
3434
+ });
3435
+ }
3436
+ /**
3437
+ * Reads all files in the directory
3438
+ *
3439
+ * @param path
3440
+ * @param isRecursive
3441
+ * @returns List of all files in the directory
3442
+ * @private internal function for `createLibraryFromDirectory`
3443
+ */
3444
+ function listAllFiles(path$1, isRecursive) {
3445
+ return __awaiter(this, void 0, void 0, function () {
3446
+ var dirents, fileNames, _a, _b, dirent, subPath, _c, _d, _e, _f, e_2_1;
3447
+ var e_2, _g;
3448
+ return __generator(this, function (_h) {
3449
+ switch (_h.label) {
3450
+ case 0: return [4 /*yield*/, promises.readdir(path$1, {
3451
+ withFileTypes: true /* Note: This is not working: recursive: isRecursive */,
3452
+ })];
3453
+ case 1:
3454
+ dirents = _h.sent();
3455
+ fileNames = dirents.filter(function (dirent) { return dirent.isFile(); }).map(function (_a) {
3456
+ var name = _a.name;
3457
+ return path.join(path$1, name);
3458
+ });
3459
+ if (!isRecursive) return [3 /*break*/, 9];
3460
+ _h.label = 2;
3461
+ case 2:
3462
+ _h.trys.push([2, 7, 8, 9]);
3463
+ _a = __values(dirents.filter(function (dirent) { return dirent.isDirectory(); })), _b = _a.next();
3464
+ _h.label = 3;
3465
+ case 3:
3466
+ if (!!_b.done) return [3 /*break*/, 6];
3467
+ dirent = _b.value;
3468
+ subPath = path.join(path$1, dirent.name);
3469
+ _d = (_c = fileNames.push).apply;
3470
+ _e = [fileNames];
3471
+ _f = [[]];
3472
+ return [4 /*yield*/, listAllFiles(subPath, isRecursive)];
3473
+ case 4:
3474
+ _d.apply(_c, _e.concat([__spreadArray.apply(void 0, _f.concat([__read.apply(void 0, [(_h.sent())]), false]))]));
3475
+ _h.label = 5;
3476
+ case 5:
3477
+ _b = _a.next();
3478
+ return [3 /*break*/, 3];
3479
+ case 6: return [3 /*break*/, 9];
3480
+ case 7:
3481
+ e_2_1 = _h.sent();
3482
+ e_2 = { error: e_2_1 };
3483
+ return [3 /*break*/, 9];
3484
+ case 8:
3485
+ try {
3486
+ if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
3487
+ }
3488
+ finally { if (e_2) throw e_2.error; }
3489
+ return [7 /*endfinally*/];
3490
+ case 9: return [2 /*return*/, fileNames];
3491
+ }
3492
+ });
3493
+ });
3494
+ }
3495
+ /**
3496
+ * TODO: !!!! [🧠] Library precompilation and do not mix markdown and json promptbooks
3497
+ */
3498
+
3499
+ /**
3500
+ * Converts PromptbookLibrary to serialized JSON
3501
+ *
3502
+ * Note: Functions `libraryToJson` and `createLibraryFromJson` are complementary
3503
+ */
3504
+ function libraryToJson(library) {
3505
+ return __awaiter(this, void 0, void 0, function () {
3506
+ var promptbookUrls, promptbooks;
3507
+ return __generator(this, function (_a) {
3508
+ switch (_a.label) {
3509
+ case 0: return [4 /*yield*/, library.listPromptbooks()];
3510
+ case 1:
3511
+ promptbookUrls = _a.sent();
3512
+ return [4 /*yield*/, Promise.all(promptbookUrls.map(function (url) { return library.getPromptbookByUrl(url); }))];
3513
+ case 2:
3514
+ promptbooks = _a.sent();
3515
+ return [2 /*return*/, promptbooks];
3516
+ }
3517
+ });
3518
+ });
3519
+ }
3520
+
3521
+ /**
3522
+ * Initializes `make` command for Promptbook CLI utilities
3523
+ *
3524
+ * @private part of `promptbookCli`
3525
+ */
3526
+ function initializeMake(program) {
3527
+ var _this = this;
3528
+ var helloCommand = program.command('make');
3529
+ helloCommand.description(spaceTrim__default["default"]("\n Makes a new promptbook library in given folder\n "));
3530
+ helloCommand.argument('<path>', 'Path to promptbook directory');
3531
+ helloCommand.option('--project-name', "Name of the project for whom library is", 'Project');
3532
+ helloCommand.option('-f, --format <format>', spaceTrim__default["default"]("\n Output format of builded library \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳‍🌈] */);
3533
+ helloCommand.option('--no-validation', "Do not validate logic of promptbooks in library", true);
3534
+ helloCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
3535
+ // TODO: !!! Auto-detect AI api keys + explicit api keys as argv
3536
+ helloCommand.action(function (path$1, _a) {
3537
+ var projectName = _a.projectName, format = _a.format, validation = _a.validation;
3538
+ return __awaiter(_this, void 0, void 0, function () {
3539
+ var formats, validations, library, validations_1, validations_1_1, validation_1, _b, _c, promptbookUrl, promptbook, e_1_1, e_2_1, libraryJson, libraryJsonString, saveFile;
3540
+ var e_2, _d, e_1, _e;
3541
+ var _this = this;
3542
+ return __generator(this, function (_f) {
3543
+ switch (_f.label) {
3544
+ case 0:
3545
+ console.info('!!!', { projectName: projectName, path: path$1, format: format, validation: validation });
3546
+ formats = (format || '')
3547
+ .split(',')
3548
+ .map(function (_) { return _.trim(); })
3549
+ .filter(function (_) { return _ !== ''; });
3550
+ validations = (validation || '')
3551
+ .split(',')
3552
+ .map(function (_) { return _.trim(); })
3553
+ .filter(function (_) { return _ !== ''; });
3554
+ return [4 /*yield*/, createLibraryFromDirectory(path$1, {
3555
+ isVerbose: true,
3556
+ isRecursive: true,
3557
+ })];
3558
+ case 1:
3559
+ library = _f.sent();
3560
+ _f.label = 2;
3561
+ case 2:
3562
+ _f.trys.push([2, 14, 15, 16]);
3563
+ validations_1 = __values(validations), validations_1_1 = validations_1.next();
3564
+ _f.label = 3;
3565
+ case 3:
3566
+ if (!!validations_1_1.done) return [3 /*break*/, 13];
3567
+ validation_1 = validations_1_1.value;
3568
+ _f.label = 4;
3569
+ case 4:
3570
+ _f.trys.push([4, 10, 11, 12]);
3571
+ e_1 = void 0;
3572
+ return [4 /*yield*/, library.listPromptbooks()];
3573
+ case 5:
3574
+ _b = (__values.apply(void 0, [_f.sent()])), _c = _b.next();
3575
+ _f.label = 6;
3576
+ case 6:
3577
+ if (!!_c.done) return [3 /*break*/, 9];
3578
+ promptbookUrl = _c.value;
3579
+ return [4 /*yield*/, library.getPromptbookByUrl(promptbookUrl)];
3580
+ case 7:
3581
+ promptbook = _f.sent();
3582
+ if (validation_1 === 'logic') {
3583
+ validatePromptbook(promptbook);
3584
+ }
3585
+ _f.label = 8;
3586
+ case 8:
3587
+ _c = _b.next();
3588
+ return [3 /*break*/, 6];
3589
+ case 9: return [3 /*break*/, 12];
3590
+ case 10:
3591
+ e_1_1 = _f.sent();
3592
+ e_1 = { error: e_1_1 };
3593
+ return [3 /*break*/, 12];
3594
+ case 11:
3595
+ try {
3596
+ if (_c && !_c.done && (_e = _b.return)) _e.call(_b);
3597
+ }
3598
+ finally { if (e_1) throw e_1.error; }
3599
+ return [7 /*endfinally*/];
3600
+ case 12:
3601
+ validations_1_1 = validations_1.next();
3602
+ return [3 /*break*/, 3];
3603
+ case 13: return [3 /*break*/, 16];
3604
+ case 14:
3605
+ e_2_1 = _f.sent();
3606
+ e_2 = { error: e_2_1 };
3607
+ return [3 /*break*/, 16];
3608
+ case 15:
3609
+ try {
3610
+ if (validations_1_1 && !validations_1_1.done && (_d = validations_1.return)) _d.call(validations_1);
3611
+ }
3612
+ finally { if (e_2) throw e_2.error; }
3613
+ return [7 /*endfinally*/];
3614
+ case 16: return [4 /*yield*/, libraryToJson(library)];
3615
+ case 17:
3616
+ libraryJson = _f.sent();
3617
+ libraryJsonString = JSON.stringify(libraryJson);
3618
+ saveFile = function (extension, content) { return __awaiter(_this, void 0, void 0, function () {
3619
+ var filePath;
3620
+ return __generator(this, function (_a) {
3621
+ switch (_a.label) {
3622
+ case 0:
3623
+ filePath = path.join(path$1, "promptbook-library.".concat(extension));
3624
+ return [4 /*yield*/, promises.writeFile(filePath, content, 'utf-8')];
3625
+ case 1:
3626
+ _a.sent();
3627
+ console.info(colors__default["default"].green("Maked ".concat(filePath)));
3628
+ return [2 /*return*/];
3629
+ }
3630
+ });
3631
+ }); };
3632
+ if (!formats.includes('json')) return [3 /*break*/, 19];
3633
+ return [4 /*yield*/, saveFile('json', libraryJsonString + '\n')];
3634
+ case 18:
3635
+ _f.sent();
3636
+ _f.label = 19;
3637
+ case 19:
3638
+ if (formats.includes('javascript')) {
3639
+ // TODO: !!!!;
3640
+ // TODO: !!! DRY javascript and typescript
3641
+ formats.push('javascript');
3642
+ }
3643
+ if (!formats.includes('typescript')) return [3 /*break*/, 21];
3644
+ // TODO: !!!!!!!! Javascript json
3645
+ return [4 /*yield*/, saveFile('ts', spaceTrim__default["default"]("\n import type { PromptbookLibrary, SimplePromptbookLibrary } from '@promptbook/types';\n import type { createLibraryFromJson } from '@promptbook/core';\n\n /**\n * Promptbook library for ".concat(projectName, "\n *\n * @private internal cache for `getPromptbookLibrary`\n */\n let promptbookLibrary: null | SimplePromptbookLibrary = null;\n\n\n /**\n * Get promptbook library for ").concat(projectName, "\n *\n * @returns {PromptbookLibrary} Library of promptbooks for ").concat(projectName, "\n * @generated by `@promptbook/cli`\n */\n export function getPromptbookLibrary(): PromptbookLibrary{\n if(promptbookLibrary===null){\n promptbookLibrary = createLibraryFromJson(").concat(libraryJsonString.substring(1, libraryJsonString.length - 2), ");\n }\n\n return promptbookLibrary;\n }\n ") + '\n'))];
3646
+ case 20:
3647
+ // TODO: !!!!!!!! Javascript json
3648
+ _f.sent();
3649
+ _f.label = 21;
3650
+ case 21:
3651
+ process.exit(0);
3652
+ return [2 /*return*/];
3653
+ }
3654
+ });
3655
+ });
3656
+ });
3657
+ }
3658
+
3659
+ /**
3660
+ * Add or modify an auto-generated section in a markdown file
3661
+ *
3662
+ * @private within the library
3663
+ */
3664
+ function addAutoGeneratedSection(content, options) {
3665
+ var sectionName = options.sectionName, sectionContent = options.sectionContent;
3666
+ var warningLine = "<!-- \u26A0\uFE0F WARNING: This section was auto-generated -->";
3667
+ var sectionRegex = new RegExp("<!--".concat(sectionName, "-->([\\s\\S]*?)<!--/").concat(sectionName, "-->"), 'g');
3668
+ var sectionMatch = content.match(sectionRegex);
3669
+ if (sectionMatch) {
3670
+ return content.replace(sectionRegex, spaceTrim.spaceTrim(function (block) { return "\n <!--".concat(sectionName, "-->\n ").concat(block(warningLine), "\n ").concat(block(sectionContent), "\n <!--/").concat(sectionName, "-->\n "); }));
3671
+ }
3672
+ var placeForSection = removeContentComments(content).match(/^##.*$/im);
3673
+ if (!placeForSection) {
3674
+ throw new Error("No place where to put the section <!--".concat(sectionName, "-->"));
3675
+ }
3676
+ var _a = __read(placeForSection, 1), heading = _a[0];
3677
+ return content.replace(heading, "<!--".concat(sectionName, "-->\n").concat(warningLine, "\n").concat(sectionContent, "\n<!--/").concat(sectionName, "-->\n\n").concat(heading));
3678
+ }
3679
+
3233
3680
  /* tslint:disable */
3234
3681
  function normalizeTo_camelCase(sentence, __firstLetterCapital) {
3235
3682
  var e_1, _a;