@promptbook/cli 0.89.0-9 → 0.89.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -11
- package/esm/index.es.js +925 -616
- package/esm/index.es.js.map +1 -1
- package/esm/typings/servers.d.ts +40 -0
- package/esm/typings/src/_packages/core.index.d.ts +8 -4
- package/esm/typings/src/_packages/types.index.d.ts +18 -0
- package/esm/typings/src/_packages/utils.index.d.ts +4 -0
- package/esm/typings/src/cli/cli-commands/login.d.ts +0 -1
- package/esm/typings/src/cli/common/$provideLlmToolsForCli.d.ts +16 -3
- package/esm/typings/src/cli/test/ptbk.d.ts +1 -1
- package/esm/typings/src/commands/EXPECT/expectCommandParser.d.ts +2 -0
- package/esm/typings/src/config.d.ts +10 -19
- package/esm/typings/src/errors/0-index.d.ts +7 -4
- package/esm/typings/src/errors/PipelineExecutionError.d.ts +1 -1
- package/esm/typings/src/errors/WrappedError.d.ts +10 -0
- package/esm/typings/src/errors/assertsError.d.ts +11 -0
- package/esm/typings/src/execution/PromptbookFetch.d.ts +1 -1
- package/esm/typings/src/formats/csv/utils/isValidCsvString.d.ts +9 -0
- package/esm/typings/src/formats/csv/utils/isValidCsvString.test.d.ts +1 -0
- package/esm/typings/src/formats/json/utils/isValidJsonString.d.ts +3 -0
- package/esm/typings/src/formats/xml/utils/isValidXmlString.d.ts +9 -0
- package/esm/typings/src/formats/xml/utils/isValidXmlString.test.d.ts +1 -0
- package/esm/typings/src/llm-providers/_common/register/{$provideEnvFilepath.d.ts → $provideEnvFilename.d.ts} +2 -2
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsConfigurationFromEnv.d.ts +1 -1
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +1 -1
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForWizzardOrCli.d.ts +11 -2
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsFromEnv.d.ts +1 -1
- package/esm/typings/src/remote-server/openapi-types.d.ts +284 -0
- package/esm/typings/src/remote-server/openapi.d.ts +187 -0
- package/esm/typings/src/remote-server/socket-types/_subtypes/Identification.d.ts +7 -1
- package/esm/typings/src/remote-server/socket-types/_subtypes/identificationToPromptbookToken.d.ts +11 -0
- package/esm/typings/src/remote-server/socket-types/_subtypes/promptbookTokenToIdentification.d.ts +10 -0
- package/esm/typings/src/remote-server/startRemoteServer.d.ts +1 -2
- package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +15 -9
- package/esm/typings/src/storage/env-storage/$EnvStorage.d.ts +40 -0
- package/esm/typings/src/types/typeAliases.d.ts +26 -0
- package/package.json +15 -11
- package/umd/index.umd.js +929 -620
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/cli/test/ptbk2.d.ts +0 -5
package/umd/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('waitasecond'), require('prompts'), require('path'), require('fs/promises'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('crypto'), require('socket.io-client'), require('rxjs'), require('
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'waitasecond', 'prompts', 'path', 'fs/promises', 'crypto-js/enc-hex', 'crypto-js/sha256', 'crypto', 'socket.io-client', 'rxjs', '
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global.spaceTrim, global.waitasecond, global.prompts, global.path, global.promises, global.hexEncoder, global.sha256, global.crypto, global.socket_ioClient, global.rxjs, global.
|
|
5
|
-
})(this, (function (exports, colors, commander, spaceTrim, waitasecond, prompts, path, promises, hexEncoder, sha256, crypto, socket_ioClient, rxjs,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('waitasecond'), require('prompts'), require('path'), require('fs/promises'), require('dotenv'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('crypto'), require('socket.io-client'), require('rxjs'), require('child_process'), require('jszip'), require('prettier'), require('prettier/parser-html'), require('papaparse'), require('crypto-js'), require('mime-types'), require('glob-promise'), require('moment'), require('express'), require('http'), require('socket.io'), require('express-openapi-validator'), require('swagger-ui-express'), require('@anthropic-ai/sdk'), require('@azure/openai'), require('openai'), require('@mozilla/readability'), require('jsdom'), require('showdown')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'waitasecond', 'prompts', 'path', 'fs/promises', 'dotenv', 'crypto-js/enc-hex', 'crypto-js/sha256', 'crypto', 'socket.io-client', 'rxjs', 'child_process', 'jszip', 'prettier', 'prettier/parser-html', 'papaparse', 'crypto-js', 'mime-types', 'glob-promise', 'moment', 'express', 'http', 'socket.io', 'express-openapi-validator', 'swagger-ui-express', '@anthropic-ai/sdk', '@azure/openai', 'openai', '@mozilla/readability', 'jsdom', 'showdown'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global.spaceTrim, global.waitasecond, global.prompts, global.path, global.promises, global.dotenv, global.hexEncoder, global.sha256, global.crypto, global.socket_ioClient, global.rxjs, global.child_process, global.JSZip, global.prettier, global.parserHtml, global.papaparse, global.cryptoJs, global.mimeTypes, global.glob, global.moment, global.express, global.http, global.socket_io, global.OpenApiValidator, global.swaggerUi, global.Anthropic, global.openai, global.OpenAI, global.readability, global.jsdom, global.showdown));
|
|
5
|
+
})(this, (function (exports, colors, commander, spaceTrim, waitasecond, prompts, path, promises, dotenv, hexEncoder, sha256, crypto, socket_ioClient, rxjs, child_process, JSZip, prettier, parserHtml, papaparse, cryptoJs, mimeTypes, glob, moment, express, http, socket_io, OpenApiValidator, swaggerUi, Anthropic, openai, OpenAI, readability, jsdom, showdown) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
@@ -28,16 +28,16 @@
|
|
|
28
28
|
var commander__default = /*#__PURE__*/_interopDefaultLegacy(commander);
|
|
29
29
|
var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
|
|
30
30
|
var prompts__default = /*#__PURE__*/_interopDefaultLegacy(prompts);
|
|
31
|
+
var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
|
|
31
32
|
var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
|
|
32
33
|
var sha256__default = /*#__PURE__*/_interopDefaultLegacy(sha256);
|
|
33
|
-
var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
|
|
34
34
|
var JSZip__default = /*#__PURE__*/_interopDefaultLegacy(JSZip);
|
|
35
35
|
var parserHtml__default = /*#__PURE__*/_interopDefaultLegacy(parserHtml);
|
|
36
36
|
var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
|
|
37
37
|
var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
|
|
38
38
|
var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
|
|
39
39
|
var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
|
|
40
|
-
var
|
|
40
|
+
var OpenApiValidator__namespace = /*#__PURE__*/_interopNamespace(OpenApiValidator);
|
|
41
41
|
var swaggerUi__default = /*#__PURE__*/_interopDefaultLegacy(swaggerUi);
|
|
42
42
|
var Anthropic__default = /*#__PURE__*/_interopDefaultLegacy(Anthropic);
|
|
43
43
|
var OpenAI__default = /*#__PURE__*/_interopDefaultLegacy(OpenAI);
|
|
@@ -56,12 +56,43 @@
|
|
|
56
56
|
* @generated
|
|
57
57
|
* @see https://github.com/webgptorg/promptbook
|
|
58
58
|
*/
|
|
59
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.89.0
|
|
59
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.89.0';
|
|
60
60
|
/**
|
|
61
61
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
62
62
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
63
63
|
*/
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Available remote servers for the Promptbook
|
|
67
|
+
*
|
|
68
|
+
* @public exported from `@promptbook/core`
|
|
69
|
+
*/
|
|
70
|
+
const REMOTE_SERVER_URLS = [
|
|
71
|
+
{
|
|
72
|
+
title: 'Promptbook',
|
|
73
|
+
description: `Servers of Promptbook.studio`,
|
|
74
|
+
owner: 'AI Web, LLC <legal@ptbk.io> (https://www.ptbk.io/)',
|
|
75
|
+
isAnonymousModeAllowed: true,
|
|
76
|
+
urls: [
|
|
77
|
+
'https://promptbook.s5.ptbk.io/',
|
|
78
|
+
// Note: Servers 1-4 are not running
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
/*
|
|
82
|
+
Note: Working on older version of Promptbook and not supported anymore
|
|
83
|
+
{
|
|
84
|
+
title: 'Pavol Promptbook Server',
|
|
85
|
+
description: `Personal server of Pavol Hejný with simple testing server, DO NOT USE IT FOR PRODUCTION`,
|
|
86
|
+
owner: 'Pavol Hejný <pavol@ptbk.io> (https://www.pavolhejny.com/)',
|
|
87
|
+
isAnonymousModeAllowed: true,
|
|
88
|
+
urls: ['https://api.pavolhejny.com/promptbook'],
|
|
89
|
+
},
|
|
90
|
+
*/
|
|
91
|
+
];
|
|
92
|
+
/**
|
|
93
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
94
|
+
*/
|
|
95
|
+
|
|
65
96
|
/**
|
|
66
97
|
* Returns the same value that is passed as argument.
|
|
67
98
|
* No side effects.
|
|
@@ -116,6 +147,7 @@
|
|
|
116
147
|
* @public exported from `@promptbook/core`
|
|
117
148
|
*/
|
|
118
149
|
const CLAIM = `It's time for a paradigm shift. The future of software in plain English, French or Latin`;
|
|
150
|
+
// <- TODO: [🐊] Pick the best claim
|
|
119
151
|
/**
|
|
120
152
|
* When the title is not provided, the default title is used
|
|
121
153
|
*
|
|
@@ -146,6 +178,12 @@
|
|
|
146
178
|
* @private within the repository
|
|
147
179
|
*/
|
|
148
180
|
const GENERATOR_WARNING_BY_PROMPTBOOK_CLI = `⚠️ WARNING: This code has been generated by \`@promptbook/cli\` so that any manual changes will be overwritten`;
|
|
181
|
+
/**
|
|
182
|
+
* Warning message for the automatically generated sections of `.env` files
|
|
183
|
+
*
|
|
184
|
+
* @private within the repository
|
|
185
|
+
*/
|
|
186
|
+
const GENERATOR_WARNING_IN_ENV = `Note: Added by Promptbook`;
|
|
149
187
|
// <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
|
|
150
188
|
/**
|
|
151
189
|
* The maximum number of iterations for a loops
|
|
@@ -166,6 +204,7 @@
|
|
|
166
204
|
infinity: '(infinity; ∞)',
|
|
167
205
|
negativeInfinity: '(negative infinity; -∞)',
|
|
168
206
|
unserializable: '(unserializable value)',
|
|
207
|
+
circular: '(circular JSON)',
|
|
169
208
|
};
|
|
170
209
|
/**
|
|
171
210
|
* Small number limit
|
|
@@ -225,7 +264,7 @@
|
|
|
225
264
|
*/
|
|
226
265
|
const DEFAULT_BOOKS_DIRNAME = './books';
|
|
227
266
|
// <- TODO: [🕝] Make also `BOOKS_DIRNAME_ALTERNATIVES`
|
|
228
|
-
// TODO:
|
|
267
|
+
// TODO: Just `.promptbook` in config, hardcode subfolders like `download-cache` or `execution-cache`
|
|
229
268
|
/**
|
|
230
269
|
* Where to store the temporary downloads
|
|
231
270
|
*
|
|
@@ -281,11 +320,11 @@
|
|
|
281
320
|
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.
|
|
282
321
|
};
|
|
283
322
|
/**
|
|
284
|
-
*
|
|
323
|
+
* Default remote server URL for the Promptbook
|
|
285
324
|
*
|
|
286
325
|
* @public exported from `@promptbook/core`
|
|
287
326
|
*/
|
|
288
|
-
const DEFAULT_REMOTE_SERVER_URL =
|
|
327
|
+
const DEFAULT_REMOTE_SERVER_URL = REMOTE_SERVER_URLS[0].urls[0];
|
|
289
328
|
// <- TODO: [🧜♂️]
|
|
290
329
|
/**
|
|
291
330
|
* @@@
|
|
@@ -419,6 +458,122 @@
|
|
|
419
458
|
* TODO: [🎺]
|
|
420
459
|
*/
|
|
421
460
|
|
|
461
|
+
/**
|
|
462
|
+
* Make error report URL for the given error
|
|
463
|
+
*
|
|
464
|
+
* @private private within the repository
|
|
465
|
+
*/
|
|
466
|
+
function getErrorReportUrl(error) {
|
|
467
|
+
const report = {
|
|
468
|
+
title: `🐜 Error report from ${NAME}`,
|
|
469
|
+
body: spaceTrim__default["default"]((block) => `
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
\`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
|
|
473
|
+
|
|
474
|
+
\`\`\`
|
|
475
|
+
${block(error.message || '(no error message)')}
|
|
476
|
+
\`\`\`
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
## More info:
|
|
480
|
+
|
|
481
|
+
- **Promptbook engine version:** ${PROMPTBOOK_ENGINE_VERSION}
|
|
482
|
+
- **Book language version:** ${BOOK_LANGUAGE_VERSION}
|
|
483
|
+
- **Time:** ${new Date().toISOString()}
|
|
484
|
+
|
|
485
|
+
<details>
|
|
486
|
+
<summary>Stack trace:</summary>
|
|
487
|
+
|
|
488
|
+
## Stack trace:
|
|
489
|
+
|
|
490
|
+
\`\`\`stacktrace
|
|
491
|
+
${block(error.stack || '(empty)')}
|
|
492
|
+
\`\`\`
|
|
493
|
+
</details>
|
|
494
|
+
|
|
495
|
+
`),
|
|
496
|
+
};
|
|
497
|
+
const reportUrl = new URL(`https://github.com/webgptorg/promptbook/issues/new`);
|
|
498
|
+
reportUrl.searchParams.set('labels', 'bug');
|
|
499
|
+
reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
|
|
500
|
+
reportUrl.searchParams.set('title', report.title);
|
|
501
|
+
reportUrl.searchParams.set('body', report.body);
|
|
502
|
+
return reportUrl;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* This error type indicates that the error should not happen and its last check before crashing with some other error
|
|
507
|
+
*
|
|
508
|
+
* @public exported from `@promptbook/core`
|
|
509
|
+
*/
|
|
510
|
+
class UnexpectedError extends Error {
|
|
511
|
+
constructor(message) {
|
|
512
|
+
super(spaceTrim.spaceTrim((block) => `
|
|
513
|
+
${block(message)}
|
|
514
|
+
|
|
515
|
+
Note: This error should not happen.
|
|
516
|
+
It's probbably a bug in the pipeline collection
|
|
517
|
+
|
|
518
|
+
Please report issue:
|
|
519
|
+
${block(getErrorReportUrl(new Error(message)).href)}
|
|
520
|
+
|
|
521
|
+
Or contact us on ${ADMIN_EMAIL}
|
|
522
|
+
|
|
523
|
+
`));
|
|
524
|
+
this.name = 'UnexpectedError';
|
|
525
|
+
Object.setPrototypeOf(this, UnexpectedError.prototype);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* This error type indicates that somewhere in the code non-Error object was thrown and it was wrapped into the `WrappedError`
|
|
531
|
+
*
|
|
532
|
+
* @public exported from `@promptbook/core`
|
|
533
|
+
*/
|
|
534
|
+
class WrappedError extends Error {
|
|
535
|
+
constructor(whatWasThrown) {
|
|
536
|
+
const tag = `[🤮]`;
|
|
537
|
+
console.error(tag, whatWasThrown);
|
|
538
|
+
super(spaceTrim.spaceTrim(`
|
|
539
|
+
Non-Error object was thrown
|
|
540
|
+
|
|
541
|
+
Note: Look for ${tag} in the console for more details
|
|
542
|
+
Please report issue on ${ADMIN_EMAIL}
|
|
543
|
+
`));
|
|
544
|
+
this.name = 'WrappedError';
|
|
545
|
+
Object.setPrototypeOf(this, WrappedError.prototype);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Helper used in catch blocks to assert that the error is an instance of `Error`
|
|
551
|
+
*
|
|
552
|
+
* @param whatWasThrown Any object that was thrown
|
|
553
|
+
* @returns Nothing if the error is an instance of `Error`
|
|
554
|
+
* @throws `WrappedError` or `UnexpectedError` if the error is not standard
|
|
555
|
+
*
|
|
556
|
+
* @private within the repository
|
|
557
|
+
*/
|
|
558
|
+
function assertsError(whatWasThrown) {
|
|
559
|
+
// Case 1: Handle error which was rethrown as `WrappedError`
|
|
560
|
+
if (whatWasThrown instanceof WrappedError) {
|
|
561
|
+
const wrappedError = whatWasThrown;
|
|
562
|
+
throw wrappedError;
|
|
563
|
+
}
|
|
564
|
+
// Case 2: Handle unexpected errors
|
|
565
|
+
if (whatWasThrown instanceof UnexpectedError) {
|
|
566
|
+
const unexpectedError = whatWasThrown;
|
|
567
|
+
throw unexpectedError;
|
|
568
|
+
}
|
|
569
|
+
// Case 3: Handle standard errors - keep them up to consumer
|
|
570
|
+
if (whatWasThrown instanceof Error) {
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
// Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
|
|
574
|
+
throw new WrappedError(whatWasThrown);
|
|
575
|
+
}
|
|
576
|
+
|
|
422
577
|
/**
|
|
423
578
|
* Wraps action to handle error console logging and exit process with error code
|
|
424
579
|
*
|
|
@@ -433,9 +588,7 @@
|
|
|
433
588
|
return process.exit(0);
|
|
434
589
|
}
|
|
435
590
|
catch (error) {
|
|
436
|
-
|
|
437
|
-
throw error;
|
|
438
|
-
}
|
|
591
|
+
assertsError(error);
|
|
439
592
|
// console.error(colors.bgRed(error.name));
|
|
440
593
|
console.error(colors__default["default"].red(/* error.stack || */ error.message));
|
|
441
594
|
return process.exit(1);
|
|
@@ -542,74 +695,6 @@
|
|
|
542
695
|
}
|
|
543
696
|
}
|
|
544
697
|
|
|
545
|
-
/**
|
|
546
|
-
* Make error report URL for the given error
|
|
547
|
-
*
|
|
548
|
-
* @private private within the repository
|
|
549
|
-
*/
|
|
550
|
-
function getErrorReportUrl(error) {
|
|
551
|
-
const report = {
|
|
552
|
-
title: `🐜 Error report from ${NAME}`,
|
|
553
|
-
body: spaceTrim__default["default"]((block) => `
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
\`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
|
|
557
|
-
|
|
558
|
-
\`\`\`
|
|
559
|
-
${block(error.message || '(no error message)')}
|
|
560
|
-
\`\`\`
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
## More info:
|
|
564
|
-
|
|
565
|
-
- **Promptbook engine version:** ${PROMPTBOOK_ENGINE_VERSION}
|
|
566
|
-
- **Book language version:** ${BOOK_LANGUAGE_VERSION}
|
|
567
|
-
- **Time:** ${new Date().toISOString()}
|
|
568
|
-
|
|
569
|
-
<details>
|
|
570
|
-
<summary>Stack trace:</summary>
|
|
571
|
-
|
|
572
|
-
## Stack trace:
|
|
573
|
-
|
|
574
|
-
\`\`\`stacktrace
|
|
575
|
-
${block(error.stack || '(empty)')}
|
|
576
|
-
\`\`\`
|
|
577
|
-
</details>
|
|
578
|
-
|
|
579
|
-
`),
|
|
580
|
-
};
|
|
581
|
-
const reportUrl = new URL(`https://github.com/webgptorg/promptbook/issues/new`);
|
|
582
|
-
reportUrl.searchParams.set('labels', 'bug');
|
|
583
|
-
reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
|
|
584
|
-
reportUrl.searchParams.set('title', report.title);
|
|
585
|
-
reportUrl.searchParams.set('body', report.body);
|
|
586
|
-
return reportUrl;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* This error type indicates that the error should not happen and its last check before crashing with some other error
|
|
591
|
-
*
|
|
592
|
-
* @public exported from `@promptbook/core`
|
|
593
|
-
*/
|
|
594
|
-
class UnexpectedError extends Error {
|
|
595
|
-
constructor(message) {
|
|
596
|
-
super(spaceTrim.spaceTrim((block) => `
|
|
597
|
-
${block(message)}
|
|
598
|
-
|
|
599
|
-
Note: This error should not happen.
|
|
600
|
-
It's probbably a bug in the pipeline collection
|
|
601
|
-
|
|
602
|
-
Please report issue:
|
|
603
|
-
${block(getErrorReportUrl(new Error(message)).href)}
|
|
604
|
-
|
|
605
|
-
Or contact us on ${ADMIN_EMAIL}
|
|
606
|
-
|
|
607
|
-
`));
|
|
608
|
-
this.name = 'UnexpectedError';
|
|
609
|
-
Object.setPrototypeOf(this, UnexpectedError.prototype);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
698
|
/**
|
|
614
699
|
* @@@
|
|
615
700
|
*
|
|
@@ -929,6 +1014,40 @@
|
|
|
929
1014
|
keepUnused(...sideEffectSubjects);
|
|
930
1015
|
}
|
|
931
1016
|
|
|
1017
|
+
/**
|
|
1018
|
+
* Convert identification to Promptbook token
|
|
1019
|
+
*
|
|
1020
|
+
* @param identification
|
|
1021
|
+
*
|
|
1022
|
+
* @public exported from `@promptbook/core`
|
|
1023
|
+
*/
|
|
1024
|
+
function identificationToPromptbookToken(identification) {
|
|
1025
|
+
const { appId, userId, userToken } = identification;
|
|
1026
|
+
const promptbookToken = `${appId}-${userId}-${userToken}`;
|
|
1027
|
+
return promptbookToken;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Convert Promptbook token to identification
|
|
1032
|
+
*
|
|
1033
|
+
* @param promptbookToken
|
|
1034
|
+
*
|
|
1035
|
+
* @public exported from `@promptbook/core`
|
|
1036
|
+
*/
|
|
1037
|
+
function promptbookTokenToIdentification(promptbookToken) {
|
|
1038
|
+
const [appId, userId, userToken] = promptbookToken.split('-');
|
|
1039
|
+
if (!appId || !userId || !userToken) {
|
|
1040
|
+
throw new Error(`Invalid promptbook token: ${promptbookToken}`);
|
|
1041
|
+
}
|
|
1042
|
+
const identification = {
|
|
1043
|
+
appId,
|
|
1044
|
+
userId,
|
|
1045
|
+
userToken,
|
|
1046
|
+
isAnonymous: false,
|
|
1047
|
+
};
|
|
1048
|
+
return identification;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
932
1051
|
/**
|
|
933
1052
|
* Just marks a place of place where should be something implemented
|
|
934
1053
|
* No side effects.
|
|
@@ -942,27 +1061,199 @@
|
|
|
942
1061
|
function TODO_USE(...value) {
|
|
943
1062
|
}
|
|
944
1063
|
|
|
945
|
-
/**
|
|
946
|
-
* @@@
|
|
947
|
-
*
|
|
948
|
-
* @public exported from `@promptbook/node`
|
|
949
|
-
*/
|
|
950
|
-
function $provideFilesystemForNode(options) {
|
|
951
|
-
if (!$isRunningInNode()) {
|
|
952
|
-
throw new EnvironmentMismatchError('Function `$provideFilesystemForNode` works only in Node.js environment');
|
|
1064
|
+
/**
|
|
1065
|
+
* @@@
|
|
1066
|
+
*
|
|
1067
|
+
* @public exported from `@promptbook/node`
|
|
1068
|
+
*/
|
|
1069
|
+
function $provideFilesystemForNode(options) {
|
|
1070
|
+
if (!$isRunningInNode()) {
|
|
1071
|
+
throw new EnvironmentMismatchError('Function `$provideFilesystemForNode` works only in Node.js environment');
|
|
1072
|
+
}
|
|
1073
|
+
return {
|
|
1074
|
+
stat: promises.stat,
|
|
1075
|
+
access: promises.access,
|
|
1076
|
+
constants: promises.constants,
|
|
1077
|
+
readFile: promises.readFile,
|
|
1078
|
+
writeFile: promises.writeFile,
|
|
1079
|
+
readdir: promises.readdir,
|
|
1080
|
+
mkdir: promises.mkdir,
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
1085
|
+
*/
|
|
1086
|
+
|
|
1087
|
+
/**
|
|
1088
|
+
* Checks if the file exists
|
|
1089
|
+
*
|
|
1090
|
+
* @private within the repository
|
|
1091
|
+
*/
|
|
1092
|
+
async function isFileExisting(filename, fs) {
|
|
1093
|
+
const isReadAccessAllowed = await fs
|
|
1094
|
+
.access(filename, fs.constants.R_OK)
|
|
1095
|
+
.then(() => true)
|
|
1096
|
+
.catch(() => false);
|
|
1097
|
+
if (!isReadAccessAllowed) {
|
|
1098
|
+
return false;
|
|
1099
|
+
}
|
|
1100
|
+
const isFile = await fs
|
|
1101
|
+
.stat(filename)
|
|
1102
|
+
.then((fileStat) => fileStat.isFile())
|
|
1103
|
+
.catch(() => false);
|
|
1104
|
+
return isFile;
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Note: Not [~🟢~] because it is not directly dependent on `fs
|
|
1108
|
+
* TODO: [🐠] This can be a validator - with variants that return true/false and variants that throw errors with meaningless messages
|
|
1109
|
+
* TODO: [🖇] What about symlinks?
|
|
1110
|
+
*/
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* Determines if the given path is a root path.
|
|
1114
|
+
*
|
|
1115
|
+
* Note: This does not check if the file exists only if the path is valid
|
|
1116
|
+
* @public exported from `@promptbook/utils`
|
|
1117
|
+
*/
|
|
1118
|
+
function isRootPath(value) {
|
|
1119
|
+
if (value === '/') {
|
|
1120
|
+
return true;
|
|
1121
|
+
}
|
|
1122
|
+
if (/^[A-Z]:\\$/i.test(value)) {
|
|
1123
|
+
return true;
|
|
1124
|
+
}
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
/**
|
|
1128
|
+
* TODO: [🍏] Make for MacOS paths
|
|
1129
|
+
*/
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* Provides the path to the `.env` file
|
|
1133
|
+
*
|
|
1134
|
+
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
|
|
1135
|
+
*
|
|
1136
|
+
* @private within the repository - for CLI utils
|
|
1137
|
+
*/
|
|
1138
|
+
async function $provideEnvFilename() {
|
|
1139
|
+
if (!$isRunningInNode()) {
|
|
1140
|
+
throw new EnvironmentMismatchError('Function `$provideEnvFilename` works only in Node.js environment');
|
|
1141
|
+
}
|
|
1142
|
+
const envFilePatterns = [
|
|
1143
|
+
'.env',
|
|
1144
|
+
'.env.test',
|
|
1145
|
+
'.env.local',
|
|
1146
|
+
'.env.development.local',
|
|
1147
|
+
'.env.development',
|
|
1148
|
+
'.env.production.local',
|
|
1149
|
+
'.env.production',
|
|
1150
|
+
'.env.prod.local',
|
|
1151
|
+
'.env.prod',
|
|
1152
|
+
// <- TODO: Maybe add more patterns
|
|
1153
|
+
];
|
|
1154
|
+
let rootDirname = process.cwd();
|
|
1155
|
+
up_to_root: for (let i = 0; i < LOOP_LIMIT; i++) {
|
|
1156
|
+
for (const pattern of envFilePatterns) {
|
|
1157
|
+
const envFilename = path.join(rootDirname, pattern);
|
|
1158
|
+
if (await isFileExisting(envFilename, $provideFilesystemForNode())) {
|
|
1159
|
+
$setUsedEnvFilename(envFilename);
|
|
1160
|
+
return envFilename;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
if (isRootPath(rootDirname)) {
|
|
1164
|
+
break up_to_root;
|
|
1165
|
+
}
|
|
1166
|
+
// Note: If the directory does not exist, try the parent directory
|
|
1167
|
+
rootDirname = path.join(rootDirname, '..');
|
|
1168
|
+
}
|
|
1169
|
+
return null;
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
1173
|
+
*/
|
|
1174
|
+
|
|
1175
|
+
/**
|
|
1176
|
+
* Stores data in .env variables
|
|
1177
|
+
*
|
|
1178
|
+
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file and also writes to `process.env`
|
|
1179
|
+
*
|
|
1180
|
+
* @private within the repository - for CLI utils
|
|
1181
|
+
*/
|
|
1182
|
+
class $EnvStorage {
|
|
1183
|
+
constructor() {
|
|
1184
|
+
this.envFilename = null;
|
|
1185
|
+
}
|
|
1186
|
+
async $provideOrCreateEnvFile() {
|
|
1187
|
+
if (this.envFilename !== null) {
|
|
1188
|
+
return this.envFilename;
|
|
1189
|
+
}
|
|
1190
|
+
let envFilename = await $provideEnvFilename();
|
|
1191
|
+
if (envFilename !== null) {
|
|
1192
|
+
this.envFilename = envFilename;
|
|
1193
|
+
return envFilename;
|
|
1194
|
+
}
|
|
1195
|
+
envFilename = path.join(process.cwd(), '.env');
|
|
1196
|
+
await promises.writeFile(envFilename, '# This file was initialized by Promptbook', 'utf-8');
|
|
1197
|
+
this.envFilename = envFilename;
|
|
1198
|
+
return envFilename;
|
|
1199
|
+
}
|
|
1200
|
+
transformKey(key) {
|
|
1201
|
+
return normalizeTo_SCREAMING_CASE(key);
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Returns the number of key/value pairs currently present in the list associated with the object.
|
|
1205
|
+
*/
|
|
1206
|
+
get length() {
|
|
1207
|
+
throw new NotYetImplementedError('Method `$EnvStorage.length` not implemented.');
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Empties the list associated with the object of all key/value pairs, if there are any.
|
|
1211
|
+
*/
|
|
1212
|
+
clear() {
|
|
1213
|
+
throw new NotYetImplementedError('Method `$EnvStorage.clear` not implemented.');
|
|
1214
|
+
}
|
|
1215
|
+
/**
|
|
1216
|
+
* Returns the current value associated with the given key, or null if the given key does not exist in the list associated with the object.
|
|
1217
|
+
*/
|
|
1218
|
+
async getItem(key) {
|
|
1219
|
+
dotenv__namespace.config({ path: await this.$provideOrCreateEnvFile() });
|
|
1220
|
+
return process.env[this.transformKey(key)] || null;
|
|
1221
|
+
}
|
|
1222
|
+
/**
|
|
1223
|
+
* Returns the name of the nth key in the list, or null if n is greater than or equal to the number of key/value pairs in the object.
|
|
1224
|
+
*/
|
|
1225
|
+
key(index) {
|
|
1226
|
+
throw new NotYetImplementedError('Method `$EnvStorage.key` not implemented.');
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
|
|
1230
|
+
*/
|
|
1231
|
+
async setItem(key, value) {
|
|
1232
|
+
const envFilename = await this.$provideOrCreateEnvFile();
|
|
1233
|
+
const envContent = await promises.readFile(envFilename, 'utf-8');
|
|
1234
|
+
const transformedKey = this.transformKey(key);
|
|
1235
|
+
const updatedEnvContent = envContent
|
|
1236
|
+
.split('\n')
|
|
1237
|
+
.filter((line) => !line.startsWith(`# ${GENERATOR_WARNING_IN_ENV}`)) // Remove GENERATOR_WARNING_IN_ENV
|
|
1238
|
+
.filter((line) => !line.startsWith(`${transformedKey}=`)) // Remove existing key if present
|
|
1239
|
+
.join('\n');
|
|
1240
|
+
const newEnvContent = spaceTrim__default["default"]((block) => `
|
|
1241
|
+
${block(updatedEnvContent)}
|
|
1242
|
+
|
|
1243
|
+
# ${GENERATOR_WARNING_IN_ENV}
|
|
1244
|
+
${transformedKey}=${JSON.stringify(value)}
|
|
1245
|
+
`);
|
|
1246
|
+
await promises.writeFile(envFilename, newEnvContent, 'utf-8');
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Removes the key/value pair with the given key from the list associated with the object, if a key/value pair with the given key exists.
|
|
1250
|
+
*/
|
|
1251
|
+
removeItem(key) {
|
|
1252
|
+
throw new NotYetImplementedError('Method `$EnvStorage.removeItem` not implemented.');
|
|
953
1253
|
}
|
|
954
|
-
return {
|
|
955
|
-
stat: promises.stat,
|
|
956
|
-
access: promises.access,
|
|
957
|
-
constants: promises.constants,
|
|
958
|
-
readFile: promises.readFile,
|
|
959
|
-
writeFile: promises.writeFile,
|
|
960
|
-
readdir: promises.readdir,
|
|
961
|
-
mkdir: promises.mkdir,
|
|
962
|
-
};
|
|
963
1254
|
}
|
|
964
1255
|
/**
|
|
965
|
-
*
|
|
1256
|
+
* TODO: Write file more securely - ensure that there can be no accidental overwriting of existing variables and other content
|
|
966
1257
|
*/
|
|
967
1258
|
|
|
968
1259
|
/**
|
|
@@ -1098,9 +1389,7 @@
|
|
|
1098
1389
|
JSON.stringify(value); // <- TODO: [0]
|
|
1099
1390
|
}
|
|
1100
1391
|
catch (error) {
|
|
1101
|
-
|
|
1102
|
-
throw error;
|
|
1103
|
-
}
|
|
1392
|
+
assertsError(error);
|
|
1104
1393
|
throw new UnexpectedError(spaceTrim__default["default"]((block) => `
|
|
1105
1394
|
\`${name}\` is not serializable
|
|
1106
1395
|
|
|
@@ -1333,31 +1622,6 @@
|
|
|
1333
1622
|
* TODO: [🍙] Make some standard order of json properties
|
|
1334
1623
|
*/
|
|
1335
1624
|
|
|
1336
|
-
/**
|
|
1337
|
-
* Checks if the file exists
|
|
1338
|
-
*
|
|
1339
|
-
* @private within the repository
|
|
1340
|
-
*/
|
|
1341
|
-
async function isFileExisting(filename, fs) {
|
|
1342
|
-
const isReadAccessAllowed = await fs
|
|
1343
|
-
.access(filename, fs.constants.R_OK)
|
|
1344
|
-
.then(() => true)
|
|
1345
|
-
.catch(() => false);
|
|
1346
|
-
if (!isReadAccessAllowed) {
|
|
1347
|
-
return false;
|
|
1348
|
-
}
|
|
1349
|
-
const isFile = await fs
|
|
1350
|
-
.stat(filename)
|
|
1351
|
-
.then((fileStat) => fileStat.isFile())
|
|
1352
|
-
.catch(() => false);
|
|
1353
|
-
return isFile;
|
|
1354
|
-
}
|
|
1355
|
-
/**
|
|
1356
|
-
* Note: Not [~🟢~] because it is not directly dependent on `fs
|
|
1357
|
-
* TODO: [🐠] This can be a validator - with variants that return true/false and variants that throw errors with meaningless messages
|
|
1358
|
-
* TODO: [🖇] What about symlinks?
|
|
1359
|
-
*/
|
|
1360
|
-
|
|
1361
1625
|
/**
|
|
1362
1626
|
* Removes emojis from a string and fix whitespaces
|
|
1363
1627
|
*
|
|
@@ -1863,53 +2127,6 @@
|
|
|
1863
2127
|
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
1864
2128
|
*/
|
|
1865
2129
|
|
|
1866
|
-
/**
|
|
1867
|
-
* Stores data in memory (HEAP)
|
|
1868
|
-
*
|
|
1869
|
-
* @public exported from `@promptbook/core`
|
|
1870
|
-
*/
|
|
1871
|
-
class MemoryStorage {
|
|
1872
|
-
constructor() {
|
|
1873
|
-
this.storage = {};
|
|
1874
|
-
}
|
|
1875
|
-
/**
|
|
1876
|
-
* Returns the number of key/value pairs currently present in the list associated with the object.
|
|
1877
|
-
*/
|
|
1878
|
-
get length() {
|
|
1879
|
-
return Object.keys(this.storage).length;
|
|
1880
|
-
}
|
|
1881
|
-
/**
|
|
1882
|
-
* Empties the list associated with the object of all key/value pairs, if there are any.
|
|
1883
|
-
*/
|
|
1884
|
-
clear() {
|
|
1885
|
-
this.storage = {};
|
|
1886
|
-
}
|
|
1887
|
-
/**
|
|
1888
|
-
* Returns the current value associated with the given key, or null if the given key does not exist in the list associated with the object.
|
|
1889
|
-
*/
|
|
1890
|
-
getItem(key) {
|
|
1891
|
-
return this.storage[key] || null;
|
|
1892
|
-
}
|
|
1893
|
-
/**
|
|
1894
|
-
* Returns the name of the nth key in the list, or null if n is greater than or equal to the number of key/value pairs in the object.
|
|
1895
|
-
*/
|
|
1896
|
-
key(index) {
|
|
1897
|
-
return Object.keys(this.storage)[index] || null;
|
|
1898
|
-
}
|
|
1899
|
-
/**
|
|
1900
|
-
* Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
|
|
1901
|
-
*/
|
|
1902
|
-
setItem(key, value) {
|
|
1903
|
-
this.storage[key] = value;
|
|
1904
|
-
}
|
|
1905
|
-
/**
|
|
1906
|
-
* Removes the key/value pair with the given key from the list associated with the object, if a key/value pair with the given key exists.
|
|
1907
|
-
*/
|
|
1908
|
-
removeItem(key) {
|
|
1909
|
-
delete this.storage[key];
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
|
|
1913
2130
|
/**
|
|
1914
2131
|
* This error indicates problems parsing the format value
|
|
1915
2132
|
*
|
|
@@ -2086,7 +2303,7 @@
|
|
|
2086
2303
|
}
|
|
2087
2304
|
}
|
|
2088
2305
|
/**
|
|
2089
|
-
* TODO:
|
|
2306
|
+
* TODO: [🧠][🌂] Add id to all errors
|
|
2090
2307
|
*/
|
|
2091
2308
|
|
|
2092
2309
|
/**
|
|
@@ -2148,7 +2365,10 @@
|
|
|
2148
2365
|
PipelineExecutionError,
|
|
2149
2366
|
PipelineLogicError,
|
|
2150
2367
|
PipelineUrlError,
|
|
2368
|
+
AuthenticationError,
|
|
2369
|
+
PromptbookFetchError,
|
|
2151
2370
|
UnexpectedError,
|
|
2371
|
+
WrappedError,
|
|
2152
2372
|
// TODO: [🪑]> VersionMismatchError,
|
|
2153
2373
|
};
|
|
2154
2374
|
/**
|
|
@@ -2165,8 +2385,6 @@
|
|
|
2165
2385
|
TypeError,
|
|
2166
2386
|
URIError,
|
|
2167
2387
|
AggregateError,
|
|
2168
|
-
AuthenticationError,
|
|
2169
|
-
PromptbookFetchError,
|
|
2170
2388
|
/*
|
|
2171
2389
|
Note: Not widely supported
|
|
2172
2390
|
> InternalError,
|
|
@@ -2224,17 +2442,31 @@
|
|
|
2224
2442
|
*/
|
|
2225
2443
|
async function createRemoteClient(options) {
|
|
2226
2444
|
const { remoteServerUrl } = options;
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2445
|
+
if (!isValidUrl(remoteServerUrl)) {
|
|
2446
|
+
throw new Error(`Invalid \`remoteServerUrl\`: "${remoteServerUrl}"`);
|
|
2447
|
+
}
|
|
2448
|
+
const remoteServerUrlParsed = new URL(remoteServerUrl);
|
|
2449
|
+
if (remoteServerUrlParsed.pathname !== '/' && remoteServerUrlParsed.pathname !== '') {
|
|
2450
|
+
remoteServerUrlParsed.pathname = '/';
|
|
2451
|
+
throw new Error(spaceTrim__default["default"]((block) => `
|
|
2452
|
+
Remote server requires root url \`/\`
|
|
2453
|
+
|
|
2454
|
+
You have provided \`remoteServerUrl\`:
|
|
2455
|
+
${block(remoteServerUrl)}
|
|
2456
|
+
|
|
2457
|
+
But something like this is expected:
|
|
2458
|
+
${block(remoteServerUrlParsed.href)}
|
|
2459
|
+
|
|
2460
|
+
Note: If you need to run multiple services on the same server, use 3rd or 4th degree subdomain
|
|
2461
|
+
|
|
2462
|
+
`));
|
|
2230
2463
|
}
|
|
2231
|
-
path = `${path}/socket.io`;
|
|
2232
2464
|
return new Promise((resolve, reject) => {
|
|
2233
2465
|
const socket = socket_ioClient.io(remoteServerUrl, {
|
|
2234
2466
|
retries: CONNECTION_RETRIES_LIMIT,
|
|
2235
2467
|
timeout: CONNECTION_TIMEOUT_MS,
|
|
2236
|
-
path,
|
|
2237
|
-
transports: [
|
|
2468
|
+
path: '/socket.io',
|
|
2469
|
+
transports: ['polling', 'websocket' /*, <- TODO: [🌬] Allow to pass `transports`, add 'webtransport' */],
|
|
2238
2470
|
});
|
|
2239
2471
|
// console.log('Connecting to', this.options.remoteServerUrl.href, { socket });
|
|
2240
2472
|
socket.on('connect', () => {
|
|
@@ -2359,6 +2591,53 @@
|
|
|
2359
2591
|
* TODO: [🧠] Maybe remove `@promptbook/remote-client` and just use `@promptbook/core`
|
|
2360
2592
|
*/
|
|
2361
2593
|
|
|
2594
|
+
/**
|
|
2595
|
+
* Stores data in memory (HEAP)
|
|
2596
|
+
*
|
|
2597
|
+
* @public exported from `@promptbook/core`
|
|
2598
|
+
*/
|
|
2599
|
+
class MemoryStorage {
|
|
2600
|
+
constructor() {
|
|
2601
|
+
this.storage = {};
|
|
2602
|
+
}
|
|
2603
|
+
/**
|
|
2604
|
+
* Returns the number of key/value pairs currently present in the list associated with the object.
|
|
2605
|
+
*/
|
|
2606
|
+
get length() {
|
|
2607
|
+
return Object.keys(this.storage).length;
|
|
2608
|
+
}
|
|
2609
|
+
/**
|
|
2610
|
+
* Empties the list associated with the object of all key/value pairs, if there are any.
|
|
2611
|
+
*/
|
|
2612
|
+
clear() {
|
|
2613
|
+
this.storage = {};
|
|
2614
|
+
}
|
|
2615
|
+
/**
|
|
2616
|
+
* Returns the current value associated with the given key, or null if the given key does not exist in the list associated with the object.
|
|
2617
|
+
*/
|
|
2618
|
+
getItem(key) {
|
|
2619
|
+
return this.storage[key] || null;
|
|
2620
|
+
}
|
|
2621
|
+
/**
|
|
2622
|
+
* Returns the name of the nth key in the list, or null if n is greater than or equal to the number of key/value pairs in the object.
|
|
2623
|
+
*/
|
|
2624
|
+
key(index) {
|
|
2625
|
+
return Object.keys(this.storage)[index] || null;
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
|
|
2629
|
+
*/
|
|
2630
|
+
setItem(key, value) {
|
|
2631
|
+
this.storage[key] = value;
|
|
2632
|
+
}
|
|
2633
|
+
/**
|
|
2634
|
+
* Removes the key/value pair with the given key from the list associated with the object, if a key/value pair with the given key exists.
|
|
2635
|
+
*/
|
|
2636
|
+
removeItem(key) {
|
|
2637
|
+
delete this.storage[key];
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2362
2641
|
/**
|
|
2363
2642
|
* Simple wrapper `new Date().toISOString()`
|
|
2364
2643
|
*
|
|
@@ -2617,102 +2896,39 @@
|
|
|
2617
2896
|
};
|
|
2618
2897
|
}
|
|
2619
2898
|
if (llmTools.callCompletionModel !== undefined) {
|
|
2620
|
-
proxyTools.callCompletionModel = async (prompt) => {
|
|
2621
|
-
// console.info('[🚕] callCompletionModel through countTotalUsage');
|
|
2622
|
-
const promptResult = await llmTools.callCompletionModel(prompt);
|
|
2623
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
2624
|
-
spending.next(promptResult.usage);
|
|
2625
|
-
return promptResult;
|
|
2626
|
-
};
|
|
2627
|
-
}
|
|
2628
|
-
if (llmTools.callEmbeddingModel !== undefined) {
|
|
2629
|
-
proxyTools.callEmbeddingModel = async (prompt) => {
|
|
2630
|
-
// console.info('[🚕] callEmbeddingModel through countTotalUsage');
|
|
2631
|
-
const promptResult = await llmTools.callEmbeddingModel(prompt);
|
|
2632
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
2633
|
-
spending.next(promptResult.usage);
|
|
2634
|
-
return promptResult;
|
|
2635
|
-
};
|
|
2636
|
-
}
|
|
2637
|
-
// <- Note: [🤖]
|
|
2638
|
-
return proxyTools;
|
|
2639
|
-
}
|
|
2640
|
-
/**
|
|
2641
|
-
* TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
|
|
2642
|
-
* TODO: [🧠] Is there some meaningfull way how to test this util
|
|
2643
|
-
* TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
|
|
2644
|
-
* > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
|
|
2645
|
-
* TODO: [👷♂️] @@@ Manual about construction of llmTools
|
|
2646
|
-
*/
|
|
2647
|
-
|
|
2648
|
-
/**
|
|
2649
|
-
* Determines if the given path is a root path.
|
|
2650
|
-
*
|
|
2651
|
-
* Note: This does not check if the file exists only if the path is valid
|
|
2652
|
-
* @public exported from `@promptbook/utils`
|
|
2653
|
-
*/
|
|
2654
|
-
function isRootPath(value) {
|
|
2655
|
-
if (value === '/') {
|
|
2656
|
-
return true;
|
|
2657
|
-
}
|
|
2658
|
-
if (/^[A-Z]:\\$/i.test(value)) {
|
|
2659
|
-
return true;
|
|
2660
|
-
}
|
|
2661
|
-
return false;
|
|
2662
|
-
}
|
|
2663
|
-
/**
|
|
2664
|
-
* TODO: [🍏] Make for MacOS paths
|
|
2665
|
-
*/
|
|
2666
|
-
|
|
2667
|
-
/**
|
|
2668
|
-
* Provides the path to the `.env` file
|
|
2669
|
-
*
|
|
2670
|
-
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access .env file
|
|
2671
|
-
*
|
|
2672
|
-
* @private within the repository - for CLI utils
|
|
2673
|
-
*/
|
|
2674
|
-
async function $provideEnvFilepath() {
|
|
2675
|
-
if (!$isRunningInNode()) {
|
|
2676
|
-
throw new EnvironmentMismatchError('Function `$provideEnvFilepath` works only in Node.js environment');
|
|
2677
|
-
}
|
|
2678
|
-
const envFilePatterns = [
|
|
2679
|
-
'.env',
|
|
2680
|
-
'.env.test',
|
|
2681
|
-
'.env.local',
|
|
2682
|
-
'.env.development.local',
|
|
2683
|
-
'.env.development',
|
|
2684
|
-
'.env.production.local',
|
|
2685
|
-
'.env.production',
|
|
2686
|
-
'.env.prod.local',
|
|
2687
|
-
'.env.prod',
|
|
2688
|
-
// <- TODO: Maybe add more patterns
|
|
2689
|
-
];
|
|
2690
|
-
let rootDirname = process.cwd();
|
|
2691
|
-
up_to_root: for (let i = 0; i < LOOP_LIMIT; i++) {
|
|
2692
|
-
for (const pattern of envFilePatterns) {
|
|
2693
|
-
const envFilename = path.join(rootDirname, pattern);
|
|
2694
|
-
if (await isFileExisting(envFilename, $provideFilesystemForNode())) {
|
|
2695
|
-
$setUsedEnvFilename(envFilename);
|
|
2696
|
-
return envFilename;
|
|
2697
|
-
}
|
|
2698
|
-
}
|
|
2699
|
-
if (isRootPath(rootDirname)) {
|
|
2700
|
-
break up_to_root;
|
|
2701
|
-
}
|
|
2702
|
-
// Note: If the directory does not exist, try the parent directory
|
|
2703
|
-
rootDirname = path.join(rootDirname, '..');
|
|
2899
|
+
proxyTools.callCompletionModel = async (prompt) => {
|
|
2900
|
+
// console.info('[🚕] callCompletionModel through countTotalUsage');
|
|
2901
|
+
const promptResult = await llmTools.callCompletionModel(prompt);
|
|
2902
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
2903
|
+
spending.next(promptResult.usage);
|
|
2904
|
+
return promptResult;
|
|
2905
|
+
};
|
|
2704
2906
|
}
|
|
2705
|
-
|
|
2907
|
+
if (llmTools.callEmbeddingModel !== undefined) {
|
|
2908
|
+
proxyTools.callEmbeddingModel = async (prompt) => {
|
|
2909
|
+
// console.info('[🚕] callEmbeddingModel through countTotalUsage');
|
|
2910
|
+
const promptResult = await llmTools.callEmbeddingModel(prompt);
|
|
2911
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
2912
|
+
spending.next(promptResult.usage);
|
|
2913
|
+
return promptResult;
|
|
2914
|
+
};
|
|
2915
|
+
}
|
|
2916
|
+
// <- Note: [🤖]
|
|
2917
|
+
return proxyTools;
|
|
2706
2918
|
}
|
|
2707
2919
|
/**
|
|
2708
|
-
*
|
|
2920
|
+
* TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
|
|
2921
|
+
* TODO: [🧠] Is there some meaningfull way how to test this util
|
|
2922
|
+
* TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
|
|
2923
|
+
* > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
|
|
2924
|
+
* TODO: [👷♂️] @@@ Manual about construction of llmTools
|
|
2709
2925
|
*/
|
|
2710
2926
|
|
|
2711
2927
|
/**
|
|
2712
2928
|
* @@@
|
|
2713
2929
|
*
|
|
2714
2930
|
* @@@ .env
|
|
2715
|
-
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access
|
|
2931
|
+
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
|
|
2716
2932
|
*
|
|
2717
2933
|
* It looks for environment variables:
|
|
2718
2934
|
* - `process.env.OPENAI_API_KEY`
|
|
@@ -2726,7 +2942,7 @@
|
|
|
2726
2942
|
if (!$isRunningInNode()) {
|
|
2727
2943
|
throw new EnvironmentMismatchError('Function `$provideLlmToolsFromEnv` works only in Node.js environment');
|
|
2728
2944
|
}
|
|
2729
|
-
const envFilepath = await $
|
|
2945
|
+
const envFilepath = await $provideEnvFilename();
|
|
2730
2946
|
if (envFilepath !== null) {
|
|
2731
2947
|
dotenv__namespace.config({ path: envFilepath });
|
|
2732
2948
|
}
|
|
@@ -2834,14 +3050,15 @@
|
|
|
2834
3050
|
}
|
|
2835
3051
|
}
|
|
2836
3052
|
catch (error) {
|
|
2837
|
-
|
|
3053
|
+
assertsError(error);
|
|
3054
|
+
if (error instanceof UnexpectedError) {
|
|
2838
3055
|
throw error;
|
|
2839
3056
|
}
|
|
2840
3057
|
errors.push({ llmExecutionTools, error });
|
|
2841
3058
|
}
|
|
2842
3059
|
}
|
|
2843
3060
|
if (errors.length === 1) {
|
|
2844
|
-
throw errors[0];
|
|
3061
|
+
throw errors[0].error;
|
|
2845
3062
|
}
|
|
2846
3063
|
else if (errors.length > 1) {
|
|
2847
3064
|
throw new PipelineExecutionError(
|
|
@@ -2988,7 +3205,7 @@
|
|
|
2988
3205
|
* Note: This function is not cached, every call creates new instance of `MultipleLlmExecutionTools`
|
|
2989
3206
|
*
|
|
2990
3207
|
* @@@ .env
|
|
2991
|
-
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access
|
|
3208
|
+
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
|
|
2992
3209
|
*
|
|
2993
3210
|
* It looks for environment variables:
|
|
2994
3211
|
* - `process.env.OPENAI_API_KEY`
|
|
@@ -3033,7 +3250,7 @@
|
|
|
3033
3250
|
/**
|
|
3034
3251
|
* Returns LLM tools for CLI
|
|
3035
3252
|
*
|
|
3036
|
-
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access
|
|
3253
|
+
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file and also writes this .env file
|
|
3037
3254
|
*
|
|
3038
3255
|
* @private within the repository - for CLI utils
|
|
3039
3256
|
*/
|
|
@@ -3042,18 +3259,27 @@
|
|
|
3042
3259
|
throw new EnvironmentMismatchError('Function `$provideLlmToolsForWizzardOrCli` works only in Node.js environment');
|
|
3043
3260
|
}
|
|
3044
3261
|
options = options !== null && options !== void 0 ? options : { strategy: 'BRING_YOUR_OWN_KEYS' };
|
|
3045
|
-
const { strategy, isCacheReloaded } = options;
|
|
3262
|
+
const { isLoginloaded, strategy, isCacheReloaded } = options;
|
|
3046
3263
|
let llmExecutionTools;
|
|
3047
3264
|
if (strategy === 'REMOTE_SERVER') {
|
|
3048
3265
|
const { remoteServerUrl = DEFAULT_REMOTE_SERVER_URL, loginPrompt } = options;
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3266
|
+
const storage = new $EnvStorage();
|
|
3267
|
+
let key = `PROMPTBOOK_TOKEN`;
|
|
3268
|
+
if (remoteServerUrl !== DEFAULT_REMOTE_SERVER_URL) {
|
|
3269
|
+
key = `${key}_${remoteServerUrl.replace(/^https?:\/\//i, '')}`;
|
|
3270
|
+
}
|
|
3271
|
+
let identification = null;
|
|
3272
|
+
let promptbookToken = await storage.getItem(key);
|
|
3273
|
+
if (promptbookToken === null || isLoginloaded) {
|
|
3055
3274
|
identification = await loginPrompt();
|
|
3056
|
-
|
|
3275
|
+
// Note: When login prompt fails, `process.exit(1)` is called so no need to check for null
|
|
3276
|
+
if (identification.isAnonymous === false) {
|
|
3277
|
+
promptbookToken = identificationToPromptbookToken(identification);
|
|
3278
|
+
await storage.setItem(key, promptbookToken);
|
|
3279
|
+
}
|
|
3280
|
+
}
|
|
3281
|
+
else {
|
|
3282
|
+
identification = promptbookTokenToIdentification(promptbookToken);
|
|
3057
3283
|
}
|
|
3058
3284
|
llmExecutionTools = new RemoteLlmExecutionTools({
|
|
3059
3285
|
remoteServerUrl,
|
|
@@ -3094,9 +3320,7 @@
|
|
|
3094
3320
|
return await fetch(urlOrRequest, init);
|
|
3095
3321
|
}
|
|
3096
3322
|
catch (error) {
|
|
3097
|
-
|
|
3098
|
-
throw error;
|
|
3099
|
-
}
|
|
3323
|
+
assertsError(error);
|
|
3100
3324
|
let url;
|
|
3101
3325
|
if (typeof urlOrRequest === 'string') {
|
|
3102
3326
|
url = urlOrRequest;
|
|
@@ -3135,8 +3359,8 @@
|
|
|
3135
3359
|
/**
|
|
3136
3360
|
* @private utility of CLI
|
|
3137
3361
|
*/
|
|
3138
|
-
function $provideLlmToolsForCli(options) {
|
|
3139
|
-
const { cliOptions: {
|
|
3362
|
+
async function $provideLlmToolsForCli(options) {
|
|
3363
|
+
const { isLoginloaded, cliOptions: {
|
|
3140
3364
|
/* TODO: Use verbose: isVerbose, */ interactive: isInteractive, provider, remoteServerUrl: remoteServerUrlRaw, }, } = options;
|
|
3141
3365
|
let strategy;
|
|
3142
3366
|
if (/^b/i.test(provider)) {
|
|
@@ -3150,7 +3374,11 @@
|
|
|
3150
3374
|
process.exit(1);
|
|
3151
3375
|
}
|
|
3152
3376
|
if (strategy === 'BRING_YOUR_OWN_KEYS') {
|
|
3153
|
-
|
|
3377
|
+
if (isLoginloaded) {
|
|
3378
|
+
throw new UnexpectedError(`\`$provideLlmToolsForCli\` isLoginloaded is not supported for strategy "BRING_YOUR_OWN_KEYS"`);
|
|
3379
|
+
}
|
|
3380
|
+
const llm = await $provideLlmToolsForWizzardOrCli({ strategy, ...options });
|
|
3381
|
+
return { strategy, llm };
|
|
3154
3382
|
}
|
|
3155
3383
|
else if (strategy === 'REMOTE_SERVER') {
|
|
3156
3384
|
if (!isValidUrl(remoteServerUrlRaw)) {
|
|
@@ -3158,7 +3386,8 @@
|
|
|
3158
3386
|
process.exit(1);
|
|
3159
3387
|
}
|
|
3160
3388
|
const remoteServerUrl = remoteServerUrlRaw.endsWith('/') ? remoteServerUrlRaw.slice(0, -1) : remoteServerUrlRaw;
|
|
3161
|
-
|
|
3389
|
+
const llm = await $provideLlmToolsForWizzardOrCli({
|
|
3390
|
+
isLoginloaded,
|
|
3162
3391
|
strategy,
|
|
3163
3392
|
appId: CLI_APP_ID,
|
|
3164
3393
|
remoteServerUrl,
|
|
@@ -3168,6 +3397,10 @@
|
|
|
3168
3397
|
console.log(colors__default["default"].red(`You can not login to remote server in non-interactive mode`));
|
|
3169
3398
|
process.exit(1);
|
|
3170
3399
|
}
|
|
3400
|
+
console.info(colors__default["default"].cyan(spaceTrim__default["default"](`
|
|
3401
|
+
You will be logged in to ${remoteServerUrl}
|
|
3402
|
+
If you don't have an account, it will be created automatically.
|
|
3403
|
+
`)));
|
|
3171
3404
|
const { username, password } = await prompts__default["default"]([
|
|
3172
3405
|
{
|
|
3173
3406
|
type: 'text',
|
|
@@ -3185,7 +3418,6 @@
|
|
|
3185
3418
|
},
|
|
3186
3419
|
]);
|
|
3187
3420
|
const loginUrl = `${remoteServerUrl}/login`;
|
|
3188
|
-
console.log('!!!', { loginUrl });
|
|
3189
3421
|
// TODO: [🧠] Should we use normal `fetch` or `scraperFetch`
|
|
3190
3422
|
const response = await promptbookFetch(loginUrl, {
|
|
3191
3423
|
method: 'POST',
|
|
@@ -3198,20 +3430,7 @@
|
|
|
3198
3430
|
password,
|
|
3199
3431
|
}),
|
|
3200
3432
|
});
|
|
3201
|
-
console.log('!!!', {
|
|
3202
|
-
loginUrl,
|
|
3203
|
-
username,
|
|
3204
|
-
password,
|
|
3205
|
-
// type: response.type,
|
|
3206
|
-
// text: await response.text(),
|
|
3207
|
-
});
|
|
3208
3433
|
const { isSuccess, message, error, identification } = (await response.json());
|
|
3209
|
-
console.log('!!!', {
|
|
3210
|
-
isSuccess,
|
|
3211
|
-
message,
|
|
3212
|
-
error,
|
|
3213
|
-
identification,
|
|
3214
|
-
});
|
|
3215
3434
|
if (message) {
|
|
3216
3435
|
if (isSuccess) {
|
|
3217
3436
|
console.log(colors__default["default"].green(message));
|
|
@@ -3232,6 +3451,7 @@
|
|
|
3232
3451
|
return identification;
|
|
3233
3452
|
},
|
|
3234
3453
|
});
|
|
3454
|
+
return { strategy, llm };
|
|
3235
3455
|
}
|
|
3236
3456
|
else {
|
|
3237
3457
|
throw new UnexpectedError(`\`$provideLlmToolsForCli\` wrong strategy "${strategy}"`);
|
|
@@ -3253,11 +3473,12 @@
|
|
|
3253
3473
|
listModelsCommand.alias('models');
|
|
3254
3474
|
listModelsCommand.alias('llm');
|
|
3255
3475
|
listModelsCommand.action(handleActionErrors(async (cliOptions) => {
|
|
3256
|
-
|
|
3257
|
-
// TODO: !!!!!! Not relevant for remote server and also for `about` command
|
|
3258
|
-
const llm = await $provideLlmToolsForCli({ cliOptions });
|
|
3476
|
+
const { strategy, llm } = await $provideLlmToolsForCli({ cliOptions });
|
|
3259
3477
|
$sideEffect(llm);
|
|
3260
3478
|
// <- Note: Providing LLM tools will make a side effect of registering all available LLM tools to show the message
|
|
3479
|
+
if (strategy !== 'BRING_YOUR_OWN_KEYS') {
|
|
3480
|
+
console.warn(colors__default["default"].yellow(`You are using --strategy ${strategy} but models listed below are relevant for --strategy BRING_YOUR_OWN_KEYS`));
|
|
3481
|
+
}
|
|
3261
3482
|
console.info($registeredLlmToolsMessage());
|
|
3262
3483
|
return process.exit(0);
|
|
3263
3484
|
}));
|
|
@@ -3440,9 +3661,7 @@
|
|
|
3440
3661
|
return result.trim();
|
|
3441
3662
|
}
|
|
3442
3663
|
catch (error) {
|
|
3443
|
-
|
|
3444
|
-
throw error;
|
|
3445
|
-
}
|
|
3664
|
+
assertsError(error);
|
|
3446
3665
|
return null;
|
|
3447
3666
|
}
|
|
3448
3667
|
}
|
|
@@ -3497,9 +3716,7 @@
|
|
|
3497
3716
|
return result.trim() + toExec;
|
|
3498
3717
|
}
|
|
3499
3718
|
catch (error) {
|
|
3500
|
-
|
|
3501
|
-
throw error;
|
|
3502
|
-
}
|
|
3719
|
+
assertsError(error);
|
|
3503
3720
|
return null;
|
|
3504
3721
|
}
|
|
3505
3722
|
}
|
|
@@ -3530,9 +3747,7 @@
|
|
|
3530
3747
|
throw new Error(`Can not locate app ${appName} on Windows.`);
|
|
3531
3748
|
}
|
|
3532
3749
|
catch (error) {
|
|
3533
|
-
|
|
3534
|
-
throw error;
|
|
3535
|
-
}
|
|
3750
|
+
assertsError(error);
|
|
3536
3751
|
return null;
|
|
3537
3752
|
}
|
|
3538
3753
|
}
|
|
@@ -3791,6 +4006,7 @@
|
|
|
3791
4006
|
`));
|
|
3792
4007
|
listModelsCommand.alias('scrapers');
|
|
3793
4008
|
listModelsCommand.action(handleActionErrors(async () => {
|
|
4009
|
+
// TODO: [🌞] Do not allow on REMOTE_SERVER strategy
|
|
3794
4010
|
const scrapers = await $provideScrapersForNode({});
|
|
3795
4011
|
const executables = await $provideExecutablesForNode();
|
|
3796
4012
|
console.info(spaceTrim__default["default"]((block) => `
|
|
@@ -3826,42 +4042,20 @@
|
|
|
3826
4042
|
loginCommand.description(spaceTrim__default["default"](`
|
|
3827
4043
|
Login to the remote Promptbook server
|
|
3828
4044
|
`));
|
|
3829
|
-
loginCommand.action(handleActionErrors(async () => {
|
|
3830
|
-
//
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
{
|
|
3838
|
-
type: 'text',
|
|
3839
|
-
name: 'email',
|
|
3840
|
-
message: 'Enter your email:',
|
|
3841
|
-
validate: (value) => (isValidEmail(value) ? true : 'Valid email is required'),
|
|
3842
|
-
},
|
|
3843
|
-
{
|
|
3844
|
-
type: 'password',
|
|
3845
|
-
name: 'password',
|
|
3846
|
-
message: 'Enter your password:',
|
|
3847
|
-
validate: (value) => value.length /* <- TODO: [🧠] Better password validation */ > 0 ? true : 'Password is required',
|
|
4045
|
+
loginCommand.action(handleActionErrors(async (cliOptions) => {
|
|
4046
|
+
// Note: Not interested in return value of this function but the side effect of logging in
|
|
4047
|
+
await $provideLlmToolsForCli({
|
|
4048
|
+
isLoginloaded: true,
|
|
4049
|
+
cliOptions: {
|
|
4050
|
+
...cliOptions,
|
|
4051
|
+
strategy: 'REMOTE_SERVER', // <- Note: Overriding strategy to `REMOTE_SERVER`
|
|
4052
|
+
// TODO: Do not allow flag `--strategy` in `login` command at all
|
|
3848
4053
|
},
|
|
3849
|
-
|
|
3850
|
-
TODO_USE(email, password);
|
|
3851
|
-
await waitasecond.forTime(1000);
|
|
3852
|
-
console.error(colors__default["default"].green(spaceTrim__default["default"](`
|
|
3853
|
-
Your account ${email} was successfully created.
|
|
3854
|
-
|
|
3855
|
-
Please verify your email:
|
|
3856
|
-
https://brj.app/api/v1/customer/register-account?apiKey=PRODdh003eNKaec7PoO1AzU244tsL4WO
|
|
3857
|
-
|
|
3858
|
-
After verification, you will receive 500 000 credits for free 🎉
|
|
3859
|
-
`)));
|
|
4054
|
+
});
|
|
3860
4055
|
return process.exit(0);
|
|
3861
4056
|
}));
|
|
3862
4057
|
}
|
|
3863
4058
|
/**
|
|
3864
|
-
* TODO: Pass remote server URL (and path)
|
|
3865
4059
|
* TODO: Implement non-interactive login
|
|
3866
4060
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
3867
4061
|
* Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
|
|
@@ -4282,6 +4476,9 @@
|
|
|
4282
4476
|
/**
|
|
4283
4477
|
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
4284
4478
|
*
|
|
4479
|
+
* @param value The string to check
|
|
4480
|
+
* @returns True if the string is a valid JSON string, false otherwise
|
|
4481
|
+
*
|
|
4285
4482
|
* @public exported from `@promptbook/utils`
|
|
4286
4483
|
*/
|
|
4287
4484
|
function isValidJsonString(value /* <- [👨⚖️] */) {
|
|
@@ -4290,9 +4487,7 @@
|
|
|
4290
4487
|
return true;
|
|
4291
4488
|
}
|
|
4292
4489
|
catch (error) {
|
|
4293
|
-
|
|
4294
|
-
throw error;
|
|
4295
|
-
}
|
|
4490
|
+
assertsError(error);
|
|
4296
4491
|
if (error.message.includes('Unexpected token')) {
|
|
4297
4492
|
return false;
|
|
4298
4493
|
}
|
|
@@ -4823,8 +5018,8 @@
|
|
|
4823
5018
|
updatedAt = new Date();
|
|
4824
5019
|
errors.push(...executionResult.errors);
|
|
4825
5020
|
warnings.push(...executionResult.warnings);
|
|
4826
|
-
// <- TODO:
|
|
4827
|
-
// TODO: [🧠]
|
|
5021
|
+
// <- TODO: [🌂] Only unique errors and warnings should be added (or filtered)
|
|
5022
|
+
// TODO: [🧠] !! errors, warning, isSuccessful are redundant both in `ExecutionTask` and `ExecutionTask.currentValue`
|
|
4828
5023
|
// Also maybe move `ExecutionTask.currentValue.usage` -> `ExecutionTask.usage`
|
|
4829
5024
|
// And delete `ExecutionTask.currentValue.preparedPipeline`
|
|
4830
5025
|
assertsTaskSuccessful(executionResult);
|
|
@@ -4834,6 +5029,7 @@
|
|
|
4834
5029
|
partialResultSubject.next(executionResult);
|
|
4835
5030
|
}
|
|
4836
5031
|
catch (error) {
|
|
5032
|
+
assertsError(error);
|
|
4837
5033
|
status = 'ERROR';
|
|
4838
5034
|
errors.push(error);
|
|
4839
5035
|
partialResultSubject.error(error);
|
|
@@ -4979,13 +5175,19 @@
|
|
|
4979
5175
|
return value.toISOString();
|
|
4980
5176
|
}
|
|
4981
5177
|
else {
|
|
4982
|
-
|
|
5178
|
+
try {
|
|
5179
|
+
return JSON.stringify(value);
|
|
5180
|
+
}
|
|
5181
|
+
catch (error) {
|
|
5182
|
+
if (error instanceof TypeError && error.message.includes('circular structure')) {
|
|
5183
|
+
return VALUE_STRINGS.circular;
|
|
5184
|
+
}
|
|
5185
|
+
throw error;
|
|
5186
|
+
}
|
|
4983
5187
|
}
|
|
4984
5188
|
}
|
|
4985
5189
|
catch (error) {
|
|
4986
|
-
|
|
4987
|
-
throw error;
|
|
4988
|
-
}
|
|
5190
|
+
assertsError(error);
|
|
4989
5191
|
console.error(error);
|
|
4990
5192
|
return VALUE_STRINGS.unserializable;
|
|
4991
5193
|
}
|
|
@@ -5042,9 +5244,7 @@
|
|
|
5042
5244
|
}
|
|
5043
5245
|
}
|
|
5044
5246
|
catch (error) {
|
|
5045
|
-
|
|
5046
|
-
throw error;
|
|
5047
|
-
}
|
|
5247
|
+
assertsError(error);
|
|
5048
5248
|
throw new ParseError(spaceTrim.spaceTrim((block) => `
|
|
5049
5249
|
Can not extract variables from the script
|
|
5050
5250
|
${block(error.stack || error.message)}
|
|
@@ -5163,6 +5363,28 @@
|
|
|
5163
5363
|
// encoding: 'utf-8',
|
|
5164
5364
|
});
|
|
5165
5365
|
|
|
5366
|
+
/**
|
|
5367
|
+
* Function to check if a string is valid CSV
|
|
5368
|
+
*
|
|
5369
|
+
* @param value The string to check
|
|
5370
|
+
* @returns True if the string is a valid CSV string, false otherwise
|
|
5371
|
+
*
|
|
5372
|
+
* @public exported from `@promptbook/utils`
|
|
5373
|
+
*/
|
|
5374
|
+
function isValidCsvString(value) {
|
|
5375
|
+
try {
|
|
5376
|
+
// A simple check for CSV format: at least one comma and no invalid characters
|
|
5377
|
+
if (value.includes(',') && /^[\w\s,"']+$/.test(value)) {
|
|
5378
|
+
return true;
|
|
5379
|
+
}
|
|
5380
|
+
return false;
|
|
5381
|
+
}
|
|
5382
|
+
catch (error) {
|
|
5383
|
+
assertsError(error);
|
|
5384
|
+
return false;
|
|
5385
|
+
}
|
|
5386
|
+
}
|
|
5387
|
+
|
|
5166
5388
|
/**
|
|
5167
5389
|
* Definition for CSV spreadsheet
|
|
5168
5390
|
*
|
|
@@ -5173,7 +5395,7 @@
|
|
|
5173
5395
|
formatName: 'CSV',
|
|
5174
5396
|
aliases: ['SPREADSHEET', 'TABLE'],
|
|
5175
5397
|
isValid(value, settings, schema) {
|
|
5176
|
-
return
|
|
5398
|
+
return isValidCsvString(value);
|
|
5177
5399
|
},
|
|
5178
5400
|
canBeValid(partialValue, settings, schema) {
|
|
5179
5401
|
return true;
|
|
@@ -5327,6 +5549,30 @@
|
|
|
5327
5549
|
* TODO: [🏢] Allow to expect something inside each item of list and other formats
|
|
5328
5550
|
*/
|
|
5329
5551
|
|
|
5552
|
+
/**
|
|
5553
|
+
* Function to check if a string is valid XML
|
|
5554
|
+
*
|
|
5555
|
+
* @param value
|
|
5556
|
+
* @returns True if the string is a valid XML string, false otherwise
|
|
5557
|
+
*
|
|
5558
|
+
* @public exported from `@promptbook/utils`
|
|
5559
|
+
*/
|
|
5560
|
+
function isValidXmlString(value) {
|
|
5561
|
+
try {
|
|
5562
|
+
const parser = new DOMParser();
|
|
5563
|
+
const parsedDocument = parser.parseFromString(value, 'application/xml');
|
|
5564
|
+
const parserError = parsedDocument.getElementsByTagName('parsererror');
|
|
5565
|
+
if (parserError.length > 0) {
|
|
5566
|
+
return false;
|
|
5567
|
+
}
|
|
5568
|
+
return true;
|
|
5569
|
+
}
|
|
5570
|
+
catch (error) {
|
|
5571
|
+
assertsError(error);
|
|
5572
|
+
return false;
|
|
5573
|
+
}
|
|
5574
|
+
}
|
|
5575
|
+
|
|
5330
5576
|
/**
|
|
5331
5577
|
* Definition for XML format
|
|
5332
5578
|
*
|
|
@@ -5336,7 +5582,7 @@
|
|
|
5336
5582
|
formatName: 'XML',
|
|
5337
5583
|
mimeType: 'application/xml',
|
|
5338
5584
|
isValid(value, settings, schema) {
|
|
5339
|
-
return
|
|
5585
|
+
return isValidXmlString(value);
|
|
5340
5586
|
},
|
|
5341
5587
|
canBeValid(partialValue, settings, schema) {
|
|
5342
5588
|
return true;
|
|
@@ -5928,9 +6174,7 @@
|
|
|
5928
6174
|
break scripts;
|
|
5929
6175
|
}
|
|
5930
6176
|
catch (error) {
|
|
5931
|
-
|
|
5932
|
-
throw error;
|
|
5933
|
-
}
|
|
6177
|
+
assertsError(error);
|
|
5934
6178
|
if (error instanceof UnexpectedError) {
|
|
5935
6179
|
throw error;
|
|
5936
6180
|
}
|
|
@@ -6000,9 +6244,7 @@
|
|
|
6000
6244
|
break scripts;
|
|
6001
6245
|
}
|
|
6002
6246
|
catch (error) {
|
|
6003
|
-
|
|
6004
|
-
throw error;
|
|
6005
|
-
}
|
|
6247
|
+
assertsError(error);
|
|
6006
6248
|
if (error instanceof UnexpectedError) {
|
|
6007
6249
|
throw error;
|
|
6008
6250
|
}
|
|
@@ -6623,9 +6865,7 @@
|
|
|
6623
6865
|
await Promise.all(resolving);
|
|
6624
6866
|
}
|
|
6625
6867
|
catch (error /* <- Note: [3] */) {
|
|
6626
|
-
|
|
6627
|
-
throw error;
|
|
6628
|
-
}
|
|
6868
|
+
assertsError(error);
|
|
6629
6869
|
// Note: No need to rethrow UnexpectedError
|
|
6630
6870
|
// if (error instanceof UnexpectedError) {
|
|
6631
6871
|
// Note: Count usage, [🧠] Maybe put to separate function executionReportJsonToUsage + DRY [🤹♂️]
|
|
@@ -7101,9 +7341,7 @@
|
|
|
7101
7341
|
knowledgePreparedUnflatten[index] = pieces;
|
|
7102
7342
|
}
|
|
7103
7343
|
catch (error) {
|
|
7104
|
-
|
|
7105
|
-
throw error;
|
|
7106
|
-
}
|
|
7344
|
+
assertsError(error);
|
|
7107
7345
|
console.warn(error);
|
|
7108
7346
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
7109
7347
|
}
|
|
@@ -7901,6 +8139,8 @@
|
|
|
7901
8139
|
*/
|
|
7902
8140
|
|
|
7903
8141
|
/**
|
|
8142
|
+
import { WrappedError } from '../../errors/WrappedError';
|
|
8143
|
+
import { assertsError } from '../../errors/assertsError';
|
|
7904
8144
|
* Parses the expect command
|
|
7905
8145
|
*
|
|
7906
8146
|
* @see `documentationUrl` for more details
|
|
@@ -7992,9 +8232,7 @@
|
|
|
7992
8232
|
};
|
|
7993
8233
|
}
|
|
7994
8234
|
catch (error) {
|
|
7995
|
-
|
|
7996
|
-
throw error;
|
|
7997
|
-
}
|
|
8235
|
+
assertsError(error);
|
|
7998
8236
|
throw new ParseError(spaceTrim__default["default"]((block) => `
|
|
7999
8237
|
Invalid FORMAT command
|
|
8000
8238
|
${block(error.message)}:
|
|
@@ -11242,9 +11480,7 @@
|
|
|
11242
11480
|
}
|
|
11243
11481
|
}
|
|
11244
11482
|
catch (error) {
|
|
11245
|
-
|
|
11246
|
-
throw error;
|
|
11247
|
-
}
|
|
11483
|
+
assertsError(error);
|
|
11248
11484
|
if (error instanceof ReferenceError) {
|
|
11249
11485
|
const undefinedName = error.message.split(' ')[0];
|
|
11250
11486
|
/*
|
|
@@ -11519,9 +11755,7 @@
|
|
|
11519
11755
|
// ---
|
|
11520
11756
|
}
|
|
11521
11757
|
catch (error) {
|
|
11522
|
-
|
|
11523
|
-
throw error;
|
|
11524
|
-
}
|
|
11758
|
+
assertsError(error);
|
|
11525
11759
|
// TODO: [7] DRY
|
|
11526
11760
|
const wrappedErrorMessage = spaceTrim__default["default"]((block) => `
|
|
11527
11761
|
${error.name} in pipeline ${fileName.split('\\').join('/')}:
|
|
@@ -11612,9 +11846,7 @@
|
|
|
11612
11846
|
}
|
|
11613
11847
|
}
|
|
11614
11848
|
catch (error) {
|
|
11615
|
-
|
|
11616
|
-
throw error;
|
|
11617
|
-
}
|
|
11849
|
+
assertsError(error);
|
|
11618
11850
|
// TODO: [7] DRY
|
|
11619
11851
|
const wrappedErrorMessage = spaceTrim__default["default"]((block) => `
|
|
11620
11852
|
${error.name} in pipeline ${fileName.split('\\').join('/')}:
|
|
@@ -11830,7 +12062,7 @@
|
|
|
11830
12062
|
isCacheReloaded,
|
|
11831
12063
|
}; /* <- TODO: ` satisfies PrepareAndScrapeOptions` */
|
|
11832
12064
|
const fs = $provideFilesystemForNode(prepareAndScrapeOptions);
|
|
11833
|
-
const llm = await $provideLlmToolsForCli({
|
|
12065
|
+
const { llm } = await $provideLlmToolsForCli({
|
|
11834
12066
|
cliOptions,
|
|
11835
12067
|
...prepareAndScrapeOptions,
|
|
11836
12068
|
});
|
|
@@ -12123,9 +12355,7 @@
|
|
|
12123
12355
|
}
|
|
12124
12356
|
}
|
|
12125
12357
|
catch (error) {
|
|
12126
|
-
|
|
12127
|
-
throw error;
|
|
12128
|
-
}
|
|
12358
|
+
assertsError(error);
|
|
12129
12359
|
console.info(colors__default["default"].red(`Prettify ${error.name} ${filename}`));
|
|
12130
12360
|
console.error(colors__default["default"].bgRed(`${error.name} in ${path.basename(__filename)}`));
|
|
12131
12361
|
console.error(colors__default["default"].red(error.stack || error.message));
|
|
@@ -12445,9 +12675,7 @@
|
|
|
12445
12675
|
return true;
|
|
12446
12676
|
}
|
|
12447
12677
|
catch (error) {
|
|
12448
|
-
|
|
12449
|
-
throw error;
|
|
12450
|
-
}
|
|
12678
|
+
assertsError(error);
|
|
12451
12679
|
return false;
|
|
12452
12680
|
}
|
|
12453
12681
|
}
|
|
@@ -12672,9 +12900,7 @@
|
|
|
12672
12900
|
ongoingParameters = result.outputParameters;
|
|
12673
12901
|
}
|
|
12674
12902
|
catch (error) {
|
|
12675
|
-
|
|
12676
|
-
throw error;
|
|
12677
|
-
}
|
|
12903
|
+
assertsError(error);
|
|
12678
12904
|
// TODO: Allow to ressurect the chatbot after an error - prompt the user to continue
|
|
12679
12905
|
console.error(colors__default["default"].red(error.stack || error.message));
|
|
12680
12906
|
return process.exit(1);
|
|
@@ -12707,7 +12933,6 @@
|
|
|
12707
12933
|
runCommand.option('-j, --json <json>', `Pass all or some input parameters as JSON record, if used the output is also returned as JSON`);
|
|
12708
12934
|
runCommand.option('-s, --save-report <path>', `Save report to file`);
|
|
12709
12935
|
runCommand.action(handleActionErrors(async (pipelineSource, cliOptions) => {
|
|
12710
|
-
console.log('!!!', cliOptions);
|
|
12711
12936
|
const { reload: isCacheReloaded, interactive: isInteractive, formfactor: isFormfactorUsed, json, verbose: isVerbose, saveReport, } = cliOptions;
|
|
12712
12937
|
if (pipelineSource.includes('-') && normalizeToKebabCase(pipelineSource) === pipelineSource) {
|
|
12713
12938
|
console.error(colors__default["default"].red(`""${pipelineSource}" is not a valid command or book. See 'ptbk --help'.`));
|
|
@@ -12733,12 +12958,10 @@
|
|
|
12733
12958
|
const fs = $provideFilesystemForNode(prepareAndScrapeOptions);
|
|
12734
12959
|
let llm;
|
|
12735
12960
|
try {
|
|
12736
|
-
llm = await $provideLlmToolsForCli({ cliOptions, ...prepareAndScrapeOptions });
|
|
12961
|
+
llm = (await $provideLlmToolsForCli({ cliOptions, ...prepareAndScrapeOptions })).llm;
|
|
12737
12962
|
}
|
|
12738
12963
|
catch (error) {
|
|
12739
|
-
|
|
12740
|
-
throw error;
|
|
12741
|
-
}
|
|
12964
|
+
assertsError(error);
|
|
12742
12965
|
if (!error.message.includes('No LLM tools')) {
|
|
12743
12966
|
throw error;
|
|
12744
12967
|
}
|
|
@@ -12944,6 +13167,198 @@
|
|
|
12944
13167
|
* TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
|
|
12945
13168
|
*/
|
|
12946
13169
|
|
|
13170
|
+
// TODO: !!!! List running services from REMOTE_SERVER_URLS
|
|
13171
|
+
// TODO: !!!! Import directly from YML
|
|
13172
|
+
/**
|
|
13173
|
+
* @private !!!! Decide how to expose this
|
|
13174
|
+
*/
|
|
13175
|
+
const openapiJson = {
|
|
13176
|
+
openapi: '3.0.0',
|
|
13177
|
+
info: {
|
|
13178
|
+
title: 'Promptbook Remote Server API (!!!! From TS)',
|
|
13179
|
+
version: '1.0.0',
|
|
13180
|
+
description: 'API documentation for the Promptbook Remote Server',
|
|
13181
|
+
},
|
|
13182
|
+
paths: {
|
|
13183
|
+
'/': {
|
|
13184
|
+
get: {
|
|
13185
|
+
summary: 'Get server details',
|
|
13186
|
+
description: 'Returns details about the Promptbook server.',
|
|
13187
|
+
responses: {
|
|
13188
|
+
'200': {
|
|
13189
|
+
description: 'Server details in markdown format.',
|
|
13190
|
+
},
|
|
13191
|
+
},
|
|
13192
|
+
},
|
|
13193
|
+
},
|
|
13194
|
+
'/login': {
|
|
13195
|
+
post: {
|
|
13196
|
+
summary: 'Login to the server',
|
|
13197
|
+
description: 'Login to the server and get identification.',
|
|
13198
|
+
requestBody: {
|
|
13199
|
+
required: true,
|
|
13200
|
+
content: {
|
|
13201
|
+
'application/json': {
|
|
13202
|
+
schema: {
|
|
13203
|
+
type: 'object',
|
|
13204
|
+
properties: {
|
|
13205
|
+
username: {
|
|
13206
|
+
type: 'string',
|
|
13207
|
+
},
|
|
13208
|
+
password: {
|
|
13209
|
+
type: 'string',
|
|
13210
|
+
},
|
|
13211
|
+
appId: {
|
|
13212
|
+
type: 'string',
|
|
13213
|
+
},
|
|
13214
|
+
},
|
|
13215
|
+
},
|
|
13216
|
+
},
|
|
13217
|
+
},
|
|
13218
|
+
},
|
|
13219
|
+
responses: {
|
|
13220
|
+
'200': {
|
|
13221
|
+
description: 'Successful login',
|
|
13222
|
+
content: {
|
|
13223
|
+
'application/json': {
|
|
13224
|
+
schema: {
|
|
13225
|
+
type: 'object',
|
|
13226
|
+
properties: {
|
|
13227
|
+
identification: {
|
|
13228
|
+
type: 'object',
|
|
13229
|
+
},
|
|
13230
|
+
},
|
|
13231
|
+
},
|
|
13232
|
+
},
|
|
13233
|
+
},
|
|
13234
|
+
},
|
|
13235
|
+
},
|
|
13236
|
+
},
|
|
13237
|
+
},
|
|
13238
|
+
'/books': {
|
|
13239
|
+
get: {
|
|
13240
|
+
summary: 'List all books',
|
|
13241
|
+
description: 'Returns a list of all available books in the collection.',
|
|
13242
|
+
responses: {
|
|
13243
|
+
'200': {
|
|
13244
|
+
description: 'A list of books.',
|
|
13245
|
+
content: {
|
|
13246
|
+
'application/json': {
|
|
13247
|
+
schema: {
|
|
13248
|
+
type: 'array',
|
|
13249
|
+
items: {
|
|
13250
|
+
type: 'string',
|
|
13251
|
+
},
|
|
13252
|
+
},
|
|
13253
|
+
},
|
|
13254
|
+
},
|
|
13255
|
+
},
|
|
13256
|
+
},
|
|
13257
|
+
},
|
|
13258
|
+
},
|
|
13259
|
+
'/books/{bookId}': {
|
|
13260
|
+
get: {
|
|
13261
|
+
summary: 'Get book content',
|
|
13262
|
+
description: 'Returns the content of a specific book.',
|
|
13263
|
+
parameters: [
|
|
13264
|
+
{
|
|
13265
|
+
in: 'path',
|
|
13266
|
+
name: 'bookId',
|
|
13267
|
+
required: true,
|
|
13268
|
+
schema: {
|
|
13269
|
+
type: 'string',
|
|
13270
|
+
},
|
|
13271
|
+
description: 'The ID of the book to retrieve.',
|
|
13272
|
+
},
|
|
13273
|
+
],
|
|
13274
|
+
responses: {
|
|
13275
|
+
'200': {
|
|
13276
|
+
description: 'The content of the book.',
|
|
13277
|
+
content: {
|
|
13278
|
+
'text/markdown': {
|
|
13279
|
+
schema: {
|
|
13280
|
+
type: 'string',
|
|
13281
|
+
},
|
|
13282
|
+
},
|
|
13283
|
+
},
|
|
13284
|
+
},
|
|
13285
|
+
'404': {
|
|
13286
|
+
description: 'Book not found.',
|
|
13287
|
+
},
|
|
13288
|
+
},
|
|
13289
|
+
},
|
|
13290
|
+
},
|
|
13291
|
+
'/executions': {
|
|
13292
|
+
get: {
|
|
13293
|
+
summary: 'List all executions',
|
|
13294
|
+
description: 'Returns a list of all running execution tasks.',
|
|
13295
|
+
responses: {
|
|
13296
|
+
'200': {
|
|
13297
|
+
description: 'A list of execution tasks.',
|
|
13298
|
+
content: {
|
|
13299
|
+
'application/json': {
|
|
13300
|
+
schema: {
|
|
13301
|
+
type: 'array',
|
|
13302
|
+
items: {
|
|
13303
|
+
type: 'object',
|
|
13304
|
+
},
|
|
13305
|
+
},
|
|
13306
|
+
},
|
|
13307
|
+
},
|
|
13308
|
+
},
|
|
13309
|
+
},
|
|
13310
|
+
},
|
|
13311
|
+
},
|
|
13312
|
+
'/executions/new': {
|
|
13313
|
+
post: {
|
|
13314
|
+
summary: 'Start a new execution',
|
|
13315
|
+
description: 'Starts a new execution task for a given pipeline.',
|
|
13316
|
+
requestBody: {
|
|
13317
|
+
required: true,
|
|
13318
|
+
content: {
|
|
13319
|
+
'application/json': {
|
|
13320
|
+
schema: {
|
|
13321
|
+
type: 'object',
|
|
13322
|
+
properties: {
|
|
13323
|
+
pipelineUrl: {
|
|
13324
|
+
type: 'string',
|
|
13325
|
+
},
|
|
13326
|
+
inputParameters: {
|
|
13327
|
+
type: 'object',
|
|
13328
|
+
},
|
|
13329
|
+
identification: {
|
|
13330
|
+
type: 'object',
|
|
13331
|
+
},
|
|
13332
|
+
},
|
|
13333
|
+
},
|
|
13334
|
+
},
|
|
13335
|
+
},
|
|
13336
|
+
},
|
|
13337
|
+
responses: {
|
|
13338
|
+
'200': {
|
|
13339
|
+
description: 'The newly created execution task.',
|
|
13340
|
+
content: {
|
|
13341
|
+
'application/json': {
|
|
13342
|
+
schema: {
|
|
13343
|
+
type: 'object',
|
|
13344
|
+
},
|
|
13345
|
+
},
|
|
13346
|
+
},
|
|
13347
|
+
},
|
|
13348
|
+
'400': {
|
|
13349
|
+
description: 'Invalid input.',
|
|
13350
|
+
},
|
|
13351
|
+
},
|
|
13352
|
+
},
|
|
13353
|
+
},
|
|
13354
|
+
},
|
|
13355
|
+
components: {},
|
|
13356
|
+
tags: [],
|
|
13357
|
+
};
|
|
13358
|
+
/**
|
|
13359
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
13360
|
+
*/
|
|
13361
|
+
|
|
12947
13362
|
/**
|
|
12948
13363
|
* Remote server is a proxy server that uses its execution tools internally and exposes the executor interface externally.
|
|
12949
13364
|
*
|
|
@@ -12954,7 +13369,7 @@
|
|
|
12954
13369
|
* @public exported from `@promptbook/remote-server`
|
|
12955
13370
|
*/
|
|
12956
13371
|
function startRemoteServer(options) {
|
|
12957
|
-
const { port, collection, createLlmExecutionTools, isAnonymousModeAllowed, isApplicationModeAllowed, isVerbose = DEFAULT_IS_VERBOSE, login, } = {
|
|
13372
|
+
const { port, collection, createLlmExecutionTools, createExecutionTools, isAnonymousModeAllowed, isApplicationModeAllowed, isVerbose = DEFAULT_IS_VERBOSE, login, } = {
|
|
12958
13373
|
isAnonymousModeAllowed: false,
|
|
12959
13374
|
isApplicationModeAllowed: false,
|
|
12960
13375
|
collection: null,
|
|
@@ -12962,22 +13377,6 @@
|
|
|
12962
13377
|
login: null,
|
|
12963
13378
|
...options,
|
|
12964
13379
|
};
|
|
12965
|
-
// <- TODO: [🦪] Some helper type to be able to use discriminant union types with destructuring
|
|
12966
|
-
let { rootPath = '/' } = options;
|
|
12967
|
-
if (!rootPath.startsWith('/')) {
|
|
12968
|
-
rootPath = `/${rootPath}`;
|
|
12969
|
-
} /* not else */
|
|
12970
|
-
if (rootPath.endsWith('/')) {
|
|
12971
|
-
rootPath = rootPath.slice(0, -1);
|
|
12972
|
-
} /* not else */
|
|
12973
|
-
if (rootPath === '/') {
|
|
12974
|
-
rootPath = '';
|
|
12975
|
-
}
|
|
12976
|
-
const socketioPath = '/' +
|
|
12977
|
-
`${rootPath}/socket.io`
|
|
12978
|
-
.split('/')
|
|
12979
|
-
.filter((part) => part !== '')
|
|
12980
|
-
.join('/');
|
|
12981
13380
|
const startupDate = new Date();
|
|
12982
13381
|
async function getExecutionToolsFromIdentification(identification) {
|
|
12983
13382
|
if (identification === null || identification === undefined) {
|
|
@@ -13000,23 +13399,25 @@
|
|
|
13000
13399
|
}
|
|
13001
13400
|
else if (isAnonymous === false && createLlmExecutionTools !== null) {
|
|
13002
13401
|
// Note: Application mode
|
|
13003
|
-
|
|
13004
|
-
llm = await createLlmExecutionTools({
|
|
13005
|
-
appId,
|
|
13006
|
-
userId,
|
|
13007
|
-
customOptions,
|
|
13008
|
-
});
|
|
13402
|
+
llm = await createLlmExecutionTools(identification);
|
|
13009
13403
|
}
|
|
13010
13404
|
else {
|
|
13011
13405
|
throw new PipelineExecutionError(`You must provide either llmToolsConfiguration or non-anonymous mode must be propperly configured`);
|
|
13012
13406
|
}
|
|
13013
|
-
const
|
|
13014
|
-
const
|
|
13407
|
+
const customExecutionTools = createExecutionTools ? await createExecutionTools(identification) : {};
|
|
13408
|
+
const fs = customExecutionTools.fs || $provideFilesystemForNode();
|
|
13409
|
+
const executables = customExecutionTools.executables || (await $provideExecutablesForNode());
|
|
13410
|
+
const scrapers = customExecutionTools.scrapers || (await $provideScrapersForNode({ fs, llm, executables }));
|
|
13411
|
+
const script = customExecutionTools.script || (await $provideScriptingForNode({}));
|
|
13412
|
+
const fetch = customExecutionTools.fetch || promptbookFetch;
|
|
13413
|
+
const userInterface = customExecutionTools.userInterface || undefined;
|
|
13015
13414
|
const tools = {
|
|
13016
13415
|
llm,
|
|
13017
13416
|
fs,
|
|
13018
|
-
scrapers
|
|
13019
|
-
script
|
|
13417
|
+
scrapers,
|
|
13418
|
+
script,
|
|
13419
|
+
fetch,
|
|
13420
|
+
userInterface,
|
|
13020
13421
|
};
|
|
13021
13422
|
return tools;
|
|
13022
13423
|
}
|
|
@@ -13026,39 +13427,27 @@
|
|
|
13026
13427
|
response.setHeader('X-Powered-By', 'Promptbook engine');
|
|
13027
13428
|
next();
|
|
13028
13429
|
});
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
version: '1.0.0',
|
|
13035
|
-
description: 'API documentation for the Promptbook Remote Server',
|
|
13036
|
-
},
|
|
13037
|
-
servers: [
|
|
13038
|
-
{
|
|
13039
|
-
url: `http://localhost:${port}${rootPath}`,
|
|
13040
|
-
// <- TODO: !!!!! Probbably: Pass `remoteServerUrl` instead of `port` and `rootPath`
|
|
13041
|
-
},
|
|
13042
|
-
],
|
|
13430
|
+
// TODO: !!!! Expose openapiJson to consumer and also allow to add new routes
|
|
13431
|
+
app.use(OpenApiValidator__namespace.middleware({
|
|
13432
|
+
apiSpec: openapiJson,
|
|
13433
|
+
ignorePaths(path) {
|
|
13434
|
+
return path.startsWith('/api-docs') || path.startsWith('/swagger') || path.startsWith('/openapi');
|
|
13043
13435
|
},
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
app.use([`/api-docs`,
|
|
13436
|
+
validateRequests: true,
|
|
13437
|
+
validateResponses: true,
|
|
13438
|
+
}));
|
|
13439
|
+
app.use([`/api-docs`, `/swagger`], swaggerUi__default["default"].serve, swaggerUi__default["default"].setup(openapiJson, {
|
|
13440
|
+
// customCss: '.swagger-ui .topbar { display: none }',
|
|
13441
|
+
// customSiteTitle: 'BRJ API',
|
|
13442
|
+
// customfavIcon: 'https://brj.app/favicon.ico',
|
|
13443
|
+
}));
|
|
13444
|
+
app.get(`/openapi`, (request, response) => {
|
|
13445
|
+
response.json(openapiJson);
|
|
13446
|
+
});
|
|
13048
13447
|
const runningExecutionTasks = [];
|
|
13049
13448
|
// <- TODO: [🤬] Identify the users
|
|
13050
13449
|
// TODO: [🧠] Do here some garbage collection of finished tasks
|
|
13051
|
-
|
|
13052
|
-
* @swagger
|
|
13053
|
-
* /:
|
|
13054
|
-
* get:
|
|
13055
|
-
* summary: Get server details
|
|
13056
|
-
* description: Returns details about the Promptbook server.
|
|
13057
|
-
* responses:
|
|
13058
|
-
* 200:
|
|
13059
|
-
* description: Server details in markdown format.
|
|
13060
|
-
*/
|
|
13061
|
-
app.get(['/', rootPath], async (request, response) => {
|
|
13450
|
+
app.get('/', async (request, response) => {
|
|
13062
13451
|
var _a;
|
|
13063
13452
|
if ((_a = request.url) === null || _a === void 0 ? void 0 : _a.includes('socket.io')) {
|
|
13064
13453
|
return;
|
|
@@ -13077,8 +13466,6 @@
|
|
|
13077
13466
|
## Details
|
|
13078
13467
|
|
|
13079
13468
|
**Server port:** ${port}
|
|
13080
|
-
**Server root path:** ${rootPath}
|
|
13081
|
-
**Socket.io path:** ${socketioPath}
|
|
13082
13469
|
**Startup date:** ${startupDate.toISOString()}
|
|
13083
13470
|
**Anonymouse mode:** ${isAnonymousModeAllowed ? 'enabled' : 'disabled'}
|
|
13084
13471
|
**Application mode:** ${isApplicationModeAllowed ? 'enabled' : 'disabled'}
|
|
@@ -13117,38 +13504,7 @@
|
|
|
13117
13504
|
https://github.com/webgptorg/promptbook
|
|
13118
13505
|
`));
|
|
13119
13506
|
});
|
|
13120
|
-
|
|
13121
|
-
* @swagger
|
|
13122
|
-
*
|
|
13123
|
-
* /login:
|
|
13124
|
-
* post:
|
|
13125
|
-
* summary: Login to the server
|
|
13126
|
-
* description: Login to the server and get identification.
|
|
13127
|
-
* requestBody:
|
|
13128
|
-
* required: true
|
|
13129
|
-
* content:
|
|
13130
|
-
* application/json:
|
|
13131
|
-
* schema:
|
|
13132
|
-
* type: object
|
|
13133
|
-
* properties:
|
|
13134
|
-
* username:
|
|
13135
|
-
* type: string
|
|
13136
|
-
* password:
|
|
13137
|
-
* type: string
|
|
13138
|
-
* appId:
|
|
13139
|
-
* type: string
|
|
13140
|
-
* responses:
|
|
13141
|
-
* 200:
|
|
13142
|
-
* description: Successful login
|
|
13143
|
-
* content:
|
|
13144
|
-
* application/json:
|
|
13145
|
-
* schema:
|
|
13146
|
-
* type: object
|
|
13147
|
-
* properties:
|
|
13148
|
-
* identification:
|
|
13149
|
-
* type: object
|
|
13150
|
-
*/
|
|
13151
|
-
app.post([`/login`, `${rootPath}/login`], async (request, response) => {
|
|
13507
|
+
app.post(`/login`, async (request, response) => {
|
|
13152
13508
|
if (!isApplicationModeAllowed || login === null) {
|
|
13153
13509
|
response.status(400).send('Application mode is not allowed');
|
|
13154
13510
|
return;
|
|
@@ -13173,9 +13529,7 @@
|
|
|
13173
13529
|
return;
|
|
13174
13530
|
}
|
|
13175
13531
|
catch (error) {
|
|
13176
|
-
|
|
13177
|
-
throw error;
|
|
13178
|
-
}
|
|
13532
|
+
assertsError(error);
|
|
13179
13533
|
if (error instanceof AuthenticationError) {
|
|
13180
13534
|
response.status(401).send({
|
|
13181
13535
|
isSuccess: false,
|
|
@@ -13190,23 +13544,7 @@
|
|
|
13190
13544
|
response.status(400).send({ error: serializeError(error) });
|
|
13191
13545
|
}
|
|
13192
13546
|
});
|
|
13193
|
-
|
|
13194
|
-
* @swagger
|
|
13195
|
-
* /books:
|
|
13196
|
-
* get:
|
|
13197
|
-
* summary: List all books
|
|
13198
|
-
* description: Returns a list of all available books in the collection.
|
|
13199
|
-
* responses:
|
|
13200
|
-
* 200:
|
|
13201
|
-
* description: A list of books.
|
|
13202
|
-
* content:
|
|
13203
|
-
* application/json:
|
|
13204
|
-
* schema:
|
|
13205
|
-
* type: array
|
|
13206
|
-
* items:
|
|
13207
|
-
* type: string
|
|
13208
|
-
*/
|
|
13209
|
-
app.get([`/books`, `${rootPath}/books`], async (request, response) => {
|
|
13547
|
+
app.get(`/books`, async (request, response) => {
|
|
13210
13548
|
if (collection === null) {
|
|
13211
13549
|
response.status(500).send('No collection available');
|
|
13212
13550
|
return;
|
|
@@ -13216,30 +13554,7 @@
|
|
|
13216
13554
|
response.send(pipelines);
|
|
13217
13555
|
});
|
|
13218
13556
|
// TODO: [🧠] Is it secure / good idea to expose source codes of hosted books
|
|
13219
|
-
|
|
13220
|
-
* @swagger
|
|
13221
|
-
* /books/{bookId}:
|
|
13222
|
-
* get:
|
|
13223
|
-
* summary: Get book content
|
|
13224
|
-
* description: Returns the content of a specific book.
|
|
13225
|
-
* parameters:
|
|
13226
|
-
* - in: path
|
|
13227
|
-
* name: bookId
|
|
13228
|
-
* required: true
|
|
13229
|
-
* schema:
|
|
13230
|
-
* type: string
|
|
13231
|
-
* description: The ID of the book to retrieve.
|
|
13232
|
-
* responses:
|
|
13233
|
-
* 200:
|
|
13234
|
-
* description: The content of the book.
|
|
13235
|
-
* content:
|
|
13236
|
-
* text/markdown:
|
|
13237
|
-
* schema:
|
|
13238
|
-
* type: string
|
|
13239
|
-
* 404:
|
|
13240
|
-
* description: Book not found.
|
|
13241
|
-
*/
|
|
13242
|
-
app.get([`/books/*`, `${rootPath}/books/*`], async (request, response) => {
|
|
13557
|
+
app.get(`/books/*`, async (request, response) => {
|
|
13243
13558
|
try {
|
|
13244
13559
|
if (collection === null) {
|
|
13245
13560
|
response.status(500).send('No collection nor books available');
|
|
@@ -13258,9 +13573,7 @@
|
|
|
13258
13573
|
.send(source.content);
|
|
13259
13574
|
}
|
|
13260
13575
|
catch (error) {
|
|
13261
|
-
|
|
13262
|
-
throw error;
|
|
13263
|
-
}
|
|
13576
|
+
assertsError(error);
|
|
13264
13577
|
response
|
|
13265
13578
|
.status(404)
|
|
13266
13579
|
.send({ error: serializeError(error) });
|
|
@@ -13293,26 +13606,10 @@
|
|
|
13293
13606
|
};
|
|
13294
13607
|
}
|
|
13295
13608
|
}
|
|
13296
|
-
|
|
13297
|
-
|
|
13298
|
-
* /executions:
|
|
13299
|
-
* get:
|
|
13300
|
-
* summary: List all executions
|
|
13301
|
-
* description: Returns a list of all running execution tasks.
|
|
13302
|
-
* responses:
|
|
13303
|
-
* 200:
|
|
13304
|
-
* description: A list of execution tasks.
|
|
13305
|
-
* content:
|
|
13306
|
-
* application/json:
|
|
13307
|
-
* schema:
|
|
13308
|
-
* type: array
|
|
13309
|
-
* items:
|
|
13310
|
-
* type: object
|
|
13311
|
-
*/
|
|
13312
|
-
app.get([`/executions`, `${rootPath}/executions`], async (request, response) => {
|
|
13313
|
-
response.send(runningExecutionTasks.map((runningExecutionTask) => exportExecutionTask(runningExecutionTask, false)));
|
|
13609
|
+
app.get(`/executions`, async (request, response) => {
|
|
13610
|
+
response.send(runningExecutionTasks.map((runningExecutionTask) => exportExecutionTask(runningExecutionTask, false)) /* <- TODO: satisfies paths['/executions']['get']['responses']['200']['content']['application/json'] */);
|
|
13314
13611
|
});
|
|
13315
|
-
app.get(
|
|
13612
|
+
app.get(`/executions/last`, async (request, response) => {
|
|
13316
13613
|
// TODO: [🤬] Filter only for user
|
|
13317
13614
|
if (runningExecutionTasks.length === 0) {
|
|
13318
13615
|
response.status(404).send('No execution tasks found');
|
|
@@ -13321,7 +13618,7 @@
|
|
|
13321
13618
|
const lastExecutionTask = runningExecutionTasks[runningExecutionTasks.length - 1];
|
|
13322
13619
|
response.send(exportExecutionTask(lastExecutionTask, true));
|
|
13323
13620
|
});
|
|
13324
|
-
app.get(
|
|
13621
|
+
app.get(`/executions/:taskId`, async (request, response) => {
|
|
13325
13622
|
const { taskId } = request.params;
|
|
13326
13623
|
// TODO: [🤬] Filter only for user
|
|
13327
13624
|
const executionTask = runningExecutionTasks.find((executionTask) => executionTask.taskId === taskId);
|
|
@@ -13333,39 +13630,12 @@
|
|
|
13333
13630
|
}
|
|
13334
13631
|
response.send(exportExecutionTask(executionTask, true));
|
|
13335
13632
|
});
|
|
13336
|
-
|
|
13337
|
-
* @swagger
|
|
13338
|
-
* /executions/new:
|
|
13339
|
-
* post:
|
|
13340
|
-
* summary: Start a new execution
|
|
13341
|
-
* description: Starts a new execution task for a given pipeline.
|
|
13342
|
-
* requestBody:
|
|
13343
|
-
* required: true
|
|
13344
|
-
* content:
|
|
13345
|
-
* application/json:
|
|
13346
|
-
* schema:
|
|
13347
|
-
* type: object
|
|
13348
|
-
* properties:
|
|
13349
|
-
* pipelineUrl:
|
|
13350
|
-
* type: string
|
|
13351
|
-
* inputParameters:
|
|
13352
|
-
* type: object
|
|
13353
|
-
* identification:
|
|
13354
|
-
* type: object
|
|
13355
|
-
* responses:
|
|
13356
|
-
* 200:
|
|
13357
|
-
* description: The newly created execution task.
|
|
13358
|
-
* content:
|
|
13359
|
-
* application/json:
|
|
13360
|
-
* schema:
|
|
13361
|
-
* type: object
|
|
13362
|
-
* 400:
|
|
13363
|
-
* description: Invalid input.
|
|
13364
|
-
*/
|
|
13365
|
-
app.post([`/executions/new`, `${rootPath}/executions/new`], async (request, response) => {
|
|
13633
|
+
app.post(`/executions/new`, async (request, response) => {
|
|
13366
13634
|
try {
|
|
13367
13635
|
const { inputParameters, identification /* <- [🤬] */ } = request.body;
|
|
13368
|
-
const pipelineUrl = request.body
|
|
13636
|
+
const pipelineUrl = request.body
|
|
13637
|
+
.pipelineUrl /* <- TODO: as paths['/executions/new']['post']['requestBody']['content']['application/json'] */ ||
|
|
13638
|
+
request.body.book;
|
|
13369
13639
|
// TODO: [🧠] Check `pipelineUrl` and `inputParameters` here or it should be responsibility of `collection.getPipelineByUrl` and `pipelineExecutor`
|
|
13370
13640
|
const pipeline = await (collection === null || collection === void 0 ? void 0 : collection.getPipelineByUrl(pipelineUrl));
|
|
13371
13641
|
if (pipeline === undefined) {
|
|
@@ -13379,7 +13649,7 @@
|
|
|
13379
13649
|
await waitasecond.forTime(10);
|
|
13380
13650
|
// <- Note: Wait for a while to wait for quick responses or sudden but asynchronous errors
|
|
13381
13651
|
// <- TODO: Put this into configuration
|
|
13382
|
-
response.send(executionTask);
|
|
13652
|
+
response.send(executionTask /* <- TODO: satisfies paths['/executions/new']['post']['responses']['200']['content']['application/json'] */);
|
|
13383
13653
|
/*/
|
|
13384
13654
|
executionTask.asObservable().subscribe({
|
|
13385
13655
|
next(partialResult) {
|
|
@@ -13399,19 +13669,24 @@
|
|
|
13399
13669
|
*/
|
|
13400
13670
|
}
|
|
13401
13671
|
catch (error) {
|
|
13402
|
-
|
|
13403
|
-
throw error;
|
|
13404
|
-
}
|
|
13672
|
+
assertsError(error);
|
|
13405
13673
|
response.status(400).send({ error: serializeError(error) });
|
|
13406
13674
|
}
|
|
13407
13675
|
});
|
|
13676
|
+
/**
|
|
13677
|
+
* Catch-all handler for unmatched routes
|
|
13678
|
+
*/
|
|
13679
|
+
app.use((request, response) => {
|
|
13680
|
+
response.status(404).send(`URL "${request.originalUrl}" was not found on Promptbook server.`);
|
|
13681
|
+
});
|
|
13408
13682
|
const httpServer = http__default["default"].createServer(app);
|
|
13409
13683
|
const server = new socket_io.Server(httpServer, {
|
|
13410
|
-
path:
|
|
13411
|
-
transports: [
|
|
13684
|
+
path: '/socket.io',
|
|
13685
|
+
transports: ['polling', 'websocket' /*, <- TODO: [🌬] Allow to pass `transports`, add 'webtransport' */],
|
|
13412
13686
|
cors: {
|
|
13413
13687
|
origin: '*',
|
|
13414
13688
|
methods: ['GET', 'POST'],
|
|
13689
|
+
// <- TODO: [🌡] Allow to pass
|
|
13415
13690
|
},
|
|
13416
13691
|
});
|
|
13417
13692
|
server.on('connection', (socket) => {
|
|
@@ -13465,9 +13740,7 @@
|
|
|
13465
13740
|
socket.emit('prompt-response', { promptResult } /* <- Note: [🤛] */);
|
|
13466
13741
|
}
|
|
13467
13742
|
catch (error) {
|
|
13468
|
-
|
|
13469
|
-
throw error;
|
|
13470
|
-
}
|
|
13743
|
+
assertsError(error);
|
|
13471
13744
|
socket.emit('error', serializeError(error) /* <- Note: [🤛] */);
|
|
13472
13745
|
}
|
|
13473
13746
|
finally {
|
|
@@ -13489,9 +13762,7 @@
|
|
|
13489
13762
|
socket.emit('listModels-response', { models } /* <- Note: [🤛] */);
|
|
13490
13763
|
}
|
|
13491
13764
|
catch (error) {
|
|
13492
|
-
|
|
13493
|
-
throw error;
|
|
13494
|
-
}
|
|
13765
|
+
assertsError(error);
|
|
13495
13766
|
socket.emit('error', serializeError(error));
|
|
13496
13767
|
}
|
|
13497
13768
|
finally {
|
|
@@ -13512,9 +13783,7 @@
|
|
|
13512
13783
|
socket.emit('preparePipeline-response', { preparedPipeline } /* <- Note: [🤛] */);
|
|
13513
13784
|
}
|
|
13514
13785
|
catch (error) {
|
|
13515
|
-
|
|
13516
|
-
throw error;
|
|
13517
|
-
}
|
|
13786
|
+
assertsError(error);
|
|
13518
13787
|
socket.emit('error', serializeError(error));
|
|
13519
13788
|
// <- TODO: [🚋] There is a problem with the remote server handling errors and sending them back to the client
|
|
13520
13789
|
}
|
|
@@ -13562,8 +13831,7 @@
|
|
|
13562
13831
|
};
|
|
13563
13832
|
}
|
|
13564
13833
|
/**
|
|
13565
|
-
* TODO:
|
|
13566
|
-
* TODO: [👩🏾🤝🧑🏾] Allow to pass custom fetch function here - PromptbookFetch
|
|
13834
|
+
* TODO: [🌡] Add CORS and security - probbably via `helmet`
|
|
13567
13835
|
* TODO: Split this file into multiple functions - handler for each request
|
|
13568
13836
|
* TODO: Maybe use `$exportJson`
|
|
13569
13837
|
* TODO: [🧠][🛍] Maybe not `isAnonymous: boolean` BUT `mode: 'ANONYMOUS'|'COLLECTION'`
|
|
@@ -13622,9 +13890,9 @@
|
|
|
13622
13890
|
if (url !== null) {
|
|
13623
13891
|
rootUrl = suffixUrl(url, '/books');
|
|
13624
13892
|
}
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13893
|
+
if (url !== null && url.pathname !== '/' && url.pathname !== '') {
|
|
13894
|
+
console.error(colors__default["default"].red(`URL of the server can not have path, but got "${url.pathname}"`));
|
|
13895
|
+
process.exit(1);
|
|
13628
13896
|
}
|
|
13629
13897
|
// TODO: DRY [◽]
|
|
13630
13898
|
const prepareAndScrapeOptions = {
|
|
@@ -13632,7 +13900,7 @@
|
|
|
13632
13900
|
isCacheReloaded,
|
|
13633
13901
|
}; /* <- TODO: ` satisfies PrepareAndScrapeOptions` */
|
|
13634
13902
|
const fs = $provideFilesystemForNode(prepareAndScrapeOptions);
|
|
13635
|
-
const llm = await $provideLlmToolsForCli({ cliOptions, ...prepareAndScrapeOptions });
|
|
13903
|
+
const { /* [0] strategy,*/ llm } = await $provideLlmToolsForCli({ cliOptions, ...prepareAndScrapeOptions });
|
|
13636
13904
|
const executables = await $provideExecutablesForNode(prepareAndScrapeOptions);
|
|
13637
13905
|
const tools = {
|
|
13638
13906
|
llm,
|
|
@@ -13651,7 +13919,6 @@
|
|
|
13651
13919
|
});
|
|
13652
13920
|
// console.log(path, await collection.listPipelines());
|
|
13653
13921
|
const server = startRemoteServer({
|
|
13654
|
-
rootPath,
|
|
13655
13922
|
port,
|
|
13656
13923
|
isAnonymousModeAllowed,
|
|
13657
13924
|
isApplicationModeAllowed: true,
|
|
@@ -13664,6 +13931,7 @@
|
|
|
13664
13931
|
TODO_USE({ appId, userId });
|
|
13665
13932
|
return llm;
|
|
13666
13933
|
},
|
|
13934
|
+
// <- TODO: [🧠][0] Maybe pass here strategy
|
|
13667
13935
|
});
|
|
13668
13936
|
keepUnused(server);
|
|
13669
13937
|
// Note: Already logged by `startRemoteServer`
|
|
@@ -13705,7 +13973,7 @@
|
|
|
13705
13973
|
isCacheReloaded,
|
|
13706
13974
|
}; /* <- TODO: ` satisfies PrepareAndScrapeOptions` */
|
|
13707
13975
|
const fs = $provideFilesystemForNode(prepareAndScrapeOptions);
|
|
13708
|
-
const llm = await $provideLlmToolsForCli({ cliOptions, ...prepareAndScrapeOptions });
|
|
13976
|
+
const { llm } = await $provideLlmToolsForCli({ cliOptions, ...prepareAndScrapeOptions });
|
|
13709
13977
|
const executables = await $provideExecutablesForNode(prepareAndScrapeOptions);
|
|
13710
13978
|
tools = {
|
|
13711
13979
|
llm,
|
|
@@ -13744,9 +14012,7 @@
|
|
|
13744
14012
|
}
|
|
13745
14013
|
}
|
|
13746
14014
|
catch (error) {
|
|
13747
|
-
|
|
13748
|
-
throw error;
|
|
13749
|
-
}
|
|
14015
|
+
assertsError(error);
|
|
13750
14016
|
console.info(colors__default["default"].red(`Pipeline is not valid ${filename}`));
|
|
13751
14017
|
console.error(colors__default["default"].bgRed(`${error.name} in ${path.basename(__filename)}`));
|
|
13752
14018
|
console.error(colors__default["default"].red(error.stack || error.message));
|
|
@@ -13970,7 +14236,25 @@
|
|
|
13970
14236
|
output: computeUsage(`$2.40 / 1M tokens`),
|
|
13971
14237
|
},
|
|
13972
14238
|
},
|
|
13973
|
-
|
|
14239
|
+
{
|
|
14240
|
+
modelVariant: 'CHAT',
|
|
14241
|
+
modelTitle: 'Claude 3.7 Sonnet',
|
|
14242
|
+
modelName: 'claude-3-7-sonnet-20250219',
|
|
14243
|
+
pricing: {
|
|
14244
|
+
prompt: computeUsage(`$3.00 / 1M tokens`),
|
|
14245
|
+
output: computeUsage(`$15.00 / 1M tokens`),
|
|
14246
|
+
},
|
|
14247
|
+
},
|
|
14248
|
+
{
|
|
14249
|
+
modelVariant: 'CHAT',
|
|
14250
|
+
modelTitle: 'Claude 3.5 Haiku',
|
|
14251
|
+
modelName: 'claude-3-5-haiku-20241022',
|
|
14252
|
+
pricing: {
|
|
14253
|
+
prompt: computeUsage(`$0.25 / 1M tokens`),
|
|
14254
|
+
output: computeUsage(`$1.25 / 1M tokens`),
|
|
14255
|
+
},
|
|
14256
|
+
},
|
|
14257
|
+
// <- [🕕]
|
|
13974
14258
|
],
|
|
13975
14259
|
});
|
|
13976
14260
|
/**
|
|
@@ -14735,7 +15019,6 @@
|
|
|
14735
15019
|
prompt: computeUsage(`$5.00 / 1M tokens`),
|
|
14736
15020
|
output: computeUsage(`$15.00 / 1M tokens`),
|
|
14737
15021
|
},
|
|
14738
|
-
//TODO: [main] !!3 Add gpt-4o-mini-2024-07-18 and all others to be up to date
|
|
14739
15022
|
},
|
|
14740
15023
|
/**/
|
|
14741
15024
|
/**/
|
|
@@ -14750,6 +15033,17 @@
|
|
|
14750
15033
|
},
|
|
14751
15034
|
/**/
|
|
14752
15035
|
/**/
|
|
15036
|
+
{
|
|
15037
|
+
modelVariant: 'CHAT',
|
|
15038
|
+
modelTitle: 'gpt-4o-mini',
|
|
15039
|
+
modelName: 'gpt-4o-mini',
|
|
15040
|
+
pricing: {
|
|
15041
|
+
prompt: computeUsage(`$3.00 / 1M tokens`),
|
|
15042
|
+
output: computeUsage(`$9.00 / 1M tokens`),
|
|
15043
|
+
},
|
|
15044
|
+
},
|
|
15045
|
+
/**/
|
|
15046
|
+
/**/
|
|
14753
15047
|
{
|
|
14754
15048
|
modelVariant: 'CHAT',
|
|
14755
15049
|
modelTitle: 'o1-preview',
|
|
@@ -14829,6 +15123,7 @@
|
|
|
14829
15123
|
},
|
|
14830
15124
|
},
|
|
14831
15125
|
/**/
|
|
15126
|
+
// <- [🕕]
|
|
14832
15127
|
],
|
|
14833
15128
|
});
|
|
14834
15129
|
/**
|
|
@@ -15397,11 +15692,17 @@
|
|
|
15397
15692
|
description: 'Implementation of Deepseek models',
|
|
15398
15693
|
vercelProvider: deepseekVercelProvider,
|
|
15399
15694
|
availableModels: [
|
|
15400
|
-
|
|
15401
|
-
|
|
15402
|
-
|
|
15695
|
+
{
|
|
15696
|
+
modelName: 'deepseek-chat',
|
|
15697
|
+
modelVariant: 'CHAT',
|
|
15698
|
+
},
|
|
15699
|
+
{
|
|
15700
|
+
modelName: 'deepseek-reasoner',
|
|
15701
|
+
modelVariant: 'CHAT',
|
|
15702
|
+
},
|
|
15703
|
+
// <- [🕕]
|
|
15403
15704
|
// <- TODO: How picking of the default model looks like in `createExecutionToolsFromVercelProvider`
|
|
15404
|
-
]
|
|
15705
|
+
],
|
|
15405
15706
|
...options,
|
|
15406
15707
|
});
|
|
15407
15708
|
}, {
|
|
@@ -15499,6 +15800,10 @@
|
|
|
15499
15800
|
vercelProvider: googleGeminiVercelProvider,
|
|
15500
15801
|
availableModels: [
|
|
15501
15802
|
// TODO: [🕘] Maybe list models in same way as in other providers - in separate file with metadata
|
|
15803
|
+
'gemini-2.5-pro-preview-03-25',
|
|
15804
|
+
'gemini-2.0-flash',
|
|
15805
|
+
'gemini-2.0-flash-lite',
|
|
15806
|
+
'gemini-2.0-flash-thinking-exp-01-21',
|
|
15502
15807
|
'gemini-1.5-flash',
|
|
15503
15808
|
'gemini-1.5-flash-latest',
|
|
15504
15809
|
'gemini-1.5-flash-001',
|
|
@@ -15514,6 +15819,7 @@
|
|
|
15514
15819
|
'gemini-1.5-pro-002',
|
|
15515
15820
|
'gemini-1.5-pro-exp-0827',
|
|
15516
15821
|
'gemini-1.0-pro',
|
|
15822
|
+
// <- [🕕]
|
|
15517
15823
|
].map((modelName) => ({ modelName, modelVariant: 'CHAT' })),
|
|
15518
15824
|
...options,
|
|
15519
15825
|
});
|
|
@@ -15793,6 +16099,7 @@
|
|
|
15793
16099
|
console.info(colors__default["default"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
15794
16100
|
}
|
|
15795
16101
|
const rawResponse = await client.chat.completions.create(rawRequest).catch((error) => {
|
|
16102
|
+
assertsError(error);
|
|
15796
16103
|
if (this.options.isVerbose) {
|
|
15797
16104
|
console.info(colors__default["default"].bgRed('error'), error);
|
|
15798
16105
|
}
|
|
@@ -15869,6 +16176,7 @@
|
|
|
15869
16176
|
console.info(colors__default["default"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
15870
16177
|
}
|
|
15871
16178
|
const rawResponse = await client.completions.create(rawRequest).catch((error) => {
|
|
16179
|
+
assertsError(error);
|
|
15872
16180
|
if (this.options.isVerbose) {
|
|
15873
16181
|
console.info(colors__default["default"].bgRed('error'), error);
|
|
15874
16182
|
}
|
|
@@ -15932,6 +16240,7 @@
|
|
|
15932
16240
|
console.info(colors__default["default"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
15933
16241
|
}
|
|
15934
16242
|
const rawResponse = await client.embeddings.create(rawRequest).catch((error) => {
|
|
16243
|
+
assertsError(error);
|
|
15935
16244
|
if (this.options.isVerbose) {
|
|
15936
16245
|
console.info(colors__default["default"].bgRed('error'), error);
|
|
15937
16246
|
}
|