@promptbook/remote-server 0.89.0-9 โ 0.92.0-3
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 -7
- package/esm/index.es.js +555 -426
- 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 +10 -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/filterModels.d.ts +15 -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 +11 -7
- package/umd/index.umd.js +476 -329
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/cli/test/ptbk2.d.ts +0 -5
package/esm/index.es.js
CHANGED
|
@@ -2,8 +2,8 @@ import colors from 'colors';
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import http from 'http';
|
|
4
4
|
import { Server } from 'socket.io';
|
|
5
|
-
import spaceTrim
|
|
6
|
-
import
|
|
5
|
+
import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
|
|
6
|
+
import * as OpenApiValidator from 'express-openapi-validator';
|
|
7
7
|
import swaggerUi from 'swagger-ui-express';
|
|
8
8
|
import { forTime } from 'waitasecond';
|
|
9
9
|
import { randomBytes } from 'crypto';
|
|
@@ -33,7 +33,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
33
33
|
* @generated
|
|
34
34
|
* @see https://github.com/webgptorg/promptbook
|
|
35
35
|
*/
|
|
36
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.
|
|
36
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-3';
|
|
37
37
|
/**
|
|
38
38
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
39
39
|
* Note: [๐] Ignore a discrepancy between file name and entity name
|
|
@@ -87,6 +87,7 @@ const ADMIN_GITHUB_NAME = 'hejny';
|
|
|
87
87
|
* @public exported from `@promptbook/core`
|
|
88
88
|
*/
|
|
89
89
|
const CLAIM = `It's time for a paradigm shift. The future of software in plain English, French or Latin`;
|
|
90
|
+
// <- TODO: [๐] Pick the best claim
|
|
90
91
|
/**
|
|
91
92
|
* When the title is not provided, the default title is used
|
|
92
93
|
*
|
|
@@ -119,6 +120,7 @@ const VALUE_STRINGS = {
|
|
|
119
120
|
infinity: '(infinity; โ)',
|
|
120
121
|
negativeInfinity: '(negative infinity; -โ)',
|
|
121
122
|
unserializable: '(unserializable value)',
|
|
123
|
+
circular: '(circular JSON)',
|
|
122
124
|
};
|
|
123
125
|
/**
|
|
124
126
|
* Small number limit
|
|
@@ -158,7 +160,7 @@ const DEFAULT_MAX_PARALLEL_COUNT = 5; // <- TODO: [๐คนโโ๏ธ]
|
|
|
158
160
|
*/
|
|
159
161
|
const DEFAULT_MAX_EXECUTION_ATTEMPTS = 10; // <- TODO: [๐คนโโ๏ธ]
|
|
160
162
|
// <- TODO: [๐] Make also `BOOKS_DIRNAME_ALTERNATIVES`
|
|
161
|
-
// TODO:
|
|
163
|
+
// TODO: Just `.promptbook` in config, hardcode subfolders like `download-cache` or `execution-cache`
|
|
162
164
|
/**
|
|
163
165
|
* Where to store the temporary downloads
|
|
164
166
|
*
|
|
@@ -213,6 +215,122 @@ true);
|
|
|
213
215
|
* TODO: [๐ง ][๐งโโ๏ธ] Maybe join remoteServerUrl and path into single value
|
|
214
216
|
*/
|
|
215
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Make error report URL for the given error
|
|
220
|
+
*
|
|
221
|
+
* @private private within the repository
|
|
222
|
+
*/
|
|
223
|
+
function getErrorReportUrl(error) {
|
|
224
|
+
const report = {
|
|
225
|
+
title: `๐ Error report from ${NAME}`,
|
|
226
|
+
body: spaceTrim((block) => `
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
\`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
|
|
230
|
+
|
|
231
|
+
\`\`\`
|
|
232
|
+
${block(error.message || '(no error message)')}
|
|
233
|
+
\`\`\`
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
## More info:
|
|
237
|
+
|
|
238
|
+
- **Promptbook engine version:** ${PROMPTBOOK_ENGINE_VERSION}
|
|
239
|
+
- **Book language version:** ${BOOK_LANGUAGE_VERSION}
|
|
240
|
+
- **Time:** ${new Date().toISOString()}
|
|
241
|
+
|
|
242
|
+
<details>
|
|
243
|
+
<summary>Stack trace:</summary>
|
|
244
|
+
|
|
245
|
+
## Stack trace:
|
|
246
|
+
|
|
247
|
+
\`\`\`stacktrace
|
|
248
|
+
${block(error.stack || '(empty)')}
|
|
249
|
+
\`\`\`
|
|
250
|
+
</details>
|
|
251
|
+
|
|
252
|
+
`),
|
|
253
|
+
};
|
|
254
|
+
const reportUrl = new URL(`https://github.com/webgptorg/promptbook/issues/new`);
|
|
255
|
+
reportUrl.searchParams.set('labels', 'bug');
|
|
256
|
+
reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
|
|
257
|
+
reportUrl.searchParams.set('title', report.title);
|
|
258
|
+
reportUrl.searchParams.set('body', report.body);
|
|
259
|
+
return reportUrl;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* This error type indicates that the error should not happen and its last check before crashing with some other error
|
|
264
|
+
*
|
|
265
|
+
* @public exported from `@promptbook/core`
|
|
266
|
+
*/
|
|
267
|
+
class UnexpectedError extends Error {
|
|
268
|
+
constructor(message) {
|
|
269
|
+
super(spaceTrim$1((block) => `
|
|
270
|
+
${block(message)}
|
|
271
|
+
|
|
272
|
+
Note: This error should not happen.
|
|
273
|
+
It's probbably a bug in the pipeline collection
|
|
274
|
+
|
|
275
|
+
Please report issue:
|
|
276
|
+
${block(getErrorReportUrl(new Error(message)).href)}
|
|
277
|
+
|
|
278
|
+
Or contact us on ${ADMIN_EMAIL}
|
|
279
|
+
|
|
280
|
+
`));
|
|
281
|
+
this.name = 'UnexpectedError';
|
|
282
|
+
Object.setPrototypeOf(this, UnexpectedError.prototype);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* This error type indicates that somewhere in the code non-Error object was thrown and it was wrapped into the `WrappedError`
|
|
288
|
+
*
|
|
289
|
+
* @public exported from `@promptbook/core`
|
|
290
|
+
*/
|
|
291
|
+
class WrappedError extends Error {
|
|
292
|
+
constructor(whatWasThrown) {
|
|
293
|
+
const tag = `[๐คฎ]`;
|
|
294
|
+
console.error(tag, whatWasThrown);
|
|
295
|
+
super(spaceTrim$1(`
|
|
296
|
+
Non-Error object was thrown
|
|
297
|
+
|
|
298
|
+
Note: Look for ${tag} in the console for more details
|
|
299
|
+
Please report issue on ${ADMIN_EMAIL}
|
|
300
|
+
`));
|
|
301
|
+
this.name = 'WrappedError';
|
|
302
|
+
Object.setPrototypeOf(this, WrappedError.prototype);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Helper used in catch blocks to assert that the error is an instance of `Error`
|
|
308
|
+
*
|
|
309
|
+
* @param whatWasThrown Any object that was thrown
|
|
310
|
+
* @returns Nothing if the error is an instance of `Error`
|
|
311
|
+
* @throws `WrappedError` or `UnexpectedError` if the error is not standard
|
|
312
|
+
*
|
|
313
|
+
* @private within the repository
|
|
314
|
+
*/
|
|
315
|
+
function assertsError(whatWasThrown) {
|
|
316
|
+
// Case 1: Handle error which was rethrown as `WrappedError`
|
|
317
|
+
if (whatWasThrown instanceof WrappedError) {
|
|
318
|
+
const wrappedError = whatWasThrown;
|
|
319
|
+
throw wrappedError;
|
|
320
|
+
}
|
|
321
|
+
// Case 2: Handle unexpected errors
|
|
322
|
+
if (whatWasThrown instanceof UnexpectedError) {
|
|
323
|
+
const unexpectedError = whatWasThrown;
|
|
324
|
+
throw unexpectedError;
|
|
325
|
+
}
|
|
326
|
+
// Case 3: Handle standard errors - keep them up to consumer
|
|
327
|
+
if (whatWasThrown instanceof Error) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
// Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
|
|
331
|
+
throw new WrappedError(whatWasThrown);
|
|
332
|
+
}
|
|
333
|
+
|
|
216
334
|
/**
|
|
217
335
|
* AuthenticationError is thrown from login function which is dependency of remote server
|
|
218
336
|
*
|
|
@@ -257,7 +375,7 @@ class PipelineExecutionError extends Error {
|
|
|
257
375
|
}
|
|
258
376
|
}
|
|
259
377
|
/**
|
|
260
|
-
* TODO:
|
|
378
|
+
* TODO: [๐ง ][๐] Add id to all errors
|
|
261
379
|
*/
|
|
262
380
|
|
|
263
381
|
/**
|
|
@@ -365,7 +483,7 @@ class LimitReachedError extends Error {
|
|
|
365
483
|
*/
|
|
366
484
|
class MissingToolsError extends Error {
|
|
367
485
|
constructor(message) {
|
|
368
|
-
super(spaceTrim((block) => `
|
|
486
|
+
super(spaceTrim$1((block) => `
|
|
369
487
|
${block(message)}
|
|
370
488
|
|
|
371
489
|
Note: You have probbably forgot to provide some tools for pipeline execution or preparation
|
|
@@ -396,7 +514,7 @@ class NotFoundError extends Error {
|
|
|
396
514
|
*/
|
|
397
515
|
class NotYetImplementedError extends Error {
|
|
398
516
|
constructor(message) {
|
|
399
|
-
super(spaceTrim((block) => `
|
|
517
|
+
super(spaceTrim$1((block) => `
|
|
400
518
|
${block(message)}
|
|
401
519
|
|
|
402
520
|
Note: This feature is not implemented yet but it will be soon.
|
|
@@ -467,74 +585,6 @@ class PromptbookFetchError extends Error {
|
|
|
467
585
|
}
|
|
468
586
|
}
|
|
469
587
|
|
|
470
|
-
/**
|
|
471
|
-
* Make error report URL for the given error
|
|
472
|
-
*
|
|
473
|
-
* @private private within the repository
|
|
474
|
-
*/
|
|
475
|
-
function getErrorReportUrl(error) {
|
|
476
|
-
const report = {
|
|
477
|
-
title: `๐ Error report from ${NAME}`,
|
|
478
|
-
body: spaceTrim$1((block) => `
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
\`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
|
|
482
|
-
|
|
483
|
-
\`\`\`
|
|
484
|
-
${block(error.message || '(no error message)')}
|
|
485
|
-
\`\`\`
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
## More info:
|
|
489
|
-
|
|
490
|
-
- **Promptbook engine version:** ${PROMPTBOOK_ENGINE_VERSION}
|
|
491
|
-
- **Book language version:** ${BOOK_LANGUAGE_VERSION}
|
|
492
|
-
- **Time:** ${new Date().toISOString()}
|
|
493
|
-
|
|
494
|
-
<details>
|
|
495
|
-
<summary>Stack trace:</summary>
|
|
496
|
-
|
|
497
|
-
## Stack trace:
|
|
498
|
-
|
|
499
|
-
\`\`\`stacktrace
|
|
500
|
-
${block(error.stack || '(empty)')}
|
|
501
|
-
\`\`\`
|
|
502
|
-
</details>
|
|
503
|
-
|
|
504
|
-
`),
|
|
505
|
-
};
|
|
506
|
-
const reportUrl = new URL(`https://github.com/webgptorg/promptbook/issues/new`);
|
|
507
|
-
reportUrl.searchParams.set('labels', 'bug');
|
|
508
|
-
reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
|
|
509
|
-
reportUrl.searchParams.set('title', report.title);
|
|
510
|
-
reportUrl.searchParams.set('body', report.body);
|
|
511
|
-
return reportUrl;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* This error type indicates that the error should not happen and its last check before crashing with some other error
|
|
516
|
-
*
|
|
517
|
-
* @public exported from `@promptbook/core`
|
|
518
|
-
*/
|
|
519
|
-
class UnexpectedError extends Error {
|
|
520
|
-
constructor(message) {
|
|
521
|
-
super(spaceTrim((block) => `
|
|
522
|
-
${block(message)}
|
|
523
|
-
|
|
524
|
-
Note: This error should not happen.
|
|
525
|
-
It's probbably a bug in the pipeline collection
|
|
526
|
-
|
|
527
|
-
Please report issue:
|
|
528
|
-
${block(getErrorReportUrl(new Error(message)).href)}
|
|
529
|
-
|
|
530
|
-
Or contact us on ${ADMIN_EMAIL}
|
|
531
|
-
|
|
532
|
-
`));
|
|
533
|
-
this.name = 'UnexpectedError';
|
|
534
|
-
Object.setPrototypeOf(this, UnexpectedError.prototype);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
588
|
/**
|
|
539
589
|
* Index of all custom errors
|
|
540
590
|
*
|
|
@@ -555,7 +605,10 @@ const PROMPTBOOK_ERRORS = {
|
|
|
555
605
|
PipelineExecutionError,
|
|
556
606
|
PipelineLogicError,
|
|
557
607
|
PipelineUrlError,
|
|
608
|
+
AuthenticationError,
|
|
609
|
+
PromptbookFetchError,
|
|
558
610
|
UnexpectedError,
|
|
611
|
+
WrappedError,
|
|
559
612
|
// TODO: [๐ช]> VersionMismatchError,
|
|
560
613
|
};
|
|
561
614
|
/**
|
|
@@ -572,8 +625,6 @@ const COMMON_JAVASCRIPT_ERRORS = {
|
|
|
572
625
|
TypeError,
|
|
573
626
|
URIError,
|
|
574
627
|
AggregateError,
|
|
575
|
-
AuthenticationError,
|
|
576
|
-
PromptbookFetchError,
|
|
577
628
|
/*
|
|
578
629
|
Note: Not widely supported
|
|
579
630
|
> InternalError,
|
|
@@ -605,7 +656,7 @@ function serializeError(error) {
|
|
|
605
656
|
const { name, message, stack } = error;
|
|
606
657
|
const { id } = error;
|
|
607
658
|
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
608
|
-
console.error(spaceTrim
|
|
659
|
+
console.error(spaceTrim((block) => `
|
|
609
660
|
|
|
610
661
|
Cannot serialize error with name "${name}"
|
|
611
662
|
|
|
@@ -769,11 +820,11 @@ function $execCommand(options) {
|
|
|
769
820
|
console.warn(`Command "${humanReadableCommand}" exited with code ${code}`);
|
|
770
821
|
// <- TODO: [๐ฎ] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
771
822
|
}
|
|
772
|
-
resolve(spaceTrim(output.join('\n')));
|
|
823
|
+
resolve(spaceTrim$1(output.join('\n')));
|
|
773
824
|
}
|
|
774
825
|
}
|
|
775
826
|
else {
|
|
776
|
-
resolve(spaceTrim(output.join('\n')));
|
|
827
|
+
resolve(spaceTrim$1(output.join('\n')));
|
|
777
828
|
}
|
|
778
829
|
};
|
|
779
830
|
commandProcess.on('close', finishWithCode);
|
|
@@ -791,7 +842,7 @@ function $execCommand(options) {
|
|
|
791
842
|
console.warn(error);
|
|
792
843
|
// <- TODO: [๐ฎ] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
793
844
|
}
|
|
794
|
-
resolve(spaceTrim(output.join('\n')));
|
|
845
|
+
resolve(spaceTrim$1(output.join('\n')));
|
|
795
846
|
}
|
|
796
847
|
});
|
|
797
848
|
}
|
|
@@ -816,9 +867,7 @@ async function locateAppOnLinux({ linuxWhich, }) {
|
|
|
816
867
|
return result.trim();
|
|
817
868
|
}
|
|
818
869
|
catch (error) {
|
|
819
|
-
|
|
820
|
-
throw error;
|
|
821
|
-
}
|
|
870
|
+
assertsError(error);
|
|
822
871
|
return null;
|
|
823
872
|
}
|
|
824
873
|
}
|
|
@@ -896,9 +945,7 @@ async function locateAppOnMacOs({ macOsName, }) {
|
|
|
896
945
|
return result.trim() + toExec;
|
|
897
946
|
}
|
|
898
947
|
catch (error) {
|
|
899
|
-
|
|
900
|
-
throw error;
|
|
901
|
-
}
|
|
948
|
+
assertsError(error);
|
|
902
949
|
return null;
|
|
903
950
|
}
|
|
904
951
|
}
|
|
@@ -929,9 +976,7 @@ async function locateAppOnWindows({ appName, windowsSuffix, }) {
|
|
|
929
976
|
throw new Error(`Can not locate app ${appName} on Windows.`);
|
|
930
977
|
}
|
|
931
978
|
catch (error) {
|
|
932
|
-
|
|
933
|
-
throw error;
|
|
934
|
-
}
|
|
979
|
+
assertsError(error);
|
|
935
980
|
return null;
|
|
936
981
|
}
|
|
937
982
|
}
|
|
@@ -1128,7 +1173,7 @@ function checkSerializableAsJson(options) {
|
|
|
1128
1173
|
}
|
|
1129
1174
|
else if (typeof value === 'object') {
|
|
1130
1175
|
if (value instanceof Date) {
|
|
1131
|
-
throw new UnexpectedError(spaceTrim
|
|
1176
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
1132
1177
|
\`${name}\` is Date
|
|
1133
1178
|
|
|
1134
1179
|
Use \`string_date_iso8601\` instead
|
|
@@ -1147,7 +1192,7 @@ function checkSerializableAsJson(options) {
|
|
|
1147
1192
|
throw new UnexpectedError(`${name} is RegExp`);
|
|
1148
1193
|
}
|
|
1149
1194
|
else if (value instanceof Error) {
|
|
1150
|
-
throw new UnexpectedError(spaceTrim
|
|
1195
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
1151
1196
|
\`${name}\` is unserialized Error
|
|
1152
1197
|
|
|
1153
1198
|
Use function \`serializeError\`
|
|
@@ -1169,10 +1214,8 @@ function checkSerializableAsJson(options) {
|
|
|
1169
1214
|
JSON.stringify(value); // <- TODO: [0]
|
|
1170
1215
|
}
|
|
1171
1216
|
catch (error) {
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
}
|
|
1175
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1217
|
+
assertsError(error);
|
|
1218
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
1176
1219
|
\`${name}\` is not serializable
|
|
1177
1220
|
|
|
1178
1221
|
${block(error.stack || error.message)}
|
|
@@ -1204,7 +1247,7 @@ function checkSerializableAsJson(options) {
|
|
|
1204
1247
|
}
|
|
1205
1248
|
}
|
|
1206
1249
|
else {
|
|
1207
|
-
throw new UnexpectedError(spaceTrim
|
|
1250
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
1208
1251
|
\`${name}\` is unknown type
|
|
1209
1252
|
|
|
1210
1253
|
Additional message for \`${name}\`:
|
|
@@ -1467,7 +1510,7 @@ function validatePipeline(pipeline) {
|
|
|
1467
1510
|
if (!(error instanceof PipelineLogicError)) {
|
|
1468
1511
|
throw error;
|
|
1469
1512
|
}
|
|
1470
|
-
console.error(spaceTrim((block) => `
|
|
1513
|
+
console.error(spaceTrim$1((block) => `
|
|
1471
1514
|
Pipeline is not valid but logic errors are temporarily disabled via \`IS_PIPELINE_LOGIC_VALIDATED\`
|
|
1472
1515
|
|
|
1473
1516
|
${block(error.message)}
|
|
@@ -1494,7 +1537,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1494
1537
|
})();
|
|
1495
1538
|
if (pipeline.pipelineUrl !== undefined && !isValidPipelineUrl(pipeline.pipelineUrl)) {
|
|
1496
1539
|
// <- Note: [๐ฒ]
|
|
1497
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1540
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1498
1541
|
Invalid promptbook URL "${pipeline.pipelineUrl}"
|
|
1499
1542
|
|
|
1500
1543
|
${block(pipelineIdentification)}
|
|
@@ -1502,7 +1545,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1502
1545
|
}
|
|
1503
1546
|
if (pipeline.bookVersion !== undefined && !isValidPromptbookVersion(pipeline.bookVersion)) {
|
|
1504
1547
|
// <- Note: [๐ฒ]
|
|
1505
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1548
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1506
1549
|
Invalid Promptbook Version "${pipeline.bookVersion}"
|
|
1507
1550
|
|
|
1508
1551
|
${block(pipelineIdentification)}
|
|
@@ -1511,7 +1554,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1511
1554
|
// TODO: [๐ง ] Maybe do here some propper JSON-schema / ZOD checking
|
|
1512
1555
|
if (!Array.isArray(pipeline.parameters)) {
|
|
1513
1556
|
// TODO: [๐ง ] what is the correct error tp throw - maybe PromptbookSchemaError
|
|
1514
|
-
throw new ParseError(spaceTrim((block) => `
|
|
1557
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
1515
1558
|
Pipeline is valid JSON but with wrong structure
|
|
1516
1559
|
|
|
1517
1560
|
\`PipelineJson.parameters\` expected to be an array, but got ${typeof pipeline.parameters}
|
|
@@ -1522,7 +1565,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1522
1565
|
// TODO: [๐ง ] Maybe do here some propper JSON-schema / ZOD checking
|
|
1523
1566
|
if (!Array.isArray(pipeline.tasks)) {
|
|
1524
1567
|
// TODO: [๐ง ] what is the correct error tp throw - maybe PromptbookSchemaError
|
|
1525
|
-
throw new ParseError(spaceTrim((block) => `
|
|
1568
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
1526
1569
|
Pipeline is valid JSON but with wrong structure
|
|
1527
1570
|
|
|
1528
1571
|
\`PipelineJson.tasks\` expected to be an array, but got ${typeof pipeline.tasks}
|
|
@@ -1548,7 +1591,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1548
1591
|
// Note: Check each parameter individually
|
|
1549
1592
|
for (const parameter of pipeline.parameters) {
|
|
1550
1593
|
if (parameter.isInput && parameter.isOutput) {
|
|
1551
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1594
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1552
1595
|
|
|
1553
1596
|
Parameter \`{${parameter.name}}\` can not be both input and output
|
|
1554
1597
|
|
|
@@ -1559,7 +1602,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1559
1602
|
if (!parameter.isInput &&
|
|
1560
1603
|
!parameter.isOutput &&
|
|
1561
1604
|
!pipeline.tasks.some((task) => task.dependentParameterNames.includes(parameter.name))) {
|
|
1562
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1605
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1563
1606
|
Parameter \`{${parameter.name}}\` is created but not used
|
|
1564
1607
|
|
|
1565
1608
|
You can declare {${parameter.name}} as output parameter by adding in the header:
|
|
@@ -1571,7 +1614,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1571
1614
|
}
|
|
1572
1615
|
// Note: Testing that parameter is either input or result of some task
|
|
1573
1616
|
if (!parameter.isInput && !pipeline.tasks.some((task) => task.resultingParameterName === parameter.name)) {
|
|
1574
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1617
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1575
1618
|
Parameter \`{${parameter.name}}\` is declared but not defined
|
|
1576
1619
|
|
|
1577
1620
|
You can do one of these:
|
|
@@ -1587,14 +1630,14 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1587
1630
|
// Note: Checking each task individually
|
|
1588
1631
|
for (const task of pipeline.tasks) {
|
|
1589
1632
|
if (definedParameters.has(task.resultingParameterName)) {
|
|
1590
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1633
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1591
1634
|
Parameter \`{${task.resultingParameterName}}\` is defined multiple times
|
|
1592
1635
|
|
|
1593
1636
|
${block(pipelineIdentification)}
|
|
1594
1637
|
`));
|
|
1595
1638
|
}
|
|
1596
1639
|
if (RESERVED_PARAMETER_NAMES.includes(task.resultingParameterName)) {
|
|
1597
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1640
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1598
1641
|
Parameter name {${task.resultingParameterName}} is reserved, please use different name
|
|
1599
1642
|
|
|
1600
1643
|
${block(pipelineIdentification)}
|
|
@@ -1604,7 +1647,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1604
1647
|
if (task.jokerParameterNames && task.jokerParameterNames.length > 0) {
|
|
1605
1648
|
if (!task.format &&
|
|
1606
1649
|
!task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
|
|
1607
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1650
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1608
1651
|
Joker parameters are used for {${task.resultingParameterName}} but no expectations are defined
|
|
1609
1652
|
|
|
1610
1653
|
${block(pipelineIdentification)}
|
|
@@ -1612,7 +1655,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1612
1655
|
}
|
|
1613
1656
|
for (const joker of task.jokerParameterNames) {
|
|
1614
1657
|
if (!task.dependentParameterNames.includes(joker)) {
|
|
1615
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1658
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1616
1659
|
Parameter \`{${joker}}\` is used for {${task.resultingParameterName}} as joker but not in \`dependentParameterNames\`
|
|
1617
1660
|
|
|
1618
1661
|
${block(pipelineIdentification)}
|
|
@@ -1623,21 +1666,21 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1623
1666
|
if (task.expectations) {
|
|
1624
1667
|
for (const [unit, { min, max }] of Object.entries(task.expectations)) {
|
|
1625
1668
|
if (min !== undefined && max !== undefined && min > max) {
|
|
1626
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1669
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1627
1670
|
Min expectation (=${min}) of ${unit} is higher than max expectation (=${max})
|
|
1628
1671
|
|
|
1629
1672
|
${block(pipelineIdentification)}
|
|
1630
1673
|
`));
|
|
1631
1674
|
}
|
|
1632
1675
|
if (min !== undefined && min < 0) {
|
|
1633
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1676
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1634
1677
|
Min expectation of ${unit} must be zero or positive
|
|
1635
1678
|
|
|
1636
1679
|
${block(pipelineIdentification)}
|
|
1637
1680
|
`));
|
|
1638
1681
|
}
|
|
1639
1682
|
if (max !== undefined && max <= 0) {
|
|
1640
|
-
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1683
|
+
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
1641
1684
|
Max expectation of ${unit} must be positive
|
|
1642
1685
|
|
|
1643
1686
|
${block(pipelineIdentification)}
|
|
@@ -1659,7 +1702,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1659
1702
|
while (unresovedTasks.length > 0) {
|
|
1660
1703
|
if (loopLimit-- < 0) {
|
|
1661
1704
|
// Note: Really UnexpectedError not LimitReachedError - this should not happen and be caught below
|
|
1662
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
1705
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1663
1706
|
Loop limit reached during detection of circular dependencies in \`validatePipeline\`
|
|
1664
1707
|
|
|
1665
1708
|
${block(pipelineIdentification)}
|
|
@@ -1669,7 +1712,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1669
1712
|
if (currentlyResovedTasks.length === 0) {
|
|
1670
1713
|
throw new PipelineLogicError(
|
|
1671
1714
|
// TODO: [๐] DRY
|
|
1672
|
-
spaceTrim((block) => `
|
|
1715
|
+
spaceTrim$1((block) => `
|
|
1673
1716
|
|
|
1674
1717
|
Can not resolve some parameters:
|
|
1675
1718
|
Either you are using a parameter that is not defined, or there are some circular dependencies.
|
|
@@ -1771,6 +1814,9 @@ function isPipelinePrepared(pipeline) {
|
|
|
1771
1814
|
/**
|
|
1772
1815
|
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
1773
1816
|
*
|
|
1817
|
+
* @param value The string to check
|
|
1818
|
+
* @returns True if the string is a valid JSON string, false otherwise
|
|
1819
|
+
*
|
|
1774
1820
|
* @public exported from `@promptbook/utils`
|
|
1775
1821
|
*/
|
|
1776
1822
|
function isValidJsonString(value /* <- [๐จโโ๏ธ] */) {
|
|
@@ -1779,9 +1825,7 @@ function isValidJsonString(value /* <- [๐จโโ๏ธ] */) {
|
|
|
1779
1825
|
return true;
|
|
1780
1826
|
}
|
|
1781
1827
|
catch (error) {
|
|
1782
|
-
|
|
1783
|
-
throw error;
|
|
1784
|
-
}
|
|
1828
|
+
assertsError(error);
|
|
1785
1829
|
if (error.message.includes('Unexpected token')) {
|
|
1786
1830
|
return false;
|
|
1787
1831
|
}
|
|
@@ -1833,7 +1877,7 @@ function deserializeError(error) {
|
|
|
1833
1877
|
message = `${name}: ${message}`;
|
|
1834
1878
|
}
|
|
1835
1879
|
if (stack !== undefined && stack !== '') {
|
|
1836
|
-
message = spaceTrim
|
|
1880
|
+
message = spaceTrim((block) => `
|
|
1837
1881
|
${block(message)}
|
|
1838
1882
|
|
|
1839
1883
|
Original stack trace:
|
|
@@ -1870,11 +1914,11 @@ function assertsTaskSuccessful(executionResult) {
|
|
|
1870
1914
|
throw deserializeError(errors[0]);
|
|
1871
1915
|
}
|
|
1872
1916
|
else {
|
|
1873
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
1917
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
1874
1918
|
Multiple errors occurred during Promptbook execution
|
|
1875
1919
|
|
|
1876
1920
|
${block(errors
|
|
1877
|
-
.map(({ name, stack, message }, index) => spaceTrim((block) => `
|
|
1921
|
+
.map(({ name, stack, message }, index) => spaceTrim$1((block) => `
|
|
1878
1922
|
${name} ${index + 1}:
|
|
1879
1923
|
${block(stack || message)}
|
|
1880
1924
|
`))
|
|
@@ -1919,8 +1963,8 @@ function createTask(options) {
|
|
|
1919
1963
|
updatedAt = new Date();
|
|
1920
1964
|
errors.push(...executionResult.errors);
|
|
1921
1965
|
warnings.push(...executionResult.warnings);
|
|
1922
|
-
// <- TODO:
|
|
1923
|
-
// TODO: [๐ง ]
|
|
1966
|
+
// <- TODO: [๐] Only unique errors and warnings should be added (or filtered)
|
|
1967
|
+
// TODO: [๐ง ] !! errors, warning, isSuccessful are redundant both in `ExecutionTask` and `ExecutionTask.currentValue`
|
|
1924
1968
|
// Also maybe move `ExecutionTask.currentValue.usage` -> `ExecutionTask.usage`
|
|
1925
1969
|
// And delete `ExecutionTask.currentValue.preparedPipeline`
|
|
1926
1970
|
assertsTaskSuccessful(executionResult);
|
|
@@ -1930,6 +1974,7 @@ function createTask(options) {
|
|
|
1930
1974
|
partialResultSubject.next(executionResult);
|
|
1931
1975
|
}
|
|
1932
1976
|
catch (error) {
|
|
1977
|
+
assertsError(error);
|
|
1933
1978
|
status = 'ERROR';
|
|
1934
1979
|
errors.push(error);
|
|
1935
1980
|
partialResultSubject.error(error);
|
|
@@ -2232,7 +2277,7 @@ function pipelineJsonToString(pipelineJson) {
|
|
|
2232
2277
|
pipelineString += '\n\n';
|
|
2233
2278
|
pipelineString += '```' + contentLanguage;
|
|
2234
2279
|
pipelineString += '\n';
|
|
2235
|
-
pipelineString += spaceTrim
|
|
2280
|
+
pipelineString += spaceTrim(content);
|
|
2236
2281
|
// <- TODO: [main] !!3 Escape
|
|
2237
2282
|
// <- TODO: [๐ง ] Some clear strategy how to spaceTrim the blocks
|
|
2238
2283
|
pipelineString += '\n';
|
|
@@ -2337,7 +2382,7 @@ class SimplePipelineCollection {
|
|
|
2337
2382
|
for (const pipeline of pipelines) {
|
|
2338
2383
|
// TODO: [๐ ] DRY
|
|
2339
2384
|
if (pipeline.pipelineUrl === undefined) {
|
|
2340
|
-
throw new PipelineUrlError(spaceTrim(`
|
|
2385
|
+
throw new PipelineUrlError(spaceTrim$1(`
|
|
2341
2386
|
Pipeline with name "${pipeline.title}" does not have defined URL
|
|
2342
2387
|
|
|
2343
2388
|
File:
|
|
@@ -2359,7 +2404,7 @@ class SimplePipelineCollection {
|
|
|
2359
2404
|
pipelineJsonToString(unpreparePipeline(pipeline)) !==
|
|
2360
2405
|
pipelineJsonToString(unpreparePipeline(this.collection.get(pipeline.pipelineUrl)))) {
|
|
2361
2406
|
const existing = this.collection.get(pipeline.pipelineUrl);
|
|
2362
|
-
throw new PipelineUrlError(spaceTrim(`
|
|
2407
|
+
throw new PipelineUrlError(spaceTrim$1(`
|
|
2363
2408
|
Pipeline with URL ${pipeline.pipelineUrl} is already in the collection ๐
|
|
2364
2409
|
|
|
2365
2410
|
Conflicting files:
|
|
@@ -2391,13 +2436,13 @@ class SimplePipelineCollection {
|
|
|
2391
2436
|
const pipeline = this.collection.get(url);
|
|
2392
2437
|
if (!pipeline) {
|
|
2393
2438
|
if (this.listPipelines().length === 0) {
|
|
2394
|
-
throw new NotFoundError(spaceTrim(`
|
|
2439
|
+
throw new NotFoundError(spaceTrim$1(`
|
|
2395
2440
|
Pipeline with url "${url}" not found
|
|
2396
2441
|
|
|
2397
2442
|
No pipelines available
|
|
2398
2443
|
`));
|
|
2399
2444
|
}
|
|
2400
|
-
throw new NotFoundError(spaceTrim((block) => `
|
|
2445
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
2401
2446
|
Pipeline with url "${url}" not found
|
|
2402
2447
|
|
|
2403
2448
|
Available pipelines:
|
|
@@ -2740,14 +2785,15 @@ class MultipleLlmExecutionTools {
|
|
|
2740
2785
|
}
|
|
2741
2786
|
}
|
|
2742
2787
|
catch (error) {
|
|
2743
|
-
|
|
2788
|
+
assertsError(error);
|
|
2789
|
+
if (error instanceof UnexpectedError) {
|
|
2744
2790
|
throw error;
|
|
2745
2791
|
}
|
|
2746
2792
|
errors.push({ llmExecutionTools, error });
|
|
2747
2793
|
}
|
|
2748
2794
|
}
|
|
2749
2795
|
if (errors.length === 1) {
|
|
2750
|
-
throw errors[0];
|
|
2796
|
+
throw errors[0].error;
|
|
2751
2797
|
}
|
|
2752
2798
|
else if (errors.length > 1) {
|
|
2753
2799
|
throw new PipelineExecutionError(
|
|
@@ -2755,7 +2801,7 @@ class MultipleLlmExecutionTools {
|
|
|
2755
2801
|
// 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
2756
2802
|
// 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
2757
2803
|
// 3) ...
|
|
2758
|
-
spaceTrim
|
|
2804
|
+
spaceTrim((block) => `
|
|
2759
2805
|
All execution tools failed:
|
|
2760
2806
|
|
|
2761
2807
|
${block(errors
|
|
@@ -2768,7 +2814,7 @@ class MultipleLlmExecutionTools {
|
|
|
2768
2814
|
throw new PipelineExecutionError(`You have not provided any \`LlmExecutionTools\``);
|
|
2769
2815
|
}
|
|
2770
2816
|
else {
|
|
2771
|
-
throw new PipelineExecutionError(spaceTrim
|
|
2817
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
2772
2818
|
You have not provided any \`LlmExecutionTools\` that support model variant "${prompt.modelRequirements.modelVariant}"
|
|
2773
2819
|
|
|
2774
2820
|
Available \`LlmExecutionTools\`:
|
|
@@ -2801,7 +2847,7 @@ class MultipleLlmExecutionTools {
|
|
|
2801
2847
|
*/
|
|
2802
2848
|
function joinLlmExecutionTools(...llmExecutionTools) {
|
|
2803
2849
|
if (llmExecutionTools.length === 0) {
|
|
2804
|
-
const warningMessage = spaceTrim
|
|
2850
|
+
const warningMessage = spaceTrim(`
|
|
2805
2851
|
You have not provided any \`LlmExecutionTools\`
|
|
2806
2852
|
This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.
|
|
2807
2853
|
|
|
@@ -3092,14 +3138,14 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
3092
3138
|
return { ...metadata, isMetadataAviailable, isInstalled, isAvilableInTools };
|
|
3093
3139
|
});
|
|
3094
3140
|
if (metadata.length === 0) {
|
|
3095
|
-
return spaceTrim
|
|
3141
|
+
return spaceTrim(`
|
|
3096
3142
|
**No scrapers are available**
|
|
3097
3143
|
|
|
3098
3144
|
This is a unexpected behavior, you are probably using some broken version of Promptbook
|
|
3099
3145
|
At least there should be available the metadata of the scrapers
|
|
3100
3146
|
`);
|
|
3101
3147
|
}
|
|
3102
|
-
return spaceTrim
|
|
3148
|
+
return spaceTrim((block) => `
|
|
3103
3149
|
Available scrapers are:
|
|
3104
3150
|
${block(metadata
|
|
3105
3151
|
.map(({ packageName, className, isMetadataAviailable, isInstalled, mimeTypes, isAvilableInBrowser, isAvilableInTools, }, i) => {
|
|
@@ -3588,9 +3634,7 @@ const promptbookFetch = async (urlOrRequest, init) => {
|
|
|
3588
3634
|
return await fetch(urlOrRequest, init);
|
|
3589
3635
|
}
|
|
3590
3636
|
catch (error) {
|
|
3591
|
-
|
|
3592
|
-
throw error;
|
|
3593
|
-
}
|
|
3637
|
+
assertsError(error);
|
|
3594
3638
|
let url;
|
|
3595
3639
|
if (typeof urlOrRequest === 'string') {
|
|
3596
3640
|
url = urlOrRequest;
|
|
@@ -3598,7 +3642,7 @@ const promptbookFetch = async (urlOrRequest, init) => {
|
|
|
3598
3642
|
else if (urlOrRequest instanceof Request) {
|
|
3599
3643
|
url = urlOrRequest.url;
|
|
3600
3644
|
}
|
|
3601
|
-
throw new PromptbookFetchError(spaceTrim
|
|
3645
|
+
throw new PromptbookFetchError(spaceTrim((block) => `
|
|
3602
3646
|
Can not fetch "${url}"
|
|
3603
3647
|
|
|
3604
3648
|
Fetch error:
|
|
@@ -3689,7 +3733,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
|
|
|
3689
3733
|
const fileExtension = getFileExtension(filename);
|
|
3690
3734
|
const mimeType = extensionToMimeType(fileExtension || '');
|
|
3691
3735
|
if (!(await isFileExisting(filename, tools.fs))) {
|
|
3692
|
-
throw new NotFoundError(spaceTrim
|
|
3736
|
+
throw new NotFoundError(spaceTrim((block) => `
|
|
3693
3737
|
Can not make source handler for file which does not exist:
|
|
3694
3738
|
|
|
3695
3739
|
File:
|
|
@@ -3776,7 +3820,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
3776
3820
|
// <- TODO: [๐ช] Here should be no need for spreading new array, just `partialPieces = partialPiecesUnchecked`
|
|
3777
3821
|
break;
|
|
3778
3822
|
}
|
|
3779
|
-
console.warn(spaceTrim
|
|
3823
|
+
console.warn(spaceTrim((block) => `
|
|
3780
3824
|
Cannot scrape knowledge from source despite the scraper \`${scraper.metadata.className}\` supports the mime type "${sourceHandler.mimeType}".
|
|
3781
3825
|
|
|
3782
3826
|
The source:
|
|
@@ -3792,7 +3836,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
3792
3836
|
// <- TODO: [๐ฎ] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
3793
3837
|
}
|
|
3794
3838
|
if (partialPieces === null) {
|
|
3795
|
-
throw new KnowledgeScrapeError(spaceTrim
|
|
3839
|
+
throw new KnowledgeScrapeError(spaceTrim((block) => `
|
|
3796
3840
|
Cannot scrape knowledge
|
|
3797
3841
|
|
|
3798
3842
|
The source:
|
|
@@ -3821,9 +3865,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
3821
3865
|
knowledgePreparedUnflatten[index] = pieces;
|
|
3822
3866
|
}
|
|
3823
3867
|
catch (error) {
|
|
3824
|
-
|
|
3825
|
-
throw error;
|
|
3826
|
-
}
|
|
3868
|
+
assertsError(error);
|
|
3827
3869
|
console.warn(error);
|
|
3828
3870
|
// <- TODO: [๐ฎ] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
3829
3871
|
}
|
|
@@ -3870,7 +3912,7 @@ async function prepareTasks(pipeline, tools, options) {
|
|
|
3870
3912
|
if (task.taskType === 'PROMPT_TASK' &&
|
|
3871
3913
|
knowledgePiecesCount > 0 &&
|
|
3872
3914
|
!dependentParameterNames.includes('knowledge')) {
|
|
3873
|
-
preparedContent = spaceTrim(`
|
|
3915
|
+
preparedContent = spaceTrim$1(`
|
|
3874
3916
|
{content}
|
|
3875
3917
|
|
|
3876
3918
|
## Knowledge
|
|
@@ -4115,13 +4157,19 @@ function valueToString(value) {
|
|
|
4115
4157
|
return value.toISOString();
|
|
4116
4158
|
}
|
|
4117
4159
|
else {
|
|
4118
|
-
|
|
4160
|
+
try {
|
|
4161
|
+
return JSON.stringify(value);
|
|
4162
|
+
}
|
|
4163
|
+
catch (error) {
|
|
4164
|
+
if (error instanceof TypeError && error.message.includes('circular structure')) {
|
|
4165
|
+
return VALUE_STRINGS.circular;
|
|
4166
|
+
}
|
|
4167
|
+
throw error;
|
|
4168
|
+
}
|
|
4119
4169
|
}
|
|
4120
4170
|
}
|
|
4121
4171
|
catch (error) {
|
|
4122
|
-
|
|
4123
|
-
throw error;
|
|
4124
|
-
}
|
|
4172
|
+
assertsError(error);
|
|
4125
4173
|
console.error(error);
|
|
4126
4174
|
return VALUE_STRINGS.unserializable;
|
|
4127
4175
|
}
|
|
@@ -4178,10 +4226,8 @@ function extractVariablesFromJavascript(script) {
|
|
|
4178
4226
|
}
|
|
4179
4227
|
}
|
|
4180
4228
|
catch (error) {
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
}
|
|
4184
|
-
throw new ParseError(spaceTrim((block) => `
|
|
4229
|
+
assertsError(error);
|
|
4230
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
4185
4231
|
Can not extract variables from the script
|
|
4186
4232
|
${block(error.stack || error.message)}
|
|
4187
4233
|
|
|
@@ -4299,6 +4345,28 @@ const MANDATORY_CSV_SETTINGS = Object.freeze({
|
|
|
4299
4345
|
// encoding: 'utf-8',
|
|
4300
4346
|
});
|
|
4301
4347
|
|
|
4348
|
+
/**
|
|
4349
|
+
* Function to check if a string is valid CSV
|
|
4350
|
+
*
|
|
4351
|
+
* @param value The string to check
|
|
4352
|
+
* @returns True if the string is a valid CSV string, false otherwise
|
|
4353
|
+
*
|
|
4354
|
+
* @public exported from `@promptbook/utils`
|
|
4355
|
+
*/
|
|
4356
|
+
function isValidCsvString(value) {
|
|
4357
|
+
try {
|
|
4358
|
+
// A simple check for CSV format: at least one comma and no invalid characters
|
|
4359
|
+
if (value.includes(',') && /^[\w\s,"']+$/.test(value)) {
|
|
4360
|
+
return true;
|
|
4361
|
+
}
|
|
4362
|
+
return false;
|
|
4363
|
+
}
|
|
4364
|
+
catch (error) {
|
|
4365
|
+
assertsError(error);
|
|
4366
|
+
return false;
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
|
|
4302
4370
|
/**
|
|
4303
4371
|
* Definition for CSV spreadsheet
|
|
4304
4372
|
*
|
|
@@ -4309,7 +4377,7 @@ const CsvFormatDefinition = {
|
|
|
4309
4377
|
formatName: 'CSV',
|
|
4310
4378
|
aliases: ['SPREADSHEET', 'TABLE'],
|
|
4311
4379
|
isValid(value, settings, schema) {
|
|
4312
|
-
return
|
|
4380
|
+
return isValidCsvString(value);
|
|
4313
4381
|
},
|
|
4314
4382
|
canBeValid(partialValue, settings, schema) {
|
|
4315
4383
|
return true;
|
|
@@ -4324,7 +4392,7 @@ const CsvFormatDefinition = {
|
|
|
4324
4392
|
// TODO: [๐จ๐พโ๐คโ๐จ๐ผ] DRY csv parsing
|
|
4325
4393
|
const csv = parse(value, { ...settings, ...MANDATORY_CSV_SETTINGS });
|
|
4326
4394
|
if (csv.errors.length !== 0) {
|
|
4327
|
-
throw new CsvFormatError(spaceTrim
|
|
4395
|
+
throw new CsvFormatError(spaceTrim((block) => `
|
|
4328
4396
|
CSV parsing error
|
|
4329
4397
|
|
|
4330
4398
|
Error(s) from CSV parsing:
|
|
@@ -4355,7 +4423,7 @@ const CsvFormatDefinition = {
|
|
|
4355
4423
|
// TODO: [๐จ๐พโ๐คโ๐จ๐ผ] DRY csv parsing
|
|
4356
4424
|
const csv = parse(value, { ...settings, ...MANDATORY_CSV_SETTINGS });
|
|
4357
4425
|
if (csv.errors.length !== 0) {
|
|
4358
|
-
throw new CsvFormatError(spaceTrim
|
|
4426
|
+
throw new CsvFormatError(spaceTrim((block) => `
|
|
4359
4427
|
CSV parsing error
|
|
4360
4428
|
|
|
4361
4429
|
Error(s) from CSV parsing:
|
|
@@ -4463,6 +4531,30 @@ const TextFormatDefinition = {
|
|
|
4463
4531
|
* TODO: [๐ข] Allow to expect something inside each item of list and other formats
|
|
4464
4532
|
*/
|
|
4465
4533
|
|
|
4534
|
+
/**
|
|
4535
|
+
* Function to check if a string is valid XML
|
|
4536
|
+
*
|
|
4537
|
+
* @param value
|
|
4538
|
+
* @returns True if the string is a valid XML string, false otherwise
|
|
4539
|
+
*
|
|
4540
|
+
* @public exported from `@promptbook/utils`
|
|
4541
|
+
*/
|
|
4542
|
+
function isValidXmlString(value) {
|
|
4543
|
+
try {
|
|
4544
|
+
const parser = new DOMParser();
|
|
4545
|
+
const parsedDocument = parser.parseFromString(value, 'application/xml');
|
|
4546
|
+
const parserError = parsedDocument.getElementsByTagName('parsererror');
|
|
4547
|
+
if (parserError.length > 0) {
|
|
4548
|
+
return false;
|
|
4549
|
+
}
|
|
4550
|
+
return true;
|
|
4551
|
+
}
|
|
4552
|
+
catch (error) {
|
|
4553
|
+
assertsError(error);
|
|
4554
|
+
return false;
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
|
|
4466
4558
|
/**
|
|
4467
4559
|
* Definition for XML format
|
|
4468
4560
|
*
|
|
@@ -4472,7 +4564,7 @@ const XmlFormatDefinition = {
|
|
|
4472
4564
|
formatName: 'XML',
|
|
4473
4565
|
mimeType: 'application/xml',
|
|
4474
4566
|
isValid(value, settings, schema) {
|
|
4475
|
-
return
|
|
4567
|
+
return isValidXmlString(value);
|
|
4476
4568
|
},
|
|
4477
4569
|
canBeValid(partialValue, settings, schema) {
|
|
4478
4570
|
return true;
|
|
@@ -4545,7 +4637,7 @@ function mapAvailableToExpectedParameters(options) {
|
|
|
4545
4637
|
}
|
|
4546
4638
|
// Phase 2๏ธโฃ: Non-matching mapping
|
|
4547
4639
|
if (expectedParameterNames.size !== availableParametersNames.size) {
|
|
4548
|
-
throw new PipelineExecutionError(spaceTrim
|
|
4640
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4549
4641
|
Can not map available parameters to expected parameters
|
|
4550
4642
|
|
|
4551
4643
|
Mapped parameters:
|
|
@@ -4947,7 +5039,7 @@ async function executeAttempts(options) {
|
|
|
4947
5039
|
const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
|
|
4948
5040
|
// TODO: [๐ง ][๐ญ] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
|
|
4949
5041
|
if (isJokerAttempt && !jokerParameterName) {
|
|
4950
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5042
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
4951
5043
|
Joker not found in attempt ${attempt}
|
|
4952
5044
|
|
|
4953
5045
|
${block(pipelineIdentification)}
|
|
@@ -4958,7 +5050,7 @@ async function executeAttempts(options) {
|
|
|
4958
5050
|
$ongoingTaskResult.$expectError = null;
|
|
4959
5051
|
if (isJokerAttempt) {
|
|
4960
5052
|
if (parameters[jokerParameterName] === undefined) {
|
|
4961
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5053
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
4962
5054
|
Joker parameter {${jokerParameterName}} not defined
|
|
4963
5055
|
|
|
4964
5056
|
${block(pipelineIdentification)}
|
|
@@ -5016,7 +5108,7 @@ async function executeAttempts(options) {
|
|
|
5016
5108
|
$ongoingTaskResult.$resultString = $ongoingTaskResult.$completionResult.content;
|
|
5017
5109
|
break variant;
|
|
5018
5110
|
case 'EMBEDDING':
|
|
5019
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5111
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5020
5112
|
Embedding model can not be used in pipeline
|
|
5021
5113
|
|
|
5022
5114
|
This should be catched during parsing
|
|
@@ -5027,7 +5119,7 @@ async function executeAttempts(options) {
|
|
|
5027
5119
|
break variant;
|
|
5028
5120
|
// <- case [๐ค]:
|
|
5029
5121
|
default:
|
|
5030
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5122
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5031
5123
|
Unknown model variant "${task.modelRequirements.modelVariant}"
|
|
5032
5124
|
|
|
5033
5125
|
${block(pipelineIdentification)}
|
|
@@ -5038,14 +5130,14 @@ async function executeAttempts(options) {
|
|
|
5038
5130
|
break;
|
|
5039
5131
|
case 'SCRIPT_TASK':
|
|
5040
5132
|
if (arrayableToArray(tools.script).length === 0) {
|
|
5041
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5133
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5042
5134
|
No script execution tools are available
|
|
5043
5135
|
|
|
5044
5136
|
${block(pipelineIdentification)}
|
|
5045
5137
|
`));
|
|
5046
5138
|
}
|
|
5047
5139
|
if (!task.contentLanguage) {
|
|
5048
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5140
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5049
5141
|
Script language is not defined for SCRIPT TASK "${task.name}"
|
|
5050
5142
|
|
|
5051
5143
|
${block(pipelineIdentification)}
|
|
@@ -5062,9 +5154,7 @@ async function executeAttempts(options) {
|
|
|
5062
5154
|
break scripts;
|
|
5063
5155
|
}
|
|
5064
5156
|
catch (error) {
|
|
5065
|
-
|
|
5066
|
-
throw error;
|
|
5067
|
-
}
|
|
5157
|
+
assertsError(error);
|
|
5068
5158
|
if (error instanceof UnexpectedError) {
|
|
5069
5159
|
throw error;
|
|
5070
5160
|
}
|
|
@@ -5078,7 +5168,7 @@ async function executeAttempts(options) {
|
|
|
5078
5168
|
throw $ongoingTaskResult.$scriptPipelineExecutionErrors[0];
|
|
5079
5169
|
}
|
|
5080
5170
|
else {
|
|
5081
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5171
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5082
5172
|
Script execution failed ${$ongoingTaskResult.$scriptPipelineExecutionErrors.length}x
|
|
5083
5173
|
|
|
5084
5174
|
${block(pipelineIdentification)}
|
|
@@ -5092,7 +5182,7 @@ async function executeAttempts(options) {
|
|
|
5092
5182
|
break taskType;
|
|
5093
5183
|
case 'DIALOG_TASK':
|
|
5094
5184
|
if (tools.userInterface === undefined) {
|
|
5095
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5185
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5096
5186
|
User interface tools are not available
|
|
5097
5187
|
|
|
5098
5188
|
${block(pipelineIdentification)}
|
|
@@ -5110,7 +5200,7 @@ async function executeAttempts(options) {
|
|
|
5110
5200
|
break taskType;
|
|
5111
5201
|
// <- case: [๐
ฑ]
|
|
5112
5202
|
default:
|
|
5113
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5203
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5114
5204
|
Unknown execution type "${task.taskType}"
|
|
5115
5205
|
|
|
5116
5206
|
${block(pipelineIdentification)}
|
|
@@ -5134,9 +5224,7 @@ async function executeAttempts(options) {
|
|
|
5134
5224
|
break scripts;
|
|
5135
5225
|
}
|
|
5136
5226
|
catch (error) {
|
|
5137
|
-
|
|
5138
|
-
throw error;
|
|
5139
|
-
}
|
|
5227
|
+
assertsError(error);
|
|
5140
5228
|
if (error instanceof UnexpectedError) {
|
|
5141
5229
|
throw error;
|
|
5142
5230
|
}
|
|
@@ -5159,7 +5247,7 @@ async function executeAttempts(options) {
|
|
|
5159
5247
|
}
|
|
5160
5248
|
catch (error) {
|
|
5161
5249
|
keepUnused(error);
|
|
5162
|
-
throw new ExpectError(spaceTrim((block) => `
|
|
5250
|
+
throw new ExpectError(spaceTrim$1((block) => `
|
|
5163
5251
|
Expected valid JSON string
|
|
5164
5252
|
|
|
5165
5253
|
${block(
|
|
@@ -5169,7 +5257,7 @@ async function executeAttempts(options) {
|
|
|
5169
5257
|
}
|
|
5170
5258
|
}
|
|
5171
5259
|
else {
|
|
5172
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5260
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5173
5261
|
Unknown format "${task.format}"
|
|
5174
5262
|
|
|
5175
5263
|
${block(pipelineIdentification)}
|
|
@@ -5209,7 +5297,7 @@ async function executeAttempts(options) {
|
|
|
5209
5297
|
}
|
|
5210
5298
|
}
|
|
5211
5299
|
if ($ongoingTaskResult.$expectError !== null && attempt === maxAttempts - 1) {
|
|
5212
|
-
throw new PipelineExecutionError(spaceTrim((block) => {
|
|
5300
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => {
|
|
5213
5301
|
var _a, _b, _c;
|
|
5214
5302
|
return `
|
|
5215
5303
|
LLM execution failed ${maxExecutionAttempts}x
|
|
@@ -5232,7 +5320,7 @@ async function executeAttempts(options) {
|
|
|
5232
5320
|
Last result:
|
|
5233
5321
|
${block($ongoingTaskResult.$resultString === null
|
|
5234
5322
|
? 'null'
|
|
5235
|
-
: spaceTrim($ongoingTaskResult.$resultString)
|
|
5323
|
+
: spaceTrim$1($ongoingTaskResult.$resultString)
|
|
5236
5324
|
.split('\n')
|
|
5237
5325
|
.map((line) => `> ${line}`)
|
|
5238
5326
|
.join('\n'))}
|
|
@@ -5242,7 +5330,7 @@ async function executeAttempts(options) {
|
|
|
5242
5330
|
}
|
|
5243
5331
|
}
|
|
5244
5332
|
if ($ongoingTaskResult.$resultString === null) {
|
|
5245
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5333
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5246
5334
|
Something went wrong and prompt result is null
|
|
5247
5335
|
|
|
5248
5336
|
${block(pipelineIdentification)}
|
|
@@ -5265,7 +5353,7 @@ async function executeFormatSubvalues(options) {
|
|
|
5265
5353
|
return /* not await */ executeAttempts(options);
|
|
5266
5354
|
}
|
|
5267
5355
|
if (jokerParameterNames.length !== 0) {
|
|
5268
|
-
throw new UnexpectedError(spaceTrim
|
|
5356
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
5269
5357
|
JOKER parameters are not supported together with FOREACH command
|
|
5270
5358
|
|
|
5271
5359
|
[๐งโโ๏ธ] This should be prevented in \`validatePipeline\`
|
|
@@ -5278,7 +5366,7 @@ async function executeFormatSubvalues(options) {
|
|
|
5278
5366
|
if (formatDefinition === undefined) {
|
|
5279
5367
|
throw new UnexpectedError(
|
|
5280
5368
|
// <- TODO: [๐ง ][๐ง] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
5281
|
-
spaceTrim
|
|
5369
|
+
spaceTrim((block) => `
|
|
5282
5370
|
Unsupported format "${task.foreach.formatName}"
|
|
5283
5371
|
|
|
5284
5372
|
Available formats:
|
|
@@ -5295,7 +5383,7 @@ async function executeFormatSubvalues(options) {
|
|
|
5295
5383
|
if (subvalueDefinition === undefined) {
|
|
5296
5384
|
throw new UnexpectedError(
|
|
5297
5385
|
// <- TODO: [๐ง ][๐ง] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
5298
|
-
spaceTrim
|
|
5386
|
+
spaceTrim((block) => `
|
|
5299
5387
|
Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
|
|
5300
5388
|
|
|
5301
5389
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
@@ -5328,7 +5416,7 @@ async function executeFormatSubvalues(options) {
|
|
|
5328
5416
|
if (!(error instanceof PipelineExecutionError)) {
|
|
5329
5417
|
throw error;
|
|
5330
5418
|
}
|
|
5331
|
-
throw new PipelineExecutionError(spaceTrim
|
|
5419
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5332
5420
|
${error.message}
|
|
5333
5421
|
|
|
5334
5422
|
This is error in FOREACH command
|
|
@@ -5348,7 +5436,7 @@ async function executeFormatSubvalues(options) {
|
|
|
5348
5436
|
...options,
|
|
5349
5437
|
priority: priority + index,
|
|
5350
5438
|
parameters: allSubparameters,
|
|
5351
|
-
pipelineIdentification: spaceTrim
|
|
5439
|
+
pipelineIdentification: spaceTrim((block) => `
|
|
5352
5440
|
${block(pipelineIdentification)}
|
|
5353
5441
|
Subparameter index: ${index}
|
|
5354
5442
|
`),
|
|
@@ -5410,7 +5498,7 @@ async function getReservedParametersForTask(options) {
|
|
|
5410
5498
|
// Note: Doublecheck that ALL reserved parameters are defined:
|
|
5411
5499
|
for (const parameterName of RESERVED_PARAMETER_NAMES) {
|
|
5412
5500
|
if (reservedParameters[parameterName] === undefined) {
|
|
5413
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5501
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5414
5502
|
Reserved parameter {${parameterName}} is not defined
|
|
5415
5503
|
|
|
5416
5504
|
${block(pipelineIdentification)}
|
|
@@ -5438,7 +5526,7 @@ async function executeTask(options) {
|
|
|
5438
5526
|
const dependentParameterNames = new Set(currentTask.dependentParameterNames);
|
|
5439
5527
|
// TODO: [๐ฉ๐พโ๐คโ๐ฉ๐ป] Use here `mapAvailableToExpectedParameters`
|
|
5440
5528
|
if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
|
|
5441
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5529
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5442
5530
|
Dependent parameters are not consistent with used parameters:
|
|
5443
5531
|
|
|
5444
5532
|
Dependent parameters:
|
|
@@ -5478,7 +5566,7 @@ async function executeTask(options) {
|
|
|
5478
5566
|
else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
|
|
5479
5567
|
// Houston, we have a problem
|
|
5480
5568
|
// Note: Checking part is also done in `validatePipeline`, but itโs good to doublecheck
|
|
5481
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5569
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5482
5570
|
Parameter \`{${parameterName}}\` is NOT defined
|
|
5483
5571
|
BUT used in task "${currentTask.title || currentTask.name}"
|
|
5484
5572
|
|
|
@@ -5544,7 +5632,7 @@ function filterJustOutputParameters(options) {
|
|
|
5544
5632
|
for (const parameter of preparedPipeline.parameters.filter(({ isOutput }) => isOutput)) {
|
|
5545
5633
|
if (parametersToPass[parameter.name] === undefined) {
|
|
5546
5634
|
// [4]
|
|
5547
|
-
$warnings.push(new PipelineExecutionError(spaceTrim((block) => `
|
|
5635
|
+
$warnings.push(new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5548
5636
|
Parameter \`{${parameter.name}}\` should be an output parameter, but it was not generated during pipeline execution
|
|
5549
5637
|
|
|
5550
5638
|
${block(pipelineIdentification)}
|
|
@@ -5619,7 +5707,7 @@ async function executePipeline(options) {
|
|
|
5619
5707
|
for (const parameterName of Object.keys(inputParameters)) {
|
|
5620
5708
|
const parameter = preparedPipeline.parameters.find(({ name }) => name === parameterName);
|
|
5621
5709
|
if (parameter === undefined) {
|
|
5622
|
-
warnings.push(new PipelineExecutionError(spaceTrim((block) => `
|
|
5710
|
+
warnings.push(new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5623
5711
|
Extra parameter {${parameterName}} is being passed which is not part of the pipeline.
|
|
5624
5712
|
|
|
5625
5713
|
${block(pipelineIdentification)}
|
|
@@ -5634,7 +5722,7 @@ async function executePipeline(options) {
|
|
|
5634
5722
|
// TODO: [๐ง ] This should be also non-critical error
|
|
5635
5723
|
return exportJson({
|
|
5636
5724
|
name: 'pipelineExecutorResult',
|
|
5637
|
-
message: spaceTrim((block) => `
|
|
5725
|
+
message: spaceTrim$1((block) => `
|
|
5638
5726
|
Unuccessful PipelineExecutorResult (with extra parameter {${parameter.name}}) PipelineExecutorResult
|
|
5639
5727
|
|
|
5640
5728
|
${block(pipelineIdentification)}
|
|
@@ -5643,7 +5731,7 @@ async function executePipeline(options) {
|
|
|
5643
5731
|
value: {
|
|
5644
5732
|
isSuccessful: false,
|
|
5645
5733
|
errors: [
|
|
5646
|
-
new PipelineExecutionError(spaceTrim((block) => `
|
|
5734
|
+
new PipelineExecutionError(spaceTrim$1((block) => `
|
|
5647
5735
|
Parameter \`{${parameter.name}}\` is passed as input parameter but it is not input
|
|
5648
5736
|
|
|
5649
5737
|
${block(pipelineIdentification)}
|
|
@@ -5670,7 +5758,7 @@ async function executePipeline(options) {
|
|
|
5670
5758
|
while (unresovedTasks.length > 0) {
|
|
5671
5759
|
if (loopLimit-- < 0) {
|
|
5672
5760
|
// Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
|
|
5673
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5761
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5674
5762
|
Loop limit reached during resolving parameters pipeline execution
|
|
5675
5763
|
|
|
5676
5764
|
${block(pipelineIdentification)}
|
|
@@ -5680,7 +5768,7 @@ async function executePipeline(options) {
|
|
|
5680
5768
|
if (!currentTask && resolving.length === 0) {
|
|
5681
5769
|
throw new UnexpectedError(
|
|
5682
5770
|
// TODO: [๐] DRY
|
|
5683
|
-
spaceTrim((block) => `
|
|
5771
|
+
spaceTrim$1((block) => `
|
|
5684
5772
|
Can not resolve some parameters:
|
|
5685
5773
|
|
|
5686
5774
|
${block(pipelineIdentification)}
|
|
@@ -5720,7 +5808,7 @@ async function executePipeline(options) {
|
|
|
5720
5808
|
tools,
|
|
5721
5809
|
onProgress(newOngoingResult) {
|
|
5722
5810
|
if (isReturned) {
|
|
5723
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5811
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5724
5812
|
Can not call \`onProgress\` after pipeline execution is finished
|
|
5725
5813
|
|
|
5726
5814
|
${block(pipelineIdentification)}
|
|
@@ -5736,7 +5824,7 @@ async function executePipeline(options) {
|
|
|
5736
5824
|
}
|
|
5737
5825
|
},
|
|
5738
5826
|
$executionReport: executionReport,
|
|
5739
|
-
pipelineIdentification: spaceTrim((block) => `
|
|
5827
|
+
pipelineIdentification: spaceTrim$1((block) => `
|
|
5740
5828
|
${block(pipelineIdentification)}
|
|
5741
5829
|
Task name: ${currentTask.name}
|
|
5742
5830
|
Task title: ${currentTask.title}
|
|
@@ -5757,9 +5845,7 @@ async function executePipeline(options) {
|
|
|
5757
5845
|
await Promise.all(resolving);
|
|
5758
5846
|
}
|
|
5759
5847
|
catch (error /* <- Note: [3] */) {
|
|
5760
|
-
|
|
5761
|
-
throw error;
|
|
5762
|
-
}
|
|
5848
|
+
assertsError(error);
|
|
5763
5849
|
// Note: No need to rethrow UnexpectedError
|
|
5764
5850
|
// if (error instanceof UnexpectedError) {
|
|
5765
5851
|
// Note: Count usage, [๐ง ] Maybe put to separate function executionReportJsonToUsage + DRY [๐คนโโ๏ธ]
|
|
@@ -5847,7 +5933,7 @@ function createPipelineExecutor(options) {
|
|
|
5847
5933
|
preparedPipeline = pipeline;
|
|
5848
5934
|
}
|
|
5849
5935
|
else if (isNotPreparedWarningSupressed !== true) {
|
|
5850
|
-
console.warn(spaceTrim((block) => `
|
|
5936
|
+
console.warn(spaceTrim$1((block) => `
|
|
5851
5937
|
Pipeline is not prepared
|
|
5852
5938
|
|
|
5853
5939
|
${block(pipelineIdentification)}
|
|
@@ -5871,7 +5957,7 @@ function createPipelineExecutor(options) {
|
|
|
5871
5957
|
inputParameters,
|
|
5872
5958
|
tools,
|
|
5873
5959
|
onProgress,
|
|
5874
|
-
pipelineIdentification: spaceTrim((block) => `
|
|
5960
|
+
pipelineIdentification: spaceTrim$1((block) => `
|
|
5875
5961
|
${block(pipelineIdentification)}
|
|
5876
5962
|
${runCount === 1 ? '' : `Run #${runCount}`}
|
|
5877
5963
|
`),
|
|
@@ -5969,13 +6055,13 @@ function $registeredLlmToolsMessage() {
|
|
|
5969
6055
|
});
|
|
5970
6056
|
const usedEnvMessage = `Unknown \`.env\` file` ;
|
|
5971
6057
|
if (metadata.length === 0) {
|
|
5972
|
-
return spaceTrim
|
|
6058
|
+
return spaceTrim((block) => `
|
|
5973
6059
|
No LLM providers are available.
|
|
5974
6060
|
|
|
5975
6061
|
${block(usedEnvMessage)}
|
|
5976
6062
|
`);
|
|
5977
6063
|
}
|
|
5978
|
-
return spaceTrim
|
|
6064
|
+
return spaceTrim((block) => `
|
|
5979
6065
|
|
|
5980
6066
|
${block(usedEnvMessage)}
|
|
5981
6067
|
|
|
@@ -6021,7 +6107,7 @@ function $registeredLlmToolsMessage() {
|
|
|
6021
6107
|
morePieces.push(`Not configured`); // <- Note: Can not be configured via environment variables
|
|
6022
6108
|
}
|
|
6023
6109
|
}
|
|
6024
|
-
let providerMessage = spaceTrim
|
|
6110
|
+
let providerMessage = spaceTrim(`
|
|
6025
6111
|
${i + 1}) **${title}** \`${className}\` from \`${packageName}\`
|
|
6026
6112
|
${morePieces.join('; ')}
|
|
6027
6113
|
`);
|
|
@@ -6061,7 +6147,7 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
|
|
|
6061
6147
|
.list()
|
|
6062
6148
|
.find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
|
|
6063
6149
|
if (registeredItem === undefined) {
|
|
6064
|
-
throw new Error(spaceTrim
|
|
6150
|
+
throw new Error(spaceTrim((block) => `
|
|
6065
6151
|
There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
|
|
6066
6152
|
|
|
6067
6153
|
You have probably forgotten install and import the provider package.
|
|
@@ -6345,13 +6431,13 @@ function removeQuotes(text) {
|
|
|
6345
6431
|
* @public exported from `@promptbook/utils`
|
|
6346
6432
|
*/
|
|
6347
6433
|
function trimCodeBlock(value) {
|
|
6348
|
-
value = spaceTrim(value);
|
|
6434
|
+
value = spaceTrim$1(value);
|
|
6349
6435
|
if (!/^```[a-z]*(.*)```$/is.test(value)) {
|
|
6350
6436
|
return value;
|
|
6351
6437
|
}
|
|
6352
6438
|
value = value.replace(/^```[a-z]*/i, '');
|
|
6353
6439
|
value = value.replace(/```$/i, '');
|
|
6354
|
-
value = spaceTrim(value);
|
|
6440
|
+
value = spaceTrim$1(value);
|
|
6355
6441
|
return value;
|
|
6356
6442
|
}
|
|
6357
6443
|
|
|
@@ -6364,9 +6450,9 @@ function trimCodeBlock(value) {
|
|
|
6364
6450
|
* @public exported from `@promptbook/utils`
|
|
6365
6451
|
*/
|
|
6366
6452
|
function trimEndOfCodeBlock(value) {
|
|
6367
|
-
value = spaceTrim(value);
|
|
6453
|
+
value = spaceTrim$1(value);
|
|
6368
6454
|
value = value.replace(/```$/g, '');
|
|
6369
|
-
value = spaceTrim(value);
|
|
6455
|
+
value = spaceTrim$1(value);
|
|
6370
6456
|
return value;
|
|
6371
6457
|
}
|
|
6372
6458
|
|
|
@@ -6388,7 +6474,7 @@ function unwrapResult(text, options) {
|
|
|
6388
6474
|
let trimmedText = text;
|
|
6389
6475
|
// Remove leading and trailing spaces and newlines
|
|
6390
6476
|
if (isTrimmed) {
|
|
6391
|
-
trimmedText = spaceTrim(trimmedText);
|
|
6477
|
+
trimmedText = spaceTrim$1(trimmedText);
|
|
6392
6478
|
}
|
|
6393
6479
|
let processedText = trimmedText;
|
|
6394
6480
|
if (isIntroduceSentenceRemoved) {
|
|
@@ -6397,7 +6483,7 @@ function unwrapResult(text, options) {
|
|
|
6397
6483
|
// Remove the introduce sentence and quotes by replacing it with an empty string
|
|
6398
6484
|
processedText = processedText.replace(introduceSentenceRegex, '');
|
|
6399
6485
|
}
|
|
6400
|
-
processedText = spaceTrim(processedText);
|
|
6486
|
+
processedText = spaceTrim$1(processedText);
|
|
6401
6487
|
}
|
|
6402
6488
|
if (processedText.length < 3) {
|
|
6403
6489
|
return trimmedText;
|
|
@@ -6460,7 +6546,7 @@ function unwrapResult(text, options) {
|
|
|
6460
6546
|
function extractOneBlockFromMarkdown(markdown) {
|
|
6461
6547
|
const codeBlocks = extractAllBlocksFromMarkdown(markdown);
|
|
6462
6548
|
if (codeBlocks.length !== 1) {
|
|
6463
|
-
throw new ParseError(spaceTrim
|
|
6549
|
+
throw new ParseError(spaceTrim((block) => `
|
|
6464
6550
|
There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
|
|
6465
6551
|
|
|
6466
6552
|
${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
|
|
@@ -6542,8 +6628,8 @@ class JavascriptEvalExecutionTools {
|
|
|
6542
6628
|
}
|
|
6543
6629
|
// Note: [๐]
|
|
6544
6630
|
// Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
|
|
6545
|
-
const spaceTrim = (_) => spaceTrim
|
|
6546
|
-
preserve(spaceTrim);
|
|
6631
|
+
const spaceTrim$1 = (_) => spaceTrim(_);
|
|
6632
|
+
preserve(spaceTrim$1);
|
|
6547
6633
|
const removeQuotes$1 = removeQuotes;
|
|
6548
6634
|
preserve(removeQuotes$1);
|
|
6549
6635
|
const unwrapResult$1 = unwrapResult;
|
|
@@ -6596,7 +6682,7 @@ class JavascriptEvalExecutionTools {
|
|
|
6596
6682
|
// TODO: DRY [๐ฏ]
|
|
6597
6683
|
const buildinFunctions = {
|
|
6598
6684
|
// TODO: [๐ฏ] DRY all these functions across the file
|
|
6599
|
-
spaceTrim,
|
|
6685
|
+
spaceTrim: spaceTrim$1,
|
|
6600
6686
|
removeQuotes: removeQuotes$1,
|
|
6601
6687
|
unwrapResult: unwrapResult$1,
|
|
6602
6688
|
trimEndOfCodeBlock: trimEndOfCodeBlock$1,
|
|
@@ -6633,7 +6719,7 @@ class JavascriptEvalExecutionTools {
|
|
|
6633
6719
|
.join('\n');
|
|
6634
6720
|
// script = templateParameters(script, parameters);
|
|
6635
6721
|
// <- TODO: [๐ง ][๐ฅณ] Should be this is one of two variants how to use parameters in script
|
|
6636
|
-
const statementToEvaluate = spaceTrim
|
|
6722
|
+
const statementToEvaluate = spaceTrim((block) => `
|
|
6637
6723
|
|
|
6638
6724
|
// Build-in functions:
|
|
6639
6725
|
${block(buildinFunctionsStatement)}
|
|
@@ -6648,7 +6734,7 @@ class JavascriptEvalExecutionTools {
|
|
|
6648
6734
|
(()=>{ ${script} })()
|
|
6649
6735
|
`);
|
|
6650
6736
|
if (this.options.isVerbose) {
|
|
6651
|
-
console.info(spaceTrim
|
|
6737
|
+
console.info(spaceTrim((block) => `
|
|
6652
6738
|
๐ Evaluating ${scriptLanguage} script:
|
|
6653
6739
|
|
|
6654
6740
|
${block(statementToEvaluate)}`));
|
|
@@ -6661,9 +6747,7 @@ class JavascriptEvalExecutionTools {
|
|
|
6661
6747
|
}
|
|
6662
6748
|
}
|
|
6663
6749
|
catch (error) {
|
|
6664
|
-
|
|
6665
|
-
throw error;
|
|
6666
|
-
}
|
|
6750
|
+
assertsError(error);
|
|
6667
6751
|
if (error instanceof ReferenceError) {
|
|
6668
6752
|
const undefinedName = error.message.split(' ')[0];
|
|
6669
6753
|
/*
|
|
@@ -6672,7 +6756,7 @@ class JavascriptEvalExecutionTools {
|
|
|
6672
6756
|
To: [PipelineExecutionError: Parameter `{thing}` is not defined],
|
|
6673
6757
|
*/
|
|
6674
6758
|
if (!statementToEvaluate.includes(undefinedName + '(')) {
|
|
6675
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6759
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
6676
6760
|
|
|
6677
6761
|
Parameter \`{${undefinedName}}\` is not defined
|
|
6678
6762
|
|
|
@@ -6694,7 +6778,7 @@ class JavascriptEvalExecutionTools {
|
|
|
6694
6778
|
`));
|
|
6695
6779
|
}
|
|
6696
6780
|
else {
|
|
6697
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6781
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
6698
6782
|
Function ${undefinedName}() is not defined
|
|
6699
6783
|
|
|
6700
6784
|
- Make sure that the function is one of built-in functions
|
|
@@ -6743,6 +6827,198 @@ async function $provideScriptingForNode(options) {
|
|
|
6743
6827
|
* Note: [๐ข] Code in this file should never be never released in packages that could be imported into browser environment
|
|
6744
6828
|
*/
|
|
6745
6829
|
|
|
6830
|
+
// TODO: !!!! List running services from REMOTE_SERVER_URLS
|
|
6831
|
+
// TODO: !!!! Import directly from YML
|
|
6832
|
+
/**
|
|
6833
|
+
* @private !!!! Decide how to expose this
|
|
6834
|
+
*/
|
|
6835
|
+
const openapiJson = {
|
|
6836
|
+
openapi: '3.0.0',
|
|
6837
|
+
info: {
|
|
6838
|
+
title: 'Promptbook Remote Server API (!!!! From TS)',
|
|
6839
|
+
version: '1.0.0',
|
|
6840
|
+
description: 'API documentation for the Promptbook Remote Server',
|
|
6841
|
+
},
|
|
6842
|
+
paths: {
|
|
6843
|
+
'/': {
|
|
6844
|
+
get: {
|
|
6845
|
+
summary: 'Get server details',
|
|
6846
|
+
description: 'Returns details about the Promptbook server.',
|
|
6847
|
+
responses: {
|
|
6848
|
+
'200': {
|
|
6849
|
+
description: 'Server details in markdown format.',
|
|
6850
|
+
},
|
|
6851
|
+
},
|
|
6852
|
+
},
|
|
6853
|
+
},
|
|
6854
|
+
'/login': {
|
|
6855
|
+
post: {
|
|
6856
|
+
summary: 'Login to the server',
|
|
6857
|
+
description: 'Login to the server and get identification.',
|
|
6858
|
+
requestBody: {
|
|
6859
|
+
required: true,
|
|
6860
|
+
content: {
|
|
6861
|
+
'application/json': {
|
|
6862
|
+
schema: {
|
|
6863
|
+
type: 'object',
|
|
6864
|
+
properties: {
|
|
6865
|
+
username: {
|
|
6866
|
+
type: 'string',
|
|
6867
|
+
},
|
|
6868
|
+
password: {
|
|
6869
|
+
type: 'string',
|
|
6870
|
+
},
|
|
6871
|
+
appId: {
|
|
6872
|
+
type: 'string',
|
|
6873
|
+
},
|
|
6874
|
+
},
|
|
6875
|
+
},
|
|
6876
|
+
},
|
|
6877
|
+
},
|
|
6878
|
+
},
|
|
6879
|
+
responses: {
|
|
6880
|
+
'200': {
|
|
6881
|
+
description: 'Successful login',
|
|
6882
|
+
content: {
|
|
6883
|
+
'application/json': {
|
|
6884
|
+
schema: {
|
|
6885
|
+
type: 'object',
|
|
6886
|
+
properties: {
|
|
6887
|
+
identification: {
|
|
6888
|
+
type: 'object',
|
|
6889
|
+
},
|
|
6890
|
+
},
|
|
6891
|
+
},
|
|
6892
|
+
},
|
|
6893
|
+
},
|
|
6894
|
+
},
|
|
6895
|
+
},
|
|
6896
|
+
},
|
|
6897
|
+
},
|
|
6898
|
+
'/books': {
|
|
6899
|
+
get: {
|
|
6900
|
+
summary: 'List all books',
|
|
6901
|
+
description: 'Returns a list of all available books in the collection.',
|
|
6902
|
+
responses: {
|
|
6903
|
+
'200': {
|
|
6904
|
+
description: 'A list of books.',
|
|
6905
|
+
content: {
|
|
6906
|
+
'application/json': {
|
|
6907
|
+
schema: {
|
|
6908
|
+
type: 'array',
|
|
6909
|
+
items: {
|
|
6910
|
+
type: 'string',
|
|
6911
|
+
},
|
|
6912
|
+
},
|
|
6913
|
+
},
|
|
6914
|
+
},
|
|
6915
|
+
},
|
|
6916
|
+
},
|
|
6917
|
+
},
|
|
6918
|
+
},
|
|
6919
|
+
'/books/{bookId}': {
|
|
6920
|
+
get: {
|
|
6921
|
+
summary: 'Get book content',
|
|
6922
|
+
description: 'Returns the content of a specific book.',
|
|
6923
|
+
parameters: [
|
|
6924
|
+
{
|
|
6925
|
+
in: 'path',
|
|
6926
|
+
name: 'bookId',
|
|
6927
|
+
required: true,
|
|
6928
|
+
schema: {
|
|
6929
|
+
type: 'string',
|
|
6930
|
+
},
|
|
6931
|
+
description: 'The ID of the book to retrieve.',
|
|
6932
|
+
},
|
|
6933
|
+
],
|
|
6934
|
+
responses: {
|
|
6935
|
+
'200': {
|
|
6936
|
+
description: 'The content of the book.',
|
|
6937
|
+
content: {
|
|
6938
|
+
'text/markdown': {
|
|
6939
|
+
schema: {
|
|
6940
|
+
type: 'string',
|
|
6941
|
+
},
|
|
6942
|
+
},
|
|
6943
|
+
},
|
|
6944
|
+
},
|
|
6945
|
+
'404': {
|
|
6946
|
+
description: 'Book not found.',
|
|
6947
|
+
},
|
|
6948
|
+
},
|
|
6949
|
+
},
|
|
6950
|
+
},
|
|
6951
|
+
'/executions': {
|
|
6952
|
+
get: {
|
|
6953
|
+
summary: 'List all executions',
|
|
6954
|
+
description: 'Returns a list of all running execution tasks.',
|
|
6955
|
+
responses: {
|
|
6956
|
+
'200': {
|
|
6957
|
+
description: 'A list of execution tasks.',
|
|
6958
|
+
content: {
|
|
6959
|
+
'application/json': {
|
|
6960
|
+
schema: {
|
|
6961
|
+
type: 'array',
|
|
6962
|
+
items: {
|
|
6963
|
+
type: 'object',
|
|
6964
|
+
},
|
|
6965
|
+
},
|
|
6966
|
+
},
|
|
6967
|
+
},
|
|
6968
|
+
},
|
|
6969
|
+
},
|
|
6970
|
+
},
|
|
6971
|
+
},
|
|
6972
|
+
'/executions/new': {
|
|
6973
|
+
post: {
|
|
6974
|
+
summary: 'Start a new execution',
|
|
6975
|
+
description: 'Starts a new execution task for a given pipeline.',
|
|
6976
|
+
requestBody: {
|
|
6977
|
+
required: true,
|
|
6978
|
+
content: {
|
|
6979
|
+
'application/json': {
|
|
6980
|
+
schema: {
|
|
6981
|
+
type: 'object',
|
|
6982
|
+
properties: {
|
|
6983
|
+
pipelineUrl: {
|
|
6984
|
+
type: 'string',
|
|
6985
|
+
},
|
|
6986
|
+
inputParameters: {
|
|
6987
|
+
type: 'object',
|
|
6988
|
+
},
|
|
6989
|
+
identification: {
|
|
6990
|
+
type: 'object',
|
|
6991
|
+
},
|
|
6992
|
+
},
|
|
6993
|
+
},
|
|
6994
|
+
},
|
|
6995
|
+
},
|
|
6996
|
+
},
|
|
6997
|
+
responses: {
|
|
6998
|
+
'200': {
|
|
6999
|
+
description: 'The newly created execution task.',
|
|
7000
|
+
content: {
|
|
7001
|
+
'application/json': {
|
|
7002
|
+
schema: {
|
|
7003
|
+
type: 'object',
|
|
7004
|
+
},
|
|
7005
|
+
},
|
|
7006
|
+
},
|
|
7007
|
+
},
|
|
7008
|
+
'400': {
|
|
7009
|
+
description: 'Invalid input.',
|
|
7010
|
+
},
|
|
7011
|
+
},
|
|
7012
|
+
},
|
|
7013
|
+
},
|
|
7014
|
+
},
|
|
7015
|
+
components: {},
|
|
7016
|
+
tags: [],
|
|
7017
|
+
};
|
|
7018
|
+
/**
|
|
7019
|
+
* Note: [๐] Ignore a discrepancy between file name and entity name
|
|
7020
|
+
*/
|
|
7021
|
+
|
|
6746
7022
|
/**
|
|
6747
7023
|
* Remote server is a proxy server that uses its execution tools internally and exposes the executor interface externally.
|
|
6748
7024
|
*
|
|
@@ -6753,7 +7029,7 @@ async function $provideScriptingForNode(options) {
|
|
|
6753
7029
|
* @public exported from `@promptbook/remote-server`
|
|
6754
7030
|
*/
|
|
6755
7031
|
function startRemoteServer(options) {
|
|
6756
|
-
const { port, collection, createLlmExecutionTools, isAnonymousModeAllowed, isApplicationModeAllowed, isVerbose = DEFAULT_IS_VERBOSE, login, } = {
|
|
7032
|
+
const { port, collection, createLlmExecutionTools, createExecutionTools, isAnonymousModeAllowed, isApplicationModeAllowed, isVerbose = DEFAULT_IS_VERBOSE, login, } = {
|
|
6757
7033
|
isAnonymousModeAllowed: false,
|
|
6758
7034
|
isApplicationModeAllowed: false,
|
|
6759
7035
|
collection: null,
|
|
@@ -6761,22 +7037,6 @@ function startRemoteServer(options) {
|
|
|
6761
7037
|
login: null,
|
|
6762
7038
|
...options,
|
|
6763
7039
|
};
|
|
6764
|
-
// <- TODO: [๐ฆช] Some helper type to be able to use discriminant union types with destructuring
|
|
6765
|
-
let { rootPath = '/' } = options;
|
|
6766
|
-
if (!rootPath.startsWith('/')) {
|
|
6767
|
-
rootPath = `/${rootPath}`;
|
|
6768
|
-
} /* not else */
|
|
6769
|
-
if (rootPath.endsWith('/')) {
|
|
6770
|
-
rootPath = rootPath.slice(0, -1);
|
|
6771
|
-
} /* not else */
|
|
6772
|
-
if (rootPath === '/') {
|
|
6773
|
-
rootPath = '';
|
|
6774
|
-
}
|
|
6775
|
-
const socketioPath = '/' +
|
|
6776
|
-
`${rootPath}/socket.io`
|
|
6777
|
-
.split('/')
|
|
6778
|
-
.filter((part) => part !== '')
|
|
6779
|
-
.join('/');
|
|
6780
7040
|
const startupDate = new Date();
|
|
6781
7041
|
async function getExecutionToolsFromIdentification(identification) {
|
|
6782
7042
|
if (identification === null || identification === undefined) {
|
|
@@ -6799,23 +7059,25 @@ function startRemoteServer(options) {
|
|
|
6799
7059
|
}
|
|
6800
7060
|
else if (isAnonymous === false && createLlmExecutionTools !== null) {
|
|
6801
7061
|
// Note: Application mode
|
|
6802
|
-
|
|
6803
|
-
llm = await createLlmExecutionTools({
|
|
6804
|
-
appId,
|
|
6805
|
-
userId,
|
|
6806
|
-
customOptions,
|
|
6807
|
-
});
|
|
7062
|
+
llm = await createLlmExecutionTools(identification);
|
|
6808
7063
|
}
|
|
6809
7064
|
else {
|
|
6810
7065
|
throw new PipelineExecutionError(`You must provide either llmToolsConfiguration or non-anonymous mode must be propperly configured`);
|
|
6811
7066
|
}
|
|
6812
|
-
const
|
|
6813
|
-
const
|
|
7067
|
+
const customExecutionTools = createExecutionTools ? await createExecutionTools(identification) : {};
|
|
7068
|
+
const fs = customExecutionTools.fs || $provideFilesystemForNode();
|
|
7069
|
+
const executables = customExecutionTools.executables || (await $provideExecutablesForNode());
|
|
7070
|
+
const scrapers = customExecutionTools.scrapers || (await $provideScrapersForNode({ fs, llm, executables }));
|
|
7071
|
+
const script = customExecutionTools.script || (await $provideScriptingForNode({}));
|
|
7072
|
+
const fetch = customExecutionTools.fetch || promptbookFetch;
|
|
7073
|
+
const userInterface = customExecutionTools.userInterface || undefined;
|
|
6814
7074
|
const tools = {
|
|
6815
7075
|
llm,
|
|
6816
7076
|
fs,
|
|
6817
|
-
scrapers
|
|
6818
|
-
script
|
|
7077
|
+
scrapers,
|
|
7078
|
+
script,
|
|
7079
|
+
fetch,
|
|
7080
|
+
userInterface,
|
|
6819
7081
|
};
|
|
6820
7082
|
return tools;
|
|
6821
7083
|
}
|
|
@@ -6825,44 +7087,32 @@ function startRemoteServer(options) {
|
|
|
6825
7087
|
response.setHeader('X-Powered-By', 'Promptbook engine');
|
|
6826
7088
|
next();
|
|
6827
7089
|
});
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
version: '1.0.0',
|
|
6834
|
-
description: 'API documentation for the Promptbook Remote Server',
|
|
6835
|
-
},
|
|
6836
|
-
servers: [
|
|
6837
|
-
{
|
|
6838
|
-
url: `http://localhost:${port}${rootPath}`,
|
|
6839
|
-
// <- TODO: !!!!! Probbably: Pass `remoteServerUrl` instead of `port` and `rootPath`
|
|
6840
|
-
},
|
|
6841
|
-
],
|
|
7090
|
+
// TODO: !!!! Expose openapiJson to consumer and also allow to add new routes
|
|
7091
|
+
app.use(OpenApiValidator.middleware({
|
|
7092
|
+
apiSpec: openapiJson,
|
|
7093
|
+
ignorePaths(path) {
|
|
7094
|
+
return path.startsWith('/api-docs') || path.startsWith('/swagger') || path.startsWith('/openapi');
|
|
6842
7095
|
},
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
app.use([`/api-docs`,
|
|
7096
|
+
validateRequests: true,
|
|
7097
|
+
validateResponses: true,
|
|
7098
|
+
}));
|
|
7099
|
+
app.use([`/api-docs`, `/swagger`], swaggerUi.serve, swaggerUi.setup(openapiJson, {
|
|
7100
|
+
// customCss: '.swagger-ui .topbar { display: none }',
|
|
7101
|
+
// customSiteTitle: 'BRJ API',
|
|
7102
|
+
// customfavIcon: 'https://brj.app/favicon.ico',
|
|
7103
|
+
}));
|
|
7104
|
+
app.get(`/openapi`, (request, response) => {
|
|
7105
|
+
response.json(openapiJson);
|
|
7106
|
+
});
|
|
6847
7107
|
const runningExecutionTasks = [];
|
|
6848
7108
|
// <- TODO: [๐คฌ] Identify the users
|
|
6849
7109
|
// TODO: [๐ง ] Do here some garbage collection of finished tasks
|
|
6850
|
-
|
|
6851
|
-
* @swagger
|
|
6852
|
-
* /:
|
|
6853
|
-
* get:
|
|
6854
|
-
* summary: Get server details
|
|
6855
|
-
* description: Returns details about the Promptbook server.
|
|
6856
|
-
* responses:
|
|
6857
|
-
* 200:
|
|
6858
|
-
* description: Server details in markdown format.
|
|
6859
|
-
*/
|
|
6860
|
-
app.get(['/', rootPath], async (request, response) => {
|
|
7110
|
+
app.get('/', async (request, response) => {
|
|
6861
7111
|
var _a;
|
|
6862
7112
|
if ((_a = request.url) === null || _a === void 0 ? void 0 : _a.includes('socket.io')) {
|
|
6863
7113
|
return;
|
|
6864
7114
|
}
|
|
6865
|
-
response.type('text/markdown').send(await spaceTrim(async (block) => `
|
|
7115
|
+
response.type('text/markdown').send(await spaceTrim$1(async (block) => `
|
|
6866
7116
|
# Promptbook
|
|
6867
7117
|
|
|
6868
7118
|
> ${block(CLAIM)}
|
|
@@ -6876,8 +7126,6 @@ function startRemoteServer(options) {
|
|
|
6876
7126
|
## Details
|
|
6877
7127
|
|
|
6878
7128
|
**Server port:** ${port}
|
|
6879
|
-
**Server root path:** ${rootPath}
|
|
6880
|
-
**Socket.io path:** ${socketioPath}
|
|
6881
7129
|
**Startup date:** ${startupDate.toISOString()}
|
|
6882
7130
|
**Anonymouse mode:** ${isAnonymousModeAllowed ? 'enabled' : 'disabled'}
|
|
6883
7131
|
**Application mode:** ${isApplicationModeAllowed ? 'enabled' : 'disabled'}
|
|
@@ -6916,38 +7164,7 @@ function startRemoteServer(options) {
|
|
|
6916
7164
|
https://github.com/webgptorg/promptbook
|
|
6917
7165
|
`));
|
|
6918
7166
|
});
|
|
6919
|
-
|
|
6920
|
-
* @swagger
|
|
6921
|
-
*
|
|
6922
|
-
* /login:
|
|
6923
|
-
* post:
|
|
6924
|
-
* summary: Login to the server
|
|
6925
|
-
* description: Login to the server and get identification.
|
|
6926
|
-
* requestBody:
|
|
6927
|
-
* required: true
|
|
6928
|
-
* content:
|
|
6929
|
-
* application/json:
|
|
6930
|
-
* schema:
|
|
6931
|
-
* type: object
|
|
6932
|
-
* properties:
|
|
6933
|
-
* username:
|
|
6934
|
-
* type: string
|
|
6935
|
-
* password:
|
|
6936
|
-
* type: string
|
|
6937
|
-
* appId:
|
|
6938
|
-
* type: string
|
|
6939
|
-
* responses:
|
|
6940
|
-
* 200:
|
|
6941
|
-
* description: Successful login
|
|
6942
|
-
* content:
|
|
6943
|
-
* application/json:
|
|
6944
|
-
* schema:
|
|
6945
|
-
* type: object
|
|
6946
|
-
* properties:
|
|
6947
|
-
* identification:
|
|
6948
|
-
* type: object
|
|
6949
|
-
*/
|
|
6950
|
-
app.post([`/login`, `${rootPath}/login`], async (request, response) => {
|
|
7167
|
+
app.post(`/login`, async (request, response) => {
|
|
6951
7168
|
if (!isApplicationModeAllowed || login === null) {
|
|
6952
7169
|
response.status(400).send('Application mode is not allowed');
|
|
6953
7170
|
return;
|
|
@@ -6972,9 +7189,7 @@ function startRemoteServer(options) {
|
|
|
6972
7189
|
return;
|
|
6973
7190
|
}
|
|
6974
7191
|
catch (error) {
|
|
6975
|
-
|
|
6976
|
-
throw error;
|
|
6977
|
-
}
|
|
7192
|
+
assertsError(error);
|
|
6978
7193
|
if (error instanceof AuthenticationError) {
|
|
6979
7194
|
response.status(401).send({
|
|
6980
7195
|
isSuccess: false,
|
|
@@ -6989,23 +7204,7 @@ function startRemoteServer(options) {
|
|
|
6989
7204
|
response.status(400).send({ error: serializeError(error) });
|
|
6990
7205
|
}
|
|
6991
7206
|
});
|
|
6992
|
-
|
|
6993
|
-
* @swagger
|
|
6994
|
-
* /books:
|
|
6995
|
-
* get:
|
|
6996
|
-
* summary: List all books
|
|
6997
|
-
* description: Returns a list of all available books in the collection.
|
|
6998
|
-
* responses:
|
|
6999
|
-
* 200:
|
|
7000
|
-
* description: A list of books.
|
|
7001
|
-
* content:
|
|
7002
|
-
* application/json:
|
|
7003
|
-
* schema:
|
|
7004
|
-
* type: array
|
|
7005
|
-
* items:
|
|
7006
|
-
* type: string
|
|
7007
|
-
*/
|
|
7008
|
-
app.get([`/books`, `${rootPath}/books`], async (request, response) => {
|
|
7207
|
+
app.get(`/books`, async (request, response) => {
|
|
7009
7208
|
if (collection === null) {
|
|
7010
7209
|
response.status(500).send('No collection available');
|
|
7011
7210
|
return;
|
|
@@ -7015,30 +7214,7 @@ function startRemoteServer(options) {
|
|
|
7015
7214
|
response.send(pipelines);
|
|
7016
7215
|
});
|
|
7017
7216
|
// TODO: [๐ง ] Is it secure / good idea to expose source codes of hosted books
|
|
7018
|
-
|
|
7019
|
-
* @swagger
|
|
7020
|
-
* /books/{bookId}:
|
|
7021
|
-
* get:
|
|
7022
|
-
* summary: Get book content
|
|
7023
|
-
* description: Returns the content of a specific book.
|
|
7024
|
-
* parameters:
|
|
7025
|
-
* - in: path
|
|
7026
|
-
* name: bookId
|
|
7027
|
-
* required: true
|
|
7028
|
-
* schema:
|
|
7029
|
-
* type: string
|
|
7030
|
-
* description: The ID of the book to retrieve.
|
|
7031
|
-
* responses:
|
|
7032
|
-
* 200:
|
|
7033
|
-
* description: The content of the book.
|
|
7034
|
-
* content:
|
|
7035
|
-
* text/markdown:
|
|
7036
|
-
* schema:
|
|
7037
|
-
* type: string
|
|
7038
|
-
* 404:
|
|
7039
|
-
* description: Book not found.
|
|
7040
|
-
*/
|
|
7041
|
-
app.get([`/books/*`, `${rootPath}/books/*`], async (request, response) => {
|
|
7217
|
+
app.get(`/books/*`, async (request, response) => {
|
|
7042
7218
|
try {
|
|
7043
7219
|
if (collection === null) {
|
|
7044
7220
|
response.status(500).send('No collection nor books available');
|
|
@@ -7057,9 +7233,7 @@ function startRemoteServer(options) {
|
|
|
7057
7233
|
.send(source.content);
|
|
7058
7234
|
}
|
|
7059
7235
|
catch (error) {
|
|
7060
|
-
|
|
7061
|
-
throw error;
|
|
7062
|
-
}
|
|
7236
|
+
assertsError(error);
|
|
7063
7237
|
response
|
|
7064
7238
|
.status(404)
|
|
7065
7239
|
.send({ error: serializeError(error) });
|
|
@@ -7092,26 +7266,10 @@ function startRemoteServer(options) {
|
|
|
7092
7266
|
};
|
|
7093
7267
|
}
|
|
7094
7268
|
}
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
* /executions:
|
|
7098
|
-
* get:
|
|
7099
|
-
* summary: List all executions
|
|
7100
|
-
* description: Returns a list of all running execution tasks.
|
|
7101
|
-
* responses:
|
|
7102
|
-
* 200:
|
|
7103
|
-
* description: A list of execution tasks.
|
|
7104
|
-
* content:
|
|
7105
|
-
* application/json:
|
|
7106
|
-
* schema:
|
|
7107
|
-
* type: array
|
|
7108
|
-
* items:
|
|
7109
|
-
* type: object
|
|
7110
|
-
*/
|
|
7111
|
-
app.get([`/executions`, `${rootPath}/executions`], async (request, response) => {
|
|
7112
|
-
response.send(runningExecutionTasks.map((runningExecutionTask) => exportExecutionTask(runningExecutionTask, false)));
|
|
7269
|
+
app.get(`/executions`, async (request, response) => {
|
|
7270
|
+
response.send(runningExecutionTasks.map((runningExecutionTask) => exportExecutionTask(runningExecutionTask, false)) /* <- TODO: satisfies paths['/executions']['get']['responses']['200']['content']['application/json'] */);
|
|
7113
7271
|
});
|
|
7114
|
-
app.get(
|
|
7272
|
+
app.get(`/executions/last`, async (request, response) => {
|
|
7115
7273
|
// TODO: [๐คฌ] Filter only for user
|
|
7116
7274
|
if (runningExecutionTasks.length === 0) {
|
|
7117
7275
|
response.status(404).send('No execution tasks found');
|
|
@@ -7120,7 +7278,7 @@ function startRemoteServer(options) {
|
|
|
7120
7278
|
const lastExecutionTask = runningExecutionTasks[runningExecutionTasks.length - 1];
|
|
7121
7279
|
response.send(exportExecutionTask(lastExecutionTask, true));
|
|
7122
7280
|
});
|
|
7123
|
-
app.get(
|
|
7281
|
+
app.get(`/executions/:taskId`, async (request, response) => {
|
|
7124
7282
|
const { taskId } = request.params;
|
|
7125
7283
|
// TODO: [๐คฌ] Filter only for user
|
|
7126
7284
|
const executionTask = runningExecutionTasks.find((executionTask) => executionTask.taskId === taskId);
|
|
@@ -7132,39 +7290,12 @@ function startRemoteServer(options) {
|
|
|
7132
7290
|
}
|
|
7133
7291
|
response.send(exportExecutionTask(executionTask, true));
|
|
7134
7292
|
});
|
|
7135
|
-
|
|
7136
|
-
* @swagger
|
|
7137
|
-
* /executions/new:
|
|
7138
|
-
* post:
|
|
7139
|
-
* summary: Start a new execution
|
|
7140
|
-
* description: Starts a new execution task for a given pipeline.
|
|
7141
|
-
* requestBody:
|
|
7142
|
-
* required: true
|
|
7143
|
-
* content:
|
|
7144
|
-
* application/json:
|
|
7145
|
-
* schema:
|
|
7146
|
-
* type: object
|
|
7147
|
-
* properties:
|
|
7148
|
-
* pipelineUrl:
|
|
7149
|
-
* type: string
|
|
7150
|
-
* inputParameters:
|
|
7151
|
-
* type: object
|
|
7152
|
-
* identification:
|
|
7153
|
-
* type: object
|
|
7154
|
-
* responses:
|
|
7155
|
-
* 200:
|
|
7156
|
-
* description: The newly created execution task.
|
|
7157
|
-
* content:
|
|
7158
|
-
* application/json:
|
|
7159
|
-
* schema:
|
|
7160
|
-
* type: object
|
|
7161
|
-
* 400:
|
|
7162
|
-
* description: Invalid input.
|
|
7163
|
-
*/
|
|
7164
|
-
app.post([`/executions/new`, `${rootPath}/executions/new`], async (request, response) => {
|
|
7293
|
+
app.post(`/executions/new`, async (request, response) => {
|
|
7165
7294
|
try {
|
|
7166
7295
|
const { inputParameters, identification /* <- [๐คฌ] */ } = request.body;
|
|
7167
|
-
const pipelineUrl = request.body
|
|
7296
|
+
const pipelineUrl = request.body
|
|
7297
|
+
.pipelineUrl /* <- TODO: as paths['/executions/new']['post']['requestBody']['content']['application/json'] */ ||
|
|
7298
|
+
request.body.book;
|
|
7168
7299
|
// TODO: [๐ง ] Check `pipelineUrl` and `inputParameters` here or it should be responsibility of `collection.getPipelineByUrl` and `pipelineExecutor`
|
|
7169
7300
|
const pipeline = await (collection === null || collection === void 0 ? void 0 : collection.getPipelineByUrl(pipelineUrl));
|
|
7170
7301
|
if (pipeline === undefined) {
|
|
@@ -7178,7 +7309,7 @@ function startRemoteServer(options) {
|
|
|
7178
7309
|
await forTime(10);
|
|
7179
7310
|
// <- Note: Wait for a while to wait for quick responses or sudden but asynchronous errors
|
|
7180
7311
|
// <- TODO: Put this into configuration
|
|
7181
|
-
response.send(executionTask);
|
|
7312
|
+
response.send(executionTask /* <- TODO: satisfies paths['/executions/new']['post']['responses']['200']['content']['application/json'] */);
|
|
7182
7313
|
/*/
|
|
7183
7314
|
executionTask.asObservable().subscribe({
|
|
7184
7315
|
next(partialResult) {
|
|
@@ -7198,19 +7329,24 @@ function startRemoteServer(options) {
|
|
|
7198
7329
|
*/
|
|
7199
7330
|
}
|
|
7200
7331
|
catch (error) {
|
|
7201
|
-
|
|
7202
|
-
throw error;
|
|
7203
|
-
}
|
|
7332
|
+
assertsError(error);
|
|
7204
7333
|
response.status(400).send({ error: serializeError(error) });
|
|
7205
7334
|
}
|
|
7206
7335
|
});
|
|
7336
|
+
/**
|
|
7337
|
+
* Catch-all handler for unmatched routes
|
|
7338
|
+
*/
|
|
7339
|
+
app.use((request, response) => {
|
|
7340
|
+
response.status(404).send(`URL "${request.originalUrl}" was not found on Promptbook server.`);
|
|
7341
|
+
});
|
|
7207
7342
|
const httpServer = http.createServer(app);
|
|
7208
7343
|
const server = new Server(httpServer, {
|
|
7209
|
-
path:
|
|
7210
|
-
transports: [
|
|
7344
|
+
path: '/socket.io',
|
|
7345
|
+
transports: ['polling', 'websocket' /*, <- TODO: [๐ฌ] Allow to pass `transports`, add 'webtransport' */],
|
|
7211
7346
|
cors: {
|
|
7212
7347
|
origin: '*',
|
|
7213
7348
|
methods: ['GET', 'POST'],
|
|
7349
|
+
// <- TODO: [๐ก] Allow to pass
|
|
7214
7350
|
},
|
|
7215
7351
|
});
|
|
7216
7352
|
server.on('connection', (socket) => {
|
|
@@ -7264,9 +7400,7 @@ function startRemoteServer(options) {
|
|
|
7264
7400
|
socket.emit('prompt-response', { promptResult } /* <- Note: [๐ค] */);
|
|
7265
7401
|
}
|
|
7266
7402
|
catch (error) {
|
|
7267
|
-
|
|
7268
|
-
throw error;
|
|
7269
|
-
}
|
|
7403
|
+
assertsError(error);
|
|
7270
7404
|
socket.emit('error', serializeError(error) /* <- Note: [๐ค] */);
|
|
7271
7405
|
}
|
|
7272
7406
|
finally {
|
|
@@ -7288,9 +7422,7 @@ function startRemoteServer(options) {
|
|
|
7288
7422
|
socket.emit('listModels-response', { models } /* <- Note: [๐ค] */);
|
|
7289
7423
|
}
|
|
7290
7424
|
catch (error) {
|
|
7291
|
-
|
|
7292
|
-
throw error;
|
|
7293
|
-
}
|
|
7425
|
+
assertsError(error);
|
|
7294
7426
|
socket.emit('error', serializeError(error));
|
|
7295
7427
|
}
|
|
7296
7428
|
finally {
|
|
@@ -7311,9 +7443,7 @@ function startRemoteServer(options) {
|
|
|
7311
7443
|
socket.emit('preparePipeline-response', { preparedPipeline } /* <- Note: [๐ค] */);
|
|
7312
7444
|
}
|
|
7313
7445
|
catch (error) {
|
|
7314
|
-
|
|
7315
|
-
throw error;
|
|
7316
|
-
}
|
|
7446
|
+
assertsError(error);
|
|
7317
7447
|
socket.emit('error', serializeError(error));
|
|
7318
7448
|
// <- TODO: [๐] There is a problem with the remote server handling errors and sending them back to the client
|
|
7319
7449
|
}
|
|
@@ -7361,8 +7491,7 @@ function startRemoteServer(options) {
|
|
|
7361
7491
|
};
|
|
7362
7492
|
}
|
|
7363
7493
|
/**
|
|
7364
|
-
* TODO:
|
|
7365
|
-
* TODO: [๐ฉ๐พโ๐คโ๐ง๐พ] Allow to pass custom fetch function here - PromptbookFetch
|
|
7494
|
+
* TODO: [๐ก] Add CORS and security - probbably via `helmet`
|
|
7366
7495
|
* TODO: Split this file into multiple functions - handler for each request
|
|
7367
7496
|
* TODO: Maybe use `$exportJson`
|
|
7368
7497
|
* TODO: [๐ง ][๐] Maybe not `isAnonymous: boolean` BUT `mode: 'ANONYMOUS'|'COLLECTION'`
|