@promptbook/cli 0.74.0-5 → 0.74.0-7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -14
- package/esm/index.es.js +639 -176
- package/esm/index.es.js.map +1 -1
- package/package.json +4 -3
- package/umd/index.umd.js +643 -180
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import colors from 'colors';
|
|
1
2
|
import commander from 'commander';
|
|
2
3
|
import spaceTrim$1, { spaceTrim } from 'spacetrim';
|
|
3
|
-
import colors from 'colors';
|
|
4
4
|
import { forTime } from 'waitasecond';
|
|
5
5
|
import { stat, access, constants, readFile, writeFile, readdir, mkdir, unlink, rm, rmdir, rename } from 'fs/promises';
|
|
6
6
|
import { join, basename, dirname } from 'path';
|
|
@@ -16,6 +16,7 @@ import * as dotenv from 'dotenv';
|
|
|
16
16
|
import sha256 from 'crypto-js/sha256';
|
|
17
17
|
import glob from 'glob-promise';
|
|
18
18
|
import prompts from 'prompts';
|
|
19
|
+
import moment from 'moment';
|
|
19
20
|
import { io } from 'socket.io-client';
|
|
20
21
|
import Anthropic from '@anthropic-ai/sdk';
|
|
21
22
|
import { OpenAIClient, AzureKeyCredential } from '@azure/openai';
|
|
@@ -36,7 +37,7 @@ var BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
36
37
|
*
|
|
37
38
|
* @see https://github.com/webgptorg/promptbook
|
|
38
39
|
*/
|
|
39
|
-
var PROMPTBOOK_ENGINE_VERSION = '0.74.0-
|
|
40
|
+
var PROMPTBOOK_ENGINE_VERSION = '0.74.0-6';
|
|
40
41
|
/**
|
|
41
42
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
42
43
|
*/
|
|
@@ -160,31 +161,6 @@ function __spreadArray(to, from, pack) {
|
|
|
160
161
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
/**
|
|
164
|
-
* This error type indicates that you try to use a feature that is not available in the current environment
|
|
165
|
-
*
|
|
166
|
-
* @public exported from `@promptbook/core`
|
|
167
|
-
*/
|
|
168
|
-
var EnvironmentMismatchError = /** @class */ (function (_super) {
|
|
169
|
-
__extends(EnvironmentMismatchError, _super);
|
|
170
|
-
function EnvironmentMismatchError(message) {
|
|
171
|
-
var _this = _super.call(this, message) || this;
|
|
172
|
-
_this.name = 'EnvironmentMismatchError';
|
|
173
|
-
Object.setPrototypeOf(_this, EnvironmentMismatchError.prototype);
|
|
174
|
-
return _this;
|
|
175
|
-
}
|
|
176
|
-
return EnvironmentMismatchError;
|
|
177
|
-
}(Error));
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Detects if the code is running in a Node.js environment
|
|
181
|
-
*
|
|
182
|
-
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
183
|
-
*
|
|
184
|
-
* @public exported from `@promptbook/utils`
|
|
185
|
-
*/
|
|
186
|
-
var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
|
|
187
|
-
|
|
188
164
|
/**
|
|
189
165
|
* Returns the same value that is passed as argument.
|
|
190
166
|
* No side effects.
|
|
@@ -526,6 +502,15 @@ var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
|
526
502
|
* @private within the repository
|
|
527
503
|
*/
|
|
528
504
|
var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
|
|
505
|
+
/**
|
|
506
|
+
* The thresholds for the relative time in the `moment` NPM package.
|
|
507
|
+
*
|
|
508
|
+
* @see https://momentjscom.readthedocs.io/en/latest/moment/07-customization/13-relative-time-threshold/
|
|
509
|
+
* @private within the repository - too low-level in comparison with other constants
|
|
510
|
+
*/
|
|
511
|
+
var MOMENT_ARG_THRESHOLDS = {
|
|
512
|
+
ss: 3, // <- least number of seconds to be counted in seconds, minus 1. Must be set after setting the `s` unit or without setting the `s` unit.
|
|
513
|
+
};
|
|
529
514
|
/**
|
|
530
515
|
* @@@
|
|
531
516
|
*
|
|
@@ -569,6 +554,31 @@ true);
|
|
|
569
554
|
* TODO: [🧠][🧜♂️] Maybe join remoteUrl and path into single value
|
|
570
555
|
*/
|
|
571
556
|
|
|
557
|
+
/**
|
|
558
|
+
* This error type indicates that you try to use a feature that is not available in the current environment
|
|
559
|
+
*
|
|
560
|
+
* @public exported from `@promptbook/core`
|
|
561
|
+
*/
|
|
562
|
+
var EnvironmentMismatchError = /** @class */ (function (_super) {
|
|
563
|
+
__extends(EnvironmentMismatchError, _super);
|
|
564
|
+
function EnvironmentMismatchError(message) {
|
|
565
|
+
var _this = _super.call(this, message) || this;
|
|
566
|
+
_this.name = 'EnvironmentMismatchError';
|
|
567
|
+
Object.setPrototypeOf(_this, EnvironmentMismatchError.prototype);
|
|
568
|
+
return _this;
|
|
569
|
+
}
|
|
570
|
+
return EnvironmentMismatchError;
|
|
571
|
+
}(Error));
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Detects if the code is running in a Node.js environment
|
|
575
|
+
*
|
|
576
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
577
|
+
*
|
|
578
|
+
* @public exported from `@promptbook/utils`
|
|
579
|
+
*/
|
|
580
|
+
var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
|
|
581
|
+
|
|
572
582
|
/**
|
|
573
583
|
* Initializes `about` command for Promptbook CLI utilities
|
|
574
584
|
*
|
|
@@ -7943,11 +7953,18 @@ function pipelineStringToJsonSync(pipelineString) {
|
|
|
7943
7953
|
}
|
|
7944
7954
|
// =============================================================
|
|
7945
7955
|
// Note: 1️⃣ Parsing of the markdown into object
|
|
7956
|
+
if (pipelineString.startsWith('#!')) {
|
|
7957
|
+
var _c = __read(pipelineString.split('\n')), shebangLine_1 = _c[0], restLines = _c.slice(1);
|
|
7958
|
+
if (!(shebangLine_1 || '').includes('ptbk')) {
|
|
7959
|
+
throw new ParseError(spaceTrim(function (block) { return "\n It seems that you try to parse a book file which has non-standard shebang line for book files:\n Shebang line must contain 'ptbk'\n\n You have:\n ".concat(block(shebangLine_1 || '(empty line)'), "\n\n It should look like this:\n #!/usr/bin/env ptbk\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
|
|
7960
|
+
}
|
|
7961
|
+
pipelineString = restLines.join('\n');
|
|
7962
|
+
}
|
|
7946
7963
|
pipelineString = removeContentComments(pipelineString);
|
|
7947
7964
|
pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
|
|
7948
7965
|
pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
|
|
7949
7966
|
pipelineString = pipelineString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
|
|
7950
|
-
var
|
|
7967
|
+
var _d = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _d[0], pipelineSections = _d.slice(1); /* <- Note: [🥞] */
|
|
7951
7968
|
if (pipelineHead === undefined) {
|
|
7952
7969
|
throw new UnexpectedError(spaceTrim(function (block) { return "\n Pipeline head is not defined\n\n ".concat(block(getPipelineIdentification()), "\n\n This should never happen, because the pipeline already flattened\n "); }));
|
|
7953
7970
|
}
|
|
@@ -8037,10 +8054,10 @@ function pipelineStringToJsonSync(pipelineString) {
|
|
|
8037
8054
|
finally { if (e_1) throw e_1.error; }
|
|
8038
8055
|
}
|
|
8039
8056
|
var _loop_2 = function (section) {
|
|
8040
|
-
var e_3,
|
|
8057
|
+
var e_3, _e;
|
|
8041
8058
|
// TODO: Parse template description (the content out of the codeblock and lists)
|
|
8042
8059
|
var listItems_2 = extractAllListItemsFromMarkdown(section.content);
|
|
8043
|
-
var
|
|
8060
|
+
var _f = extractOneBlockFromMarkdown(section.content), language = _f.language, content = _f.content;
|
|
8044
8061
|
// TODO: [🎾][1] DRY description
|
|
8045
8062
|
var description_1 = section.content;
|
|
8046
8063
|
// Note: Remove codeblocks - TODO: [🎾]
|
|
@@ -8105,14 +8122,14 @@ function pipelineStringToJsonSync(pipelineString) {
|
|
|
8105
8122
|
try {
|
|
8106
8123
|
// TODO [♓️] List commands and before apply order them to achieve order-agnostic commands
|
|
8107
8124
|
for (var commands_1 = (e_3 = void 0, __values(commands)), commands_1_1 = commands_1.next(); !commands_1_1.done; commands_1_1 = commands_1.next()) {
|
|
8108
|
-
var
|
|
8125
|
+
var _g = commands_1_1.value, listItem = _g.listItem, command = _g.command;
|
|
8109
8126
|
_loop_3(listItem, command);
|
|
8110
8127
|
}
|
|
8111
8128
|
}
|
|
8112
8129
|
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
8113
8130
|
finally {
|
|
8114
8131
|
try {
|
|
8115
|
-
if (commands_1_1 && !commands_1_1.done && (
|
|
8132
|
+
if (commands_1_1 && !commands_1_1.done && (_e = commands_1.return)) _e.call(commands_1);
|
|
8116
8133
|
}
|
|
8117
8134
|
finally { if (e_3) throw e_3.error; }
|
|
8118
8135
|
}
|
|
@@ -10209,13 +10226,13 @@ function initializeMakeCommand(program) {
|
|
|
10209
10226
|
makeCommand.option('-f, --format <format>', spaceTrim$1("\n Output format of builded collection \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳🌈] */);
|
|
10210
10227
|
makeCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
|
|
10211
10228
|
makeCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
|
|
10212
|
-
makeCommand.option('--reload', "Call LLM models even if same prompt with result is in the cache", false);
|
|
10213
|
-
makeCommand.option('--verbose', "Is output verbose", false);
|
|
10229
|
+
makeCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
|
|
10230
|
+
makeCommand.option('-v, --verbose', "Is output verbose", false);
|
|
10214
10231
|
makeCommand.option('-o, --out-file <path>', spaceTrim$1("\n Where to save the builded collection\n\n Note: If you keep it \"".concat(DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME, "\" it will be saved in the root of the promptbook directory\n If you set it to a path, it will be saved in that path\n BUT you can use only one format and set correct extension\n ")), DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME);
|
|
10215
10232
|
makeCommand.action(function (path, _a) {
|
|
10216
10233
|
var projectName = _a.projectName, format = _a.format, validation = _a.validation, isCacheReloaded = _a.reload, isVerbose = _a.verbose, outFile = _a.outFile;
|
|
10217
10234
|
return __awaiter(_this, void 0, void 0, function () {
|
|
10218
|
-
var formats, validations,
|
|
10235
|
+
var formats, validations, prepareAndScrapeOptions, fs, llm, executables, tools, collection, validations_1, validations_1_1, validation_1, _b, _c, pipelineUrl, pipeline, e_1_1, e_2_1, collectionJson, collectionJsonString, collectionJsonItems, saveFile;
|
|
10219
10236
|
var _d, e_2, _e, e_1, _f;
|
|
10220
10237
|
var _this = this;
|
|
10221
10238
|
return __generator(this, function (_g) {
|
|
@@ -10233,20 +10250,20 @@ function initializeMakeCommand(program) {
|
|
|
10233
10250
|
console.error(colors.red("You can only use one format if you specify --out-file"));
|
|
10234
10251
|
return [2 /*return*/, process.exit(1)];
|
|
10235
10252
|
}
|
|
10236
|
-
|
|
10253
|
+
prepareAndScrapeOptions = {
|
|
10237
10254
|
isVerbose: isVerbose,
|
|
10238
10255
|
isCacheReloaded: isCacheReloaded,
|
|
10239
10256
|
};
|
|
10240
|
-
fs = $provideFilesystemForNode(
|
|
10241
|
-
llm = $provideLlmToolsForCli(
|
|
10242
|
-
return [4 /*yield*/, $provideExecutablesForNode(
|
|
10257
|
+
fs = $provideFilesystemForNode(prepareAndScrapeOptions);
|
|
10258
|
+
llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
|
|
10259
|
+
return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
|
|
10243
10260
|
case 1:
|
|
10244
10261
|
executables = _g.sent();
|
|
10245
10262
|
_d = {
|
|
10246
10263
|
llm: llm,
|
|
10247
10264
|
fs: fs
|
|
10248
10265
|
};
|
|
10249
|
-
return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables },
|
|
10266
|
+
return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
|
|
10250
10267
|
case 2:
|
|
10251
10268
|
tools = (_d.scrapers = _g.sent(),
|
|
10252
10269
|
_d.script = [
|
|
@@ -10620,6 +10637,333 @@ function initializePrettifyCommand(program) {
|
|
|
10620
10637
|
* TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
|
|
10621
10638
|
*/
|
|
10622
10639
|
|
|
10640
|
+
/**
|
|
10641
|
+
* Pretty print an embedding vector for logging
|
|
10642
|
+
*
|
|
10643
|
+
* @public exported from `@promptbook/core`
|
|
10644
|
+
*/
|
|
10645
|
+
function embeddingVectorToString(embeddingVector) {
|
|
10646
|
+
var vectorLength = Math.pow(embeddingVector.reduce(function (acc, val) { return acc + Math.pow(val, 2); }, 0), 0.5);
|
|
10647
|
+
return "[EmbeddingVector; ".concat(embeddingVector.length, " dimensions; length: ").concat(vectorLength.toFixed(2), "; ").concat(embeddingVector.slice(0, 3).join(', '), "...]");
|
|
10648
|
+
}
|
|
10649
|
+
|
|
10650
|
+
/**
|
|
10651
|
+
* Format either small or big number
|
|
10652
|
+
*
|
|
10653
|
+
* @private within the repository
|
|
10654
|
+
*/
|
|
10655
|
+
function formatNumber(value) {
|
|
10656
|
+
if (value === 0) {
|
|
10657
|
+
return '0';
|
|
10658
|
+
}
|
|
10659
|
+
for (var exponent = 0; exponent < 15; exponent++) {
|
|
10660
|
+
var factor = Math.pow(10, exponent);
|
|
10661
|
+
var valueRounded = Math.round(value * factor) / factor;
|
|
10662
|
+
if (Math.abs(value - valueRounded) / value <
|
|
10663
|
+
0.001 /* <- TODO: Pass as option, pass to executionReportJsonToString as option */) {
|
|
10664
|
+
return valueRounded.toFixed(exponent);
|
|
10665
|
+
}
|
|
10666
|
+
}
|
|
10667
|
+
return value.toString();
|
|
10668
|
+
}
|
|
10669
|
+
|
|
10670
|
+
/**
|
|
10671
|
+
* Create a markdown table from a 2D array of strings
|
|
10672
|
+
*
|
|
10673
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
10674
|
+
*/
|
|
10675
|
+
function createMarkdownTable(table) {
|
|
10676
|
+
var columnWidths = table.reduce(function (widths, row) {
|
|
10677
|
+
row.forEach(function (subformat, columnIndex) {
|
|
10678
|
+
var cellLength = subformat.length;
|
|
10679
|
+
if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
|
|
10680
|
+
widths[columnIndex] = cellLength;
|
|
10681
|
+
}
|
|
10682
|
+
});
|
|
10683
|
+
return widths;
|
|
10684
|
+
}, []);
|
|
10685
|
+
var header = "| ".concat(table[0]
|
|
10686
|
+
.map(function (subformat, columnIndex) { return subformat.padEnd(columnWidths[columnIndex]); })
|
|
10687
|
+
.join(' | '), " |");
|
|
10688
|
+
var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
|
|
10689
|
+
var rows = table.slice(1).map(function (row) {
|
|
10690
|
+
var paddedRow = row.map(function (subformat, columnIndex) {
|
|
10691
|
+
return subformat.padEnd(columnWidths[columnIndex]);
|
|
10692
|
+
});
|
|
10693
|
+
return "| ".concat(paddedRow.join(' | '), " |");
|
|
10694
|
+
});
|
|
10695
|
+
return __spreadArray([header, separator], __read(rows), false).join('\n');
|
|
10696
|
+
}
|
|
10697
|
+
/**
|
|
10698
|
+
* TODO: [🏛] This can be part of markdown builder
|
|
10699
|
+
*/
|
|
10700
|
+
|
|
10701
|
+
/**
|
|
10702
|
+
* Function createMarkdownChart will draw a chart in markdown from ⬛+🟦 tiles
|
|
10703
|
+
*
|
|
10704
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
10705
|
+
*/
|
|
10706
|
+
function createMarkdownChart(options) {
|
|
10707
|
+
var e_1, _a;
|
|
10708
|
+
var nameHeader = options.nameHeader, valueHeader = options.valueHeader, items = options.items, width = options.width, unitName = options.unitName;
|
|
10709
|
+
var from = Math.min.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.from; })), false));
|
|
10710
|
+
var to = Math.max.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.to; })), false));
|
|
10711
|
+
var scale = width / (to - from);
|
|
10712
|
+
var table = [[nameHeader, valueHeader]];
|
|
10713
|
+
try {
|
|
10714
|
+
for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
|
|
10715
|
+
var item = items_1_1.value;
|
|
10716
|
+
var before = Math.round((item.from - from) * scale);
|
|
10717
|
+
var during = Math.round((item.to - item.from) * scale);
|
|
10718
|
+
var after = width - before - during;
|
|
10719
|
+
table.push([removeEmojis(item.title).trim(), '░'.repeat(before) + '█'.repeat(during) + '░'.repeat(after)]);
|
|
10720
|
+
}
|
|
10721
|
+
}
|
|
10722
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
10723
|
+
finally {
|
|
10724
|
+
try {
|
|
10725
|
+
if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
|
|
10726
|
+
}
|
|
10727
|
+
finally { if (e_1) throw e_1.error; }
|
|
10728
|
+
}
|
|
10729
|
+
var legend = "_Note: Each \u2588 represents ".concat(formatNumber(1 / scale), " ").concat(unitName, ", width of ").concat(valueHeader.toLowerCase(), " is ").concat(formatNumber(to - from), " ").concat(unitName, " = ").concat(width, " squares_");
|
|
10730
|
+
return createMarkdownTable(table) + '\n\n' + legend;
|
|
10731
|
+
}
|
|
10732
|
+
/**
|
|
10733
|
+
* TODO: Maybe use Mermain Gant Diagrams
|
|
10734
|
+
* @see https://jojozhuang.github.io/tutorial/mermaid-cheat-sheet/
|
|
10735
|
+
*/
|
|
10736
|
+
|
|
10737
|
+
/**
|
|
10738
|
+
* Function escapeMarkdownBlock will escape markdown block if needed
|
|
10739
|
+
* It is useful when you want have block in block
|
|
10740
|
+
*
|
|
10741
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
10742
|
+
*/
|
|
10743
|
+
function escapeMarkdownBlock(value) {
|
|
10744
|
+
return value.replace(/```/g, '\\`\\`\\`');
|
|
10745
|
+
}
|
|
10746
|
+
/**
|
|
10747
|
+
* TODO: [🏛] This can be part of markdown builder
|
|
10748
|
+
*/
|
|
10749
|
+
|
|
10750
|
+
/**
|
|
10751
|
+
* Default options for generating an execution report string
|
|
10752
|
+
*
|
|
10753
|
+
* @public exported from `@promptbook/core`
|
|
10754
|
+
*/
|
|
10755
|
+
var ExecutionReportStringOptionsDefaults = {
|
|
10756
|
+
taxRate: 0,
|
|
10757
|
+
chartsWidth: 36,
|
|
10758
|
+
};
|
|
10759
|
+
|
|
10760
|
+
/**
|
|
10761
|
+
* Count the duration of working time
|
|
10762
|
+
*
|
|
10763
|
+
* @private within the repository
|
|
10764
|
+
*/
|
|
10765
|
+
function countWorkingDuration(items) {
|
|
10766
|
+
var e_1, _a;
|
|
10767
|
+
var steps = Array.from(new Set(items.flatMap(function (item) { return [item.from, item.to]; })));
|
|
10768
|
+
steps.sort(function (a, b) { return a - b; });
|
|
10769
|
+
var intervals = steps.map(function (step, index) { return [step, steps[index + 1] || 0]; }).slice(0, -1);
|
|
10770
|
+
var duration = 0;
|
|
10771
|
+
var _loop_1 = function (interval) {
|
|
10772
|
+
var _b = __read(interval, 2), from = _b[0], to = _b[1];
|
|
10773
|
+
if (items.some(function (item) { return item.from < to && item.to > from; })) {
|
|
10774
|
+
duration += to - from;
|
|
10775
|
+
}
|
|
10776
|
+
};
|
|
10777
|
+
try {
|
|
10778
|
+
for (var intervals_1 = __values(intervals), intervals_1_1 = intervals_1.next(); !intervals_1_1.done; intervals_1_1 = intervals_1.next()) {
|
|
10779
|
+
var interval = intervals_1_1.value;
|
|
10780
|
+
_loop_1(interval);
|
|
10781
|
+
}
|
|
10782
|
+
}
|
|
10783
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
10784
|
+
finally {
|
|
10785
|
+
try {
|
|
10786
|
+
if (intervals_1_1 && !intervals_1_1.done && (_a = intervals_1.return)) _a.call(intervals_1);
|
|
10787
|
+
}
|
|
10788
|
+
finally { if (e_1) throw e_1.error; }
|
|
10789
|
+
}
|
|
10790
|
+
return duration;
|
|
10791
|
+
}
|
|
10792
|
+
|
|
10793
|
+
/**
|
|
10794
|
+
* Converts execution report from JSON to string format
|
|
10795
|
+
*
|
|
10796
|
+
* @public exported from `@promptbook/core`
|
|
10797
|
+
*/
|
|
10798
|
+
function executionReportJsonToString(executionReportJson, options) {
|
|
10799
|
+
var e_1, _a;
|
|
10800
|
+
var _b, _c, _d, _e, _f, _g;
|
|
10801
|
+
var _h = __assign(__assign({}, ExecutionReportStringOptionsDefaults), (options || {})), taxRate = _h.taxRate, chartsWidth = _h.chartsWidth;
|
|
10802
|
+
var executionReportString = spaceTrim(function (block) { return "\n # ".concat(executionReportJson.title || 'Execution report', "\n\n ").concat(block(executionReportJson.description || ''), "\n "); });
|
|
10803
|
+
var headerList = [];
|
|
10804
|
+
if (executionReportJson.pipelineUrl) {
|
|
10805
|
+
headerList.push("PIPELINE URL ".concat(executionReportJson.pipelineUrl));
|
|
10806
|
+
}
|
|
10807
|
+
headerList.push("PROMPTBOOK VERSION ".concat(executionReportJson.promptbookUsedVersion) +
|
|
10808
|
+
(!executionReportJson.promptbookRequestedVersion
|
|
10809
|
+
? ''
|
|
10810
|
+
: " *(requested ".concat(executionReportJson.promptbookRequestedVersion, ")*")));
|
|
10811
|
+
if (executionReportJson.promptExecutions.length !== 0) {
|
|
10812
|
+
// TODO: What if startedAt OR/AND completedAt is not defined?
|
|
10813
|
+
var startedAt = moment(Math.min.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
|
|
10814
|
+
.filter(function (promptExecution) { var _a, _b; return (_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.start; })
|
|
10815
|
+
.map(function (promptExecution) { return moment(promptExecution.result.timing.start).valueOf(); })), false)));
|
|
10816
|
+
var completedAt = moment(Math.max.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
|
|
10817
|
+
.filter(function (promptExecution) { var _a, _b; return (_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.complete; })
|
|
10818
|
+
.map(function (promptExecution) { return moment(promptExecution.result.timing.complete).valueOf(); })), false)));
|
|
10819
|
+
var timingItems = executionReportJson.promptExecutions.map(function (promptExecution) {
|
|
10820
|
+
var _a, _b, _c, _d;
|
|
10821
|
+
return ({
|
|
10822
|
+
title: promptExecution.prompt.title,
|
|
10823
|
+
from: moment((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.start).valueOf() / 1000,
|
|
10824
|
+
to: moment((_d = (_c = promptExecution.result) === null || _c === void 0 ? void 0 : _c.timing) === null || _d === void 0 ? void 0 : _d.complete).valueOf() / 1000,
|
|
10825
|
+
});
|
|
10826
|
+
});
|
|
10827
|
+
var costItems = executionReportJson.promptExecutions
|
|
10828
|
+
.filter(function (promptExecution) { var _a, _b; return typeof ((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price) === 'number'; })
|
|
10829
|
+
.map(function (promptExecution) {
|
|
10830
|
+
var _a, _b;
|
|
10831
|
+
return ({
|
|
10832
|
+
title: promptExecution.prompt.title,
|
|
10833
|
+
from: 0,
|
|
10834
|
+
to: (((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price.value) || 0) /* <- TODO: look at uncertain numbers */ *
|
|
10835
|
+
(1 + taxRate),
|
|
10836
|
+
});
|
|
10837
|
+
});
|
|
10838
|
+
var duration = moment.duration(completedAt.diff(startedAt));
|
|
10839
|
+
var llmDuration = moment.duration(countWorkingDuration(timingItems) * 1000);
|
|
10840
|
+
var executionsWithKnownCost = executionReportJson.promptExecutions.filter(function (promptExecution) { var _a, _b; return (((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price) || 'UNKNOWN') !== 'UNKNOWN'; });
|
|
10841
|
+
var cost = executionsWithKnownCost.reduce(function (cost, promptExecution) {
|
|
10842
|
+
return cost + (promptExecution.result.usage.price.value /* <- Look at uncertain number */ || 0);
|
|
10843
|
+
}, 0);
|
|
10844
|
+
headerList.push("STARTED AT ".concat(moment(startedAt).format("YYYY-MM-DD HH:mm:ss")));
|
|
10845
|
+
headerList.push("COMPLETED AT ".concat(moment(completedAt).format("YYYY-MM-DD HH:mm:ss")));
|
|
10846
|
+
headerList.push("TOTAL DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
|
|
10847
|
+
headerList.push("TOTAL LLM DURATION ".concat(llmDuration.humanize(MOMENT_ARG_THRESHOLDS)));
|
|
10848
|
+
headerList.push("TOTAL COST $".concat(formatNumber(cost * (1 + taxRate))) +
|
|
10849
|
+
(executionsWithKnownCost.length === executionReportJson.promptExecutions.length
|
|
10850
|
+
? ''
|
|
10851
|
+
: " *(Some cost is unknown)*") +
|
|
10852
|
+
(taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
|
|
10853
|
+
executionReportString += '\n\n' + headerList.map(function (header) { return "- ".concat(header); }).join('\n');
|
|
10854
|
+
executionReportString +=
|
|
10855
|
+
'\n\n' +
|
|
10856
|
+
'## 🗃 Index' +
|
|
10857
|
+
'\n\n' +
|
|
10858
|
+
executionReportJson.promptExecutions
|
|
10859
|
+
.map(function (promptExecution) {
|
|
10860
|
+
// TODO: Make some better system to convert hedings to links
|
|
10861
|
+
var hash = normalizeToKebabCase(promptExecution.prompt.title);
|
|
10862
|
+
if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
|
|
10863
|
+
hash = '-' + hash;
|
|
10864
|
+
}
|
|
10865
|
+
// TODO: Make working hash link for the template in md + pdf
|
|
10866
|
+
return "- [".concat(promptExecution.prompt.title, "](#").concat(hash, ")");
|
|
10867
|
+
})
|
|
10868
|
+
.join('\n');
|
|
10869
|
+
executionReportString +=
|
|
10870
|
+
'\n\n' +
|
|
10871
|
+
'## ⌚ Time chart' +
|
|
10872
|
+
'\n\n' +
|
|
10873
|
+
createMarkdownChart({
|
|
10874
|
+
nameHeader: 'Template',
|
|
10875
|
+
valueHeader: 'Timeline',
|
|
10876
|
+
items: timingItems,
|
|
10877
|
+
width: chartsWidth,
|
|
10878
|
+
unitName: 'seconds',
|
|
10879
|
+
});
|
|
10880
|
+
executionReportString +=
|
|
10881
|
+
'\n\n' +
|
|
10882
|
+
'## 💸 Cost chart' +
|
|
10883
|
+
'\n\n' +
|
|
10884
|
+
createMarkdownChart({
|
|
10885
|
+
nameHeader: 'Template',
|
|
10886
|
+
valueHeader: 'Cost',
|
|
10887
|
+
items: costItems,
|
|
10888
|
+
width: chartsWidth,
|
|
10889
|
+
unitName: 'USD',
|
|
10890
|
+
});
|
|
10891
|
+
}
|
|
10892
|
+
else {
|
|
10893
|
+
headerList.push("TOTAL COST $0 *(Nothing executed)*");
|
|
10894
|
+
}
|
|
10895
|
+
var _loop_1 = function (promptExecution) {
|
|
10896
|
+
executionReportString += '\n\n\n\n' + "## ".concat(promptExecution.prompt.title);
|
|
10897
|
+
var templateList = [];
|
|
10898
|
+
// TODO: What if startedAt OR/AND completedAt is not defined?
|
|
10899
|
+
var startedAt = moment((_c = (_b = promptExecution.result) === null || _b === void 0 ? void 0 : _b.timing) === null || _c === void 0 ? void 0 : _c.start);
|
|
10900
|
+
var completedAt = moment((_e = (_d = promptExecution.result) === null || _d === void 0 ? void 0 : _d.timing) === null || _e === void 0 ? void 0 : _e.complete);
|
|
10901
|
+
var duration = moment.duration(completedAt.diff(startedAt));
|
|
10902
|
+
// Not need here:
|
|
10903
|
+
// > templateList.push(`STARTED AT ${moment(startedAt).calendar()}`);
|
|
10904
|
+
templateList.push("DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
|
|
10905
|
+
if (typeof ((_g = (_f = promptExecution.result) === null || _f === void 0 ? void 0 : _f.usage) === null || _g === void 0 ? void 0 : _g.price) === 'number') {
|
|
10906
|
+
templateList.push("COST $".concat(formatNumber(promptExecution.result.usage.price * (1 + taxRate))) +
|
|
10907
|
+
(taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
|
|
10908
|
+
}
|
|
10909
|
+
else {
|
|
10910
|
+
templateList.push("COST UNKNOWN");
|
|
10911
|
+
}
|
|
10912
|
+
executionReportString += '\n\n' + templateList.map(function (header) { return "- ".concat(header); }).join('\n');
|
|
10913
|
+
/*
|
|
10914
|
+
- MODEL VARIANT ${promptExecution.prompt.modelRequirements.modelVariant}
|
|
10915
|
+
- MODEL NAME \`${promptExecution.result?.model}\` (requested \`${
|
|
10916
|
+
promptExecution.prompt.modelRequirements.modelName
|
|
10917
|
+
|
|
10918
|
+
*/
|
|
10919
|
+
if (just(true)) {
|
|
10920
|
+
executionReportString +=
|
|
10921
|
+
'\n\n\n\n' +
|
|
10922
|
+
spaceTrim(function (block) {
|
|
10923
|
+
var _a;
|
|
10924
|
+
return "\n\n ### Prompt\n\n ```\n ".concat(block(escapeMarkdownBlock(((_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.rawPromptContent) || promptExecution.prompt.content)), "\n ```\n\n ");
|
|
10925
|
+
});
|
|
10926
|
+
}
|
|
10927
|
+
if (promptExecution.result && promptExecution.result.content) {
|
|
10928
|
+
executionReportString += '\n\n\n\n' + '### Result' + '\n\n';
|
|
10929
|
+
if (promptExecution.result === undefined) {
|
|
10930
|
+
executionReportString += '*No result*';
|
|
10931
|
+
}
|
|
10932
|
+
else if (typeof promptExecution.result.content === 'string') {
|
|
10933
|
+
executionReportString += spaceTrim(function (block) { return "\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.result.content)), "\n ```\n "); });
|
|
10934
|
+
}
|
|
10935
|
+
else {
|
|
10936
|
+
executionReportString += embeddingVectorToString(promptExecution.result.content);
|
|
10937
|
+
}
|
|
10938
|
+
}
|
|
10939
|
+
if (promptExecution.error && promptExecution.error.message) {
|
|
10940
|
+
executionReportString +=
|
|
10941
|
+
'\n\n\n\n' +
|
|
10942
|
+
spaceTrim(function (block) { return "\n\n ### Error\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.error.message)), "\n ```\n\n "); });
|
|
10943
|
+
}
|
|
10944
|
+
};
|
|
10945
|
+
try {
|
|
10946
|
+
for (var _j = __values(executionReportJson.promptExecutions), _k = _j.next(); !_k.done; _k = _j.next()) {
|
|
10947
|
+
var promptExecution = _k.value;
|
|
10948
|
+
_loop_1(promptExecution);
|
|
10949
|
+
}
|
|
10950
|
+
}
|
|
10951
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
10952
|
+
finally {
|
|
10953
|
+
try {
|
|
10954
|
+
if (_k && !_k.done && (_a = _j.return)) _a.call(_j);
|
|
10955
|
+
}
|
|
10956
|
+
finally { if (e_1) throw e_1.error; }
|
|
10957
|
+
}
|
|
10958
|
+
executionReportString = prettifyMarkdown(executionReportString);
|
|
10959
|
+
return executionReportString;
|
|
10960
|
+
}
|
|
10961
|
+
/**
|
|
10962
|
+
* TODO: Add mermaid chart for every report
|
|
10963
|
+
* TODO: [🧠] Allow to filter out some parts of the report by options
|
|
10964
|
+
* TODO: [🧠] Should be in generated file GENERATOR_WARNING
|
|
10965
|
+
*/
|
|
10966
|
+
|
|
10623
10967
|
/**
|
|
10624
10968
|
* Initializes `run` command for Promptbook CLI utilities
|
|
10625
10969
|
*
|
|
@@ -10627,146 +10971,263 @@ function initializePrettifyCommand(program) {
|
|
|
10627
10971
|
*/
|
|
10628
10972
|
function initializeRunCommand(program) {
|
|
10629
10973
|
var _this = this;
|
|
10630
|
-
var runCommand = program.command('run');
|
|
10974
|
+
var runCommand = program.command('run', { isDefault: true });
|
|
10631
10975
|
runCommand.description(spaceTrim$1("\n Runs a pipeline\n "));
|
|
10632
10976
|
// TODO: [🧅] DRY command arguments
|
|
10633
10977
|
runCommand.argument('<path>',
|
|
10634
10978
|
// <- Note: [🧟♂️] This is NOT promptbook collection directory BUT direct path to .ptbk.md file
|
|
10635
|
-
'Path to
|
|
10636
|
-
runCommand.option('--reload', "Call LLM models even if same prompt with result is in the cache", false);
|
|
10637
|
-
runCommand.option('--verbose', "Is output verbose", false);
|
|
10638
|
-
runCommand.
|
|
10639
|
-
|
|
10640
|
-
|
|
10641
|
-
|
|
10642
|
-
|
|
10643
|
-
|
|
10644
|
-
|
|
10645
|
-
|
|
10646
|
-
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10979
|
+
'Path to book file');
|
|
10980
|
+
runCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
|
|
10981
|
+
runCommand.option('-v, --verbose', "Is output verbose", false);
|
|
10982
|
+
runCommand.option('--no-interactive', "Input is not interactive", false);
|
|
10983
|
+
runCommand.option('-s, --save-report <path>', "Save report to file");
|
|
10984
|
+
// TODO: !!!!!! Implement non-interactive mode - allow to pass input parameters as JSON
|
|
10985
|
+
// TODO: !!!!!! JSON output
|
|
10986
|
+
runCommand.action(function (filePathRaw, options) { return __awaiter(_this, void 0, void 0, function () {
|
|
10987
|
+
var isCacheReloaded, isVerbose, saveReport, prepareAndScrapeOptions, fs, filePath, filePathCandidates, filePathCandidates_1, filePathCandidates_1_1, filePathCandidate, e_1_1, llm, executables, tools, pipelineString, pipeline, error_1, pipelineExecutor, questions, response, inputParameters, result, isSuccessful, errors, warnings, outputParameters, executionReport, executionReportString, _a, _b, error, _c, _d, warning, _e, _f, key, value, separator;
|
|
10988
|
+
var e_1, _g, _h, e_2, _j, e_3, _k, e_4, _l;
|
|
10989
|
+
return __generator(this, function (_m) {
|
|
10990
|
+
switch (_m.label) {
|
|
10991
|
+
case 0:
|
|
10992
|
+
isCacheReloaded = options.reload, options.interactive, isVerbose = options.verbose, saveReport = options.saveReport;
|
|
10993
|
+
if (saveReport && !saveReport.endsWith('.json') && !saveReport.endsWith('.md')) {
|
|
10994
|
+
console.error(colors.red("Report file must be .json or .md"));
|
|
10995
|
+
return [2 /*return*/, process.exit(1)];
|
|
10996
|
+
}
|
|
10997
|
+
prepareAndScrapeOptions = {
|
|
10998
|
+
isVerbose: isVerbose,
|
|
10999
|
+
isCacheReloaded: isCacheReloaded,
|
|
11000
|
+
};
|
|
11001
|
+
if (isVerbose) {
|
|
11002
|
+
console.info(colors.gray('--- Preparing tools ---'));
|
|
11003
|
+
}
|
|
11004
|
+
fs = $provideFilesystemForNode(prepareAndScrapeOptions);
|
|
11005
|
+
filePath = null;
|
|
11006
|
+
filePathCandidates = [
|
|
11007
|
+
filePathRaw,
|
|
11008
|
+
"".concat(filePathRaw, ".md"),
|
|
11009
|
+
"".concat(filePathRaw, ".book.md"),
|
|
11010
|
+
"".concat(filePathRaw, ".ptbk.md"),
|
|
11011
|
+
];
|
|
11012
|
+
_m.label = 1;
|
|
11013
|
+
case 1:
|
|
11014
|
+
_m.trys.push([1, 6, 7, 8]);
|
|
11015
|
+
filePathCandidates_1 = __values(filePathCandidates), filePathCandidates_1_1 = filePathCandidates_1.next();
|
|
11016
|
+
_m.label = 2;
|
|
11017
|
+
case 2:
|
|
11018
|
+
if (!!filePathCandidates_1_1.done) return [3 /*break*/, 5];
|
|
11019
|
+
filePathCandidate = filePathCandidates_1_1.value;
|
|
11020
|
+
return [4 /*yield*/, isFileExisting(filePathCandidate, fs)
|
|
11021
|
+
// <- TODO: Also test that among the candidates the file is book not just any file
|
|
11022
|
+
];
|
|
11023
|
+
case 3:
|
|
11024
|
+
if (_m.sent()
|
|
11025
|
+
// <- TODO: Also test that among the candidates the file is book not just any file
|
|
11026
|
+
) {
|
|
11027
|
+
filePath = filePathCandidate;
|
|
11028
|
+
return [3 /*break*/, 5];
|
|
11029
|
+
}
|
|
11030
|
+
_m.label = 4;
|
|
11031
|
+
case 4:
|
|
11032
|
+
filePathCandidates_1_1 = filePathCandidates_1.next();
|
|
11033
|
+
return [3 /*break*/, 2];
|
|
11034
|
+
case 5: return [3 /*break*/, 8];
|
|
11035
|
+
case 6:
|
|
11036
|
+
e_1_1 = _m.sent();
|
|
11037
|
+
e_1 = { error: e_1_1 };
|
|
11038
|
+
return [3 /*break*/, 8];
|
|
11039
|
+
case 7:
|
|
11040
|
+
try {
|
|
11041
|
+
if (filePathCandidates_1_1 && !filePathCandidates_1_1.done && (_g = filePathCandidates_1.return)) _g.call(filePathCandidates_1);
|
|
11042
|
+
}
|
|
11043
|
+
finally { if (e_1) throw e_1.error; }
|
|
11044
|
+
return [7 /*endfinally*/];
|
|
11045
|
+
case 8:
|
|
11046
|
+
if (filePath === null) {
|
|
11047
|
+
console.error(colors.red("File \"".concat(filePathRaw, "\" does not exist")));
|
|
11048
|
+
return [2 /*return*/, process.exit(1)];
|
|
11049
|
+
}
|
|
11050
|
+
try {
|
|
11051
|
+
llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
|
|
11052
|
+
}
|
|
11053
|
+
catch (error) {
|
|
11054
|
+
if (!(error instanceof Error)) {
|
|
11055
|
+
throw error;
|
|
10653
11056
|
}
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
11057
|
+
if (!error.message.includes('No LLM tools')) {
|
|
11058
|
+
throw error;
|
|
11059
|
+
}
|
|
11060
|
+
console.error(colors.red(spaceTrim$1("\n You need to configure LLM tools first\n\n 1) Create .env file\n 2) Add OPENAI_API_KEY=...\n 3) *(and/or)* Add ANTHROPIC_CLAUDE_API_KEY=...\n ")));
|
|
11061
|
+
return [2 /*return*/, process.exit(1)];
|
|
11062
|
+
}
|
|
11063
|
+
return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
|
|
11064
|
+
case 9:
|
|
11065
|
+
executables = _m.sent();
|
|
11066
|
+
_h = {
|
|
11067
|
+
llm: llm,
|
|
11068
|
+
fs: fs
|
|
11069
|
+
};
|
|
11070
|
+
return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
|
|
11071
|
+
case 10:
|
|
11072
|
+
tools = (_h.scrapers = _m.sent(),
|
|
11073
|
+
_h.script = [
|
|
11074
|
+
/*new JavascriptExecutionTools(options)*/
|
|
11075
|
+
],
|
|
11076
|
+
_h);
|
|
11077
|
+
if (isVerbose) {
|
|
11078
|
+
console.info(colors.gray('--- Reading file ---'));
|
|
11079
|
+
}
|
|
11080
|
+
return [4 /*yield*/, readFile(filePath, 'utf-8')];
|
|
11081
|
+
case 11:
|
|
11082
|
+
pipelineString = (_m.sent());
|
|
11083
|
+
if (isVerbose) {
|
|
11084
|
+
console.info(colors.gray('--- Preparing pipeline ---'));
|
|
11085
|
+
}
|
|
11086
|
+
_m.label = 12;
|
|
11087
|
+
case 12:
|
|
11088
|
+
_m.trys.push([12, 14, , 15]);
|
|
11089
|
+
return [4 /*yield*/, pipelineStringToJson(pipelineString, tools)];
|
|
11090
|
+
case 13:
|
|
11091
|
+
pipeline = _m.sent();
|
|
11092
|
+
return [3 /*break*/, 15];
|
|
11093
|
+
case 14:
|
|
11094
|
+
error_1 = _m.sent();
|
|
11095
|
+
if (!(error_1 instanceof ParseError)) {
|
|
11096
|
+
throw error_1;
|
|
11097
|
+
}
|
|
11098
|
+
console.error(colors.red(spaceTrim$1(function (block) { return "\n ".concat(block(error_1.message), "\n\n in ").concat(filePath, "\n "); })));
|
|
11099
|
+
return [2 /*return*/, process.exit(1)];
|
|
11100
|
+
case 15:
|
|
11101
|
+
if (isVerbose) {
|
|
11102
|
+
console.info(colors.gray('--- Validating pipeline ---'));
|
|
11103
|
+
}
|
|
11104
|
+
// TODO: !!!!!! Same try-catch for LogicError
|
|
11105
|
+
validatePipeline(pipeline);
|
|
11106
|
+
if (isVerbose) {
|
|
11107
|
+
console.info(colors.gray('--- Creating executor ---'));
|
|
11108
|
+
}
|
|
11109
|
+
pipelineExecutor = createPipelineExecutor({
|
|
11110
|
+
pipeline: pipeline,
|
|
11111
|
+
tools: tools,
|
|
11112
|
+
isNotPreparedWarningSupressed: true,
|
|
11113
|
+
maxExecutionAttempts: 3,
|
|
11114
|
+
// <- TODO: !!!!!! Why "LLM execution failed undefinedx"
|
|
11115
|
+
maxParallelCount: 1, // <- TODO: !!!!!! Pass
|
|
11116
|
+
});
|
|
11117
|
+
if (isVerbose) {
|
|
11118
|
+
console.info(colors.gray('--- Getting input parameters ---'));
|
|
11119
|
+
}
|
|
11120
|
+
questions = pipeline.parameters
|
|
11121
|
+
.filter(function (_a) {
|
|
11122
|
+
var isInput = _a.isInput;
|
|
11123
|
+
return isInput;
|
|
11124
|
+
})
|
|
11125
|
+
.map(function (_a) {
|
|
11126
|
+
var name = _a.name, exampleValues = _a.exampleValues;
|
|
11127
|
+
var message = name;
|
|
11128
|
+
var initial = '';
|
|
11129
|
+
if (exampleValues && exampleValues.length > 0) {
|
|
11130
|
+
var exampleValuesFiltered = exampleValues.filter(function (exampleValue) { return countLines(exampleValue) <= 1 && countCharacters(exampleValue) <= 30; });
|
|
11131
|
+
if (exampleValuesFiltered.length !== 0) {
|
|
11132
|
+
message += " (e.g. ".concat(exampleValuesFiltered.join(', '), ")");
|
|
10660
11133
|
}
|
|
10661
|
-
|
|
10662
|
-
return [2 /*return*/, process.exit(1)];
|
|
11134
|
+
initial = exampleValues[0] || '';
|
|
10663
11135
|
}
|
|
10664
|
-
return
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
11136
|
+
return {
|
|
11137
|
+
type: 'text',
|
|
11138
|
+
name: name,
|
|
11139
|
+
message: message,
|
|
11140
|
+
initial: initial,
|
|
11141
|
+
// TODO: Maybe use> validate: value => value < 18 ? `Forbidden` : true
|
|
10670
11142
|
};
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
|
|
10692
|
-
|
|
10693
|
-
|
|
10694
|
-
|
|
10695
|
-
|
|
10696
|
-
|
|
10697
|
-
|
|
10698
|
-
|
|
10699
|
-
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
|
|
10707
|
-
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
maxExecutionAttempts: 3,
|
|
10719
|
-
// <- TODO: !!!!!! Why "LLM execution failed undefinedx"
|
|
10720
|
-
maxParallelCount: 1, // <- TODO: !!!!!! Pass
|
|
10721
|
-
});
|
|
10722
|
-
return [4 /*yield*/, pipelineExecutor(inputParameters, function (taskProgress) {
|
|
10723
|
-
if (isVerbose) {
|
|
10724
|
-
// TODO: !!!!!!! Pretty print taskProgress
|
|
10725
|
-
console.log(taskProgress);
|
|
10726
|
-
}
|
|
10727
|
-
})];
|
|
10728
|
-
case 8:
|
|
10729
|
-
result = _j.sent();
|
|
10730
|
-
isSuccessful = result.isSuccessful, errors = result.errors, outputParameters = result.outputParameters, executionReport = result.executionReport;
|
|
10731
|
-
if (isVerbose) {
|
|
10732
|
-
// TODO: !!!!!!! Pretty print
|
|
10733
|
-
console.log({ isSuccessful: isSuccessful, errors: errors, /*!!! warnings,*/ outputParameters: outputParameters, executionReport: executionReport });
|
|
10734
|
-
console.log(outputParameters);
|
|
11143
|
+
});
|
|
11144
|
+
return [4 /*yield*/, prompts(questions)];
|
|
11145
|
+
case 16:
|
|
11146
|
+
response = _m.sent();
|
|
11147
|
+
inputParameters = response;
|
|
11148
|
+
if (isVerbose) {
|
|
11149
|
+
console.info(colors.gray('--- Executing ---'));
|
|
11150
|
+
}
|
|
11151
|
+
return [4 /*yield*/, pipelineExecutor(inputParameters, function (taskProgress) {
|
|
11152
|
+
if (isVerbose) {
|
|
11153
|
+
console.info(colors.gray('--- Progress ---'));
|
|
11154
|
+
console.info(taskProgress);
|
|
11155
|
+
}
|
|
11156
|
+
})];
|
|
11157
|
+
case 17:
|
|
11158
|
+
result = _m.sent();
|
|
11159
|
+
isSuccessful = result.isSuccessful, errors = result.errors, warnings = result.warnings, outputParameters = result.outputParameters, executionReport = result.executionReport;
|
|
11160
|
+
if (isVerbose) {
|
|
11161
|
+
console.info(colors.gray('--- Detailed Result ---'));
|
|
11162
|
+
console.info({ isSuccessful: isSuccessful, errors: errors, warnings: warnings, outputParameters: outputParameters, executionReport: executionReport });
|
|
11163
|
+
}
|
|
11164
|
+
if (!(saveReport && saveReport.endsWith('.json'))) return [3 /*break*/, 19];
|
|
11165
|
+
return [4 /*yield*/, writeFile(saveReport, JSON.stringify(executionReport, null, 4) + '\n', 'utf-8')];
|
|
11166
|
+
case 18:
|
|
11167
|
+
_m.sent();
|
|
11168
|
+
return [3 /*break*/, 21];
|
|
11169
|
+
case 19:
|
|
11170
|
+
if (!(saveReport && saveReport.endsWith('.md'))) return [3 /*break*/, 21];
|
|
11171
|
+
executionReportString = executionReportJsonToString(executionReport);
|
|
11172
|
+
return [4 /*yield*/, writeFile(saveReport, executionReportString, 'utf-8')];
|
|
11173
|
+
case 20:
|
|
11174
|
+
_m.sent();
|
|
11175
|
+
_m.label = 21;
|
|
11176
|
+
case 21:
|
|
11177
|
+
if (saveReport && isVerbose) {
|
|
11178
|
+
console.info(colors.green("Report saved to ".concat(saveReport)));
|
|
11179
|
+
}
|
|
11180
|
+
if (isVerbose) {
|
|
11181
|
+
console.info(colors.gray('--- Usage ---'));
|
|
11182
|
+
console.info(colors.cyan(usageToHuman(result.usage)));
|
|
11183
|
+
}
|
|
11184
|
+
console.info(colors.gray('--- Result ---'));
|
|
11185
|
+
try {
|
|
11186
|
+
// TODO: [🧠] Should be errors or warnings shown first
|
|
11187
|
+
for (_a = __values(errors || []), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
11188
|
+
error = _b.value;
|
|
11189
|
+
console.error(colors.red(colors.bold(error.name) + ': ' + error.message));
|
|
10735
11190
|
}
|
|
10736
|
-
|
|
11191
|
+
}
|
|
11192
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
11193
|
+
finally {
|
|
10737
11194
|
try {
|
|
10738
|
-
|
|
10739
|
-
error = _c.value;
|
|
10740
|
-
console.error(colors.red(colors.bold(error.name) + ': ' + error.message));
|
|
10741
|
-
}
|
|
11195
|
+
if (_b && !_b.done && (_j = _a.return)) _j.call(_a);
|
|
10742
11196
|
}
|
|
10743
|
-
|
|
10744
|
-
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
11197
|
+
finally { if (e_2) throw e_2.error; }
|
|
11198
|
+
}
|
|
11199
|
+
try {
|
|
11200
|
+
for (_c = __values(warnings || []), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
11201
|
+
warning = _d.value;
|
|
11202
|
+
console.error(colors.red(colors.bold(warning.name) + ': ' + warning.message));
|
|
10749
11203
|
}
|
|
11204
|
+
}
|
|
11205
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
11206
|
+
finally {
|
|
10750
11207
|
try {
|
|
10751
|
-
|
|
10752
|
-
key = _e.value;
|
|
10753
|
-
value = outputParameters[key] || colors.grey(colors.italic('(nothing)'));
|
|
10754
|
-
separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
|
|
10755
|
-
console.info(colors.green(colors.bold(key) + separator + value));
|
|
10756
|
-
}
|
|
11208
|
+
if (_d && !_d.done && (_k = _c.return)) _k.call(_c);
|
|
10757
11209
|
}
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
11210
|
+
finally { if (e_3) throw e_3.error; }
|
|
11211
|
+
}
|
|
11212
|
+
try {
|
|
11213
|
+
for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
11214
|
+
key = _f.value;
|
|
11215
|
+
value = outputParameters[key] || colors.grey(colors.italic('(nothing)'));
|
|
11216
|
+
separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
|
|
11217
|
+
console.info(colors.green(colors.bold(key) + separator + value));
|
|
10764
11218
|
}
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
11219
|
+
}
|
|
11220
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
11221
|
+
finally {
|
|
11222
|
+
try {
|
|
11223
|
+
if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
|
|
11224
|
+
}
|
|
11225
|
+
finally { if (e_4) throw e_4.error; }
|
|
11226
|
+
}
|
|
11227
|
+
return [2 /*return*/, process.exit(0)];
|
|
11228
|
+
}
|
|
10768
11229
|
});
|
|
10769
|
-
});
|
|
11230
|
+
}); });
|
|
10770
11231
|
}
|
|
10771
11232
|
/**
|
|
10772
11233
|
* TODO: !!!!!! Catch and wrap all errors from CLI
|
|
@@ -10789,30 +11250,30 @@ function initializeTestCommand(program) {
|
|
|
10789
11250
|
// <- TODO: [🧟♂️] Unite path to promptbook collection argument
|
|
10790
11251
|
'Pipelines to test as glob pattern');
|
|
10791
11252
|
testCommand.option('-i, --ignore <glob>', "Ignore as glob pattern");
|
|
10792
|
-
testCommand.option('--reload', "Call LLM models even if same prompt with result is in the cache ", false);
|
|
11253
|
+
testCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache ", false);
|
|
10793
11254
|
testCommand.option('-v, --verbose', "Is output verbose", false);
|
|
10794
11255
|
testCommand.action(function (filesGlob, _a) {
|
|
10795
11256
|
var ignore = _a.ignore, isCacheReloaded = _a.reload, isVerbose = _a.verbose;
|
|
10796
11257
|
return __awaiter(_this, void 0, void 0, function () {
|
|
10797
|
-
var
|
|
11258
|
+
var prepareAndScrapeOptions, fs, llm, executables, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, error_1, e_1_1;
|
|
10798
11259
|
var _d, e_1, _e;
|
|
10799
11260
|
return __generator(this, function (_f) {
|
|
10800
11261
|
switch (_f.label) {
|
|
10801
11262
|
case 0:
|
|
10802
|
-
|
|
11263
|
+
prepareAndScrapeOptions = {
|
|
10803
11264
|
isVerbose: isVerbose,
|
|
10804
11265
|
isCacheReloaded: isCacheReloaded,
|
|
10805
11266
|
};
|
|
10806
|
-
fs = $provideFilesystemForNode(
|
|
10807
|
-
llm = $provideLlmToolsForCli(
|
|
10808
|
-
return [4 /*yield*/, $provideExecutablesForNode(
|
|
11267
|
+
fs = $provideFilesystemForNode(prepareAndScrapeOptions);
|
|
11268
|
+
llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
|
|
11269
|
+
return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
|
|
10809
11270
|
case 1:
|
|
10810
11271
|
executables = _f.sent();
|
|
10811
11272
|
_d = {
|
|
10812
11273
|
llm: llm,
|
|
10813
11274
|
fs: fs
|
|
10814
11275
|
};
|
|
10815
|
-
return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables },
|
|
11276
|
+
return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
|
|
10816
11277
|
case 2:
|
|
10817
11278
|
tools = (_d.scrapers = _f.sent(),
|
|
10818
11279
|
_d.script = [
|
|
@@ -10906,16 +11367,21 @@ function initializeTestCommand(program) {
|
|
|
10906
11367
|
*/
|
|
10907
11368
|
function promptbookCli() {
|
|
10908
11369
|
return __awaiter(this, void 0, void 0, function () {
|
|
10909
|
-
var program;
|
|
11370
|
+
var isVerbose, program;
|
|
10910
11371
|
return __generator(this, function (_a) {
|
|
10911
11372
|
if (!$isRunningInNode()) {
|
|
10912
11373
|
throw new EnvironmentMismatchError(spaceTrim("\n Function promptbookCli is initiator of CLI script and should be run in Node.js environment.\n\n - In browser use function exported from `@promptbook/utils` or `@promptbook/core` directly, for example `prettifyPipelineString`.\n\n "));
|
|
10913
11374
|
}
|
|
11375
|
+
isVerbose = process.argv.some(function (arg) { return arg === '--verbose' || arg === '-v'; });
|
|
11376
|
+
// <- TODO: Can be this be done with commander before the commander commands are initialized?
|
|
11377
|
+
if (isVerbose) {
|
|
11378
|
+
console.info(colors.gray("Promptbook CLI version ".concat(PROMPTBOOK_ENGINE_VERSION, " in ").concat(__filename.split('\\').join('/'))));
|
|
11379
|
+
}
|
|
10914
11380
|
program = new commander.Command();
|
|
10915
11381
|
program.name('promptbook');
|
|
10916
11382
|
program.alias('ptbk');
|
|
10917
11383
|
program.version(PROMPTBOOK_ENGINE_VERSION);
|
|
10918
|
-
program.description(
|
|
11384
|
+
program.description(CLAIM);
|
|
10919
11385
|
initializeAboutCommand(program);
|
|
10920
11386
|
initializeRunCommand(program);
|
|
10921
11387
|
initializeHelloCommand(program);
|
|
@@ -13244,12 +13710,9 @@ function $execCommandNormalizeOptions(options) {
|
|
|
13244
13710
|
})
|
|
13245
13711
|
.filter(function (arg) { return arg !== ''; });
|
|
13246
13712
|
if (_.length > 1) {
|
|
13247
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13248
13713
|
_a = __read(_), command = _a[0], args = _a.slice(1);
|
|
13249
13714
|
}
|
|
13250
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13251
13715
|
if (options.args) {
|
|
13252
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13253
13716
|
args = __spreadArray(__spreadArray([], __read(args), false), __read(options.args), false);
|
|
13254
13717
|
}
|
|
13255
13718
|
var humanReadableCommand = !['npx', 'npm'].includes(command) ? command : args[0];
|