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