@promptbook/documents 0.89.0-8 → 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.
Files changed (50) hide show
  1. package/README.md +9 -11
  2. package/esm/index.es.js +155 -42
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/servers.d.ts +40 -0
  5. package/esm/typings/src/_packages/core.index.d.ts +12 -4
  6. package/esm/typings/src/_packages/remote-client.index.d.ts +6 -6
  7. package/esm/typings/src/_packages/remote-server.index.d.ts +6 -6
  8. package/esm/typings/src/_packages/types.index.d.ts +24 -14
  9. package/esm/typings/src/_packages/utils.index.d.ts +4 -0
  10. package/esm/typings/src/cli/cli-commands/login.d.ts +0 -1
  11. package/esm/typings/src/cli/common/$provideLlmToolsForCli.d.ts +16 -3
  12. package/esm/typings/src/cli/test/ptbk.d.ts +1 -1
  13. package/esm/typings/src/commands/EXPECT/expectCommandParser.d.ts +2 -0
  14. package/esm/typings/src/config.d.ts +10 -19
  15. package/esm/typings/src/errors/0-index.d.ts +8 -2
  16. package/esm/typings/src/errors/PipelineExecutionError.d.ts +1 -1
  17. package/esm/typings/src/errors/PromptbookFetchError.d.ts +9 -0
  18. package/esm/typings/src/errors/WrappedError.d.ts +10 -0
  19. package/esm/typings/src/errors/assertsError.d.ts +11 -0
  20. package/esm/typings/src/execution/PromptbookFetch.d.ts +1 -1
  21. package/esm/typings/src/formats/csv/utils/isValidCsvString.d.ts +9 -0
  22. package/esm/typings/src/formats/csv/utils/isValidCsvString.test.d.ts +1 -0
  23. package/esm/typings/src/formats/json/utils/isValidJsonString.d.ts +3 -0
  24. package/esm/typings/src/formats/xml/utils/isValidXmlString.d.ts +9 -0
  25. package/esm/typings/src/formats/xml/utils/isValidXmlString.test.d.ts +1 -0
  26. package/esm/typings/src/llm-providers/_common/register/$provideEnvFilename.d.ts +12 -0
  27. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsConfigurationFromEnv.d.ts +2 -8
  28. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +2 -0
  29. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForWizzardOrCli.d.ts +15 -4
  30. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsFromEnv.d.ts +1 -0
  31. package/esm/typings/src/remote-server/openapi-types.d.ts +284 -0
  32. package/esm/typings/src/remote-server/openapi.d.ts +187 -0
  33. package/esm/typings/src/remote-server/socket-types/_subtypes/{PromptbookServer_Identification.d.ts → Identification.d.ts} +9 -3
  34. package/esm/typings/src/remote-server/socket-types/_subtypes/identificationToPromptbookToken.d.ts +11 -0
  35. package/esm/typings/src/remote-server/socket-types/_subtypes/promptbookTokenToIdentification.d.ts +10 -0
  36. package/esm/typings/src/remote-server/socket-types/listModels/PromptbookServer_ListModels_Request.d.ts +2 -2
  37. package/esm/typings/src/remote-server/socket-types/prepare/PromptbookServer_PreparePipeline_Request.d.ts +2 -2
  38. package/esm/typings/src/remote-server/socket-types/prompt/PromptbookServer_Prompt_Request.d.ts +2 -2
  39. package/esm/typings/src/remote-server/startRemoteServer.d.ts +1 -2
  40. package/esm/typings/src/remote-server/types/RemoteClientOptions.d.ts +2 -2
  41. package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +57 -38
  42. package/esm/typings/src/scrapers/_common/utils/{scraperFetch.d.ts → promptbookFetch.d.ts} +2 -2
  43. package/esm/typings/src/storage/env-storage/$EnvStorage.d.ts +40 -0
  44. package/esm/typings/src/types/typeAliases.d.ts +26 -0
  45. package/package.json +8 -4
  46. package/umd/index.umd.js +155 -42
  47. package/umd/index.umd.js.map +1 -1
  48. package/esm/typings/src/cli/test/ptbk2.d.ts +0 -5
  49. package/esm/typings/src/playground/BrjappConnector.d.ts +0 -67
  50. package/esm/typings/src/playground/brjapp-api-schema.d.ts +0 -12879
@@ -3,13 +3,15 @@ import type { Promisable } from 'type-fest';
3
3
  import type { PipelineCollection } from '../../collection/PipelineCollection';
4
4
  import { AuthenticationError } from '../../errors/AuthenticationError';
5
5
  import type { CommonToolsOptions } from '../../execution/CommonToolsOptions';
6
+ import type { ExecutionTools } from '../../execution/ExecutionTools';
6
7
  import type { LlmExecutionTools } from '../../execution/LlmExecutionTools';
7
8
  import type { string_app_id } from '../../types/typeAliases';
8
9
  import type { string_email } from '../../types/typeAliases';
9
10
  import type { string_password } from '../../types/typeAliases';
10
- import type { string_uri } from '../../types/typeAliases';
11
+ import type { string_token } from '../../types/typeAliases';
11
12
  import type { string_user_id } from '../../types/typeAliases';
12
- import type { PromptbookServer_Identification } from '../socket-types/_subtypes/PromptbookServer_Identification';
13
+ import type { ApplicationModeIdentification } from '../socket-types/_subtypes/Identification';
14
+ import type { Identification } from '../socket-types/_subtypes/Identification';
13
15
  /**
14
16
  * @@@
15
17
  *
@@ -29,14 +31,18 @@ export type RemoteServerOptions<TCustomOptions> = CommonToolsOptions & {
29
31
  */
30
32
  readonly port: number;
31
33
  /**
32
- * Root path of the server
34
+ * Creates execution tools the client
33
35
  *
34
- * Note: This is useful when you reverse proxy the server without changing the path
36
+ * This is relevant also in anonymous mode in oposition to `createLlmExecutionTools`
35
37
  *
36
- * @default '/'
37
- * @example '/api/promptbook/'
38
+ * Note: You can provide only some tools and leave the rest to the default ones also llm tools are created by `createLlmExecutionTools`
39
+ * Note: This is useful when you want to provide some custom restrictions for example:
40
+ * - Limit access to certain websites for some users
41
+ * - Bind user-interface tools to email agent
42
+ * - Allow / block script execution
43
+ * - And many more
38
44
  */
39
- readonly rootPath?: string_uri;
45
+ createExecutionTools?(options: Identification<TCustomOptions>): Promisable<Partial<Omit<ExecutionTools, 'llm'>>>;
40
46
  } & ((AnonymousRemoteServerOptions & {
41
47
  readonly isApplicationModeAllowed?: false;
42
48
  }) | ({
@@ -70,36 +76,11 @@ export type ApplicationRemoteServerOptions<TCustomOptions> = {
70
76
  * Note: In most cases DO NOT THROW `AuthenticationError` but return `isSuccess: false` with message
71
77
  * @throws `AuthenticationError` if the user is not allowed to login for example because of invalid credentials
72
78
  */
73
- login(credentials: {
74
- /**
75
- * Identifier of the application you are using
76
- *
77
- * Note: This is usefull when you use Promptbook remote server for multiple apps/frontends, if its used just for single app, use here just "app" or "your-app-name"
78
- */
79
- readonly appId: string_app_id | null;
80
- /**
81
- * Username (for example email) of the user
82
- */
83
- readonly username: string_email | string;
84
- /**
85
- * Password of the user
86
- */
87
- readonly password: string_password;
88
- /**
89
- * Request object from express if you want to access some request data for example headers, IP address, etc.
90
- */
91
- readonly rawRequest: Request;
92
- /**
93
- * Response object from express if you want to add some custom headers.
94
- *
95
- * Note: It is not recommended to use this object to send body of the response because it can confuse the client
96
- */
97
- readonly rawResponse: Response;
98
- }): Promise<ApplicationRemoteServerOptionsLoginResponse<TCustomOptions>>;
79
+ login(loginRequest: LoginRequest): Promise<LoginResponse<TCustomOptions>>;
99
80
  /**
100
81
  * Creates llm execution tools for each client
101
82
  */
102
- createLlmExecutionTools(options: ApplicationRemoteServerClientOptions<TCustomOptions>): Promisable<LlmExecutionTools>;
83
+ createLlmExecutionTools(options: ApplicationModeIdentification<TCustomOptions>): Promisable<LlmExecutionTools>;
103
84
  };
104
85
  export type ApplicationRemoteServerClientOptions<TCustomOptions> = {
105
86
  /**
@@ -121,23 +102,61 @@ export type ApplicationRemoteServerClientOptions<TCustomOptions> = {
121
102
  *
122
103
  * Note: This is passed for example to `createLlmExecutionTools`
123
104
  */
124
- readonly userToken?: string_user_id;
105
+ readonly userToken?: string_token;
125
106
  /**
126
107
  * Additional arbitrary options to identify the client or to pass custom metadata
127
108
  */
128
109
  readonly customOptions?: TCustomOptions;
129
110
  };
130
- export type ApplicationRemoteServerOptionsLoginResponse<TCustomOptions> = {
111
+ /**
112
+ * Login request for the application mode
113
+ */
114
+ export type LoginRequest = {
115
+ /**
116
+ * Identifier of the application you are using
117
+ *
118
+ * Note: This is usefull when you use Promptbook remote server for multiple apps/frontends, if its used just for single app, use here just "app" or "your-app-name"
119
+ */
120
+ readonly appId: string_app_id | null;
121
+ /**
122
+ * Username (for example email) of the user
123
+ */
124
+ readonly username: string_email | string;
125
+ /**
126
+ * Password of the user
127
+ */
128
+ readonly password: string_password;
129
+ /**
130
+ * Request object from express if you want to access some request data for example headers, IP address, etc.
131
+ */
132
+ readonly rawRequest: Request;
133
+ /**
134
+ * Response object from express if you want to add some custom headers.
135
+ *
136
+ * Note: It is not recommended to use this object to send body of the response because it can confuse the client
137
+ */
138
+ readonly rawResponse: Response;
139
+ };
140
+ /**
141
+ * Login response for the application mode
142
+ */
143
+ export type LoginResponse<TCustomOptions> = {
131
144
  /**
132
145
  * Was the login successful
133
146
  */
134
147
  readonly isSuccess: boolean;
135
148
  /**
136
- *
149
+ * Message to display to the user, this message is always displayed
137
150
  */
138
151
  readonly message?: string;
152
+ /**
153
+ * Optional error if the login was not successful
154
+ */
139
155
  readonly error?: AuthenticationError;
140
- readonly identification?: PromptbookServer_Identification<TCustomOptions>;
156
+ /**
157
+ * Identification of the user to be used in the future requests
158
+ */
159
+ readonly identification?: Identification<TCustomOptions>;
141
160
  };
142
161
  /**
143
162
  * TODO: Constrain anonymous mode for specific models / providers
@@ -2,9 +2,9 @@ import type { PromptbookFetch } from '../../../execution/PromptbookFetch';
2
2
  /**
3
3
  * The built-in `fetch' function with a lightweight error handling wrapper as default fetch function used in Promptbook scrapers
4
4
  *
5
- * @private as default `fetch` function used in Promptbook scrapers
5
+ * @public exported from `@promptbook/core`
6
6
  */
7
- export declare const scraperFetch: PromptbookFetch;
7
+ export declare const promptbookFetch: PromptbookFetch;
8
8
  /**
9
9
  * TODO: [🧠] Maybe rename because it is not used only for scrapers but also in `$getCompiledBook`
10
10
  */
@@ -0,0 +1,40 @@
1
+ import type { PromptbookStorage } from '../_common/PromptbookStorage';
2
+ /**
3
+ * Stores data in .env variables
4
+ *
5
+ * 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`
6
+ *
7
+ * @private within the repository - for CLI utils
8
+ */
9
+ export declare class $EnvStorage<TItem> implements PromptbookStorage<TItem> {
10
+ private envFilename;
11
+ private $provideOrCreateEnvFile;
12
+ private transformKey;
13
+ /**
14
+ * Returns the number of key/value pairs currently present in the list associated with the object.
15
+ */
16
+ get length(): number;
17
+ /**
18
+ * Empties the list associated with the object of all key/value pairs, if there are any.
19
+ */
20
+ clear(): void;
21
+ /**
22
+ * 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.
23
+ */
24
+ getItem(key: string): Promise<TItem | null>;
25
+ /**
26
+ * 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.
27
+ */
28
+ key(index: number): string | null;
29
+ /**
30
+ * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
31
+ */
32
+ setItem(key: string, value: TItem): Promise<void>;
33
+ /**
34
+ * 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.
35
+ */
36
+ removeItem(key: string): void;
37
+ }
38
+ /**
39
+ * TODO: Write file more securely - ensure that there can be no accidental overwriting of existing variables and other content
40
+ */
@@ -325,6 +325,12 @@ export type string_css_selector = string;
325
325
  * For example `"https://collboard.com/9SeSQTupmQHwuSrLi"`
326
326
  */
327
327
  export type string_url = string;
328
+ /**
329
+ * Semantic helper
330
+ *
331
+ * For example `"https://s1.ptbk.io/promptbook"`
332
+ */
333
+ export type string_promptbook_server_url = string;
328
334
  /**
329
335
  * Semantic helper
330
336
  *
@@ -408,6 +414,13 @@ export type string_host = string;
408
414
  * Semantic helper
409
415
  */
410
416
  export type string_protocol = 'http:' | 'https:';
417
+ /**
418
+ * Semantic helper
419
+ *
420
+ * For example `"192.168.1.1"` (IPv4)
421
+ * For example `"2001:0db8:85a3:0000:0000:8a2e:0370:7334"` (IPv6)
422
+ */
423
+ export type string_ip_address = string;
411
424
  /**
412
425
  * Semantic helper
413
426
  *
@@ -521,6 +534,13 @@ export type string_person_profile = string;
521
534
  * For example `"MIT"`
522
535
  */
523
536
  export type string_license = string;
537
+ /**
538
+ * Semantic helper
539
+ *
540
+ * For example `"Pavol Hejný <pavol@ptbk.io> (https://www.pavolhejny.com/)"`
541
+ * For example `"AI Web, LLC <legal@ptbk.io> (https://www.ptbk.io/)"`
542
+ */
543
+ export type string_legal_entity = string | string_person_profile | string_title;
524
544
  /**
525
545
  * Semantic helper for attributes
526
546
  *
@@ -570,6 +590,12 @@ export type string_postprocessing_function_name = string;
570
590
  export type id = string | number;
571
591
  export type task_id = string;
572
592
  export type string_token = string;
593
+ /**
594
+ * Semantic helper
595
+ *
596
+ * Made by `identificationToPromptbookToken` exported from `@promptbook/core`
597
+ */
598
+ export type string_promptbook_token = string_token;
573
599
  export type string_license_token = string_token;
574
600
  export type string_password = string;
575
601
  export type string_ssh_key = string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptbook/documents",
3
- "version": "0.89.0-8",
3
+ "version": "0.89.0",
4
4
  "description": "It's time for a paradigm shift. The future of software in plain English, French or Latin",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -43,19 +43,23 @@
43
43
  "url": "https://github.com/webgptorg/promptbook/issues"
44
44
  },
45
45
  "homepage": "https://ptbk.io/",
46
+ "engines": {
47
+ "node": ">=16.0.0",
48
+ "npm": ">=8.0.0"
49
+ },
46
50
  "main": "./umd/index.umd.js",
47
51
  "module": "./esm/index.es.js",
48
52
  "typings": "./esm/typings/src/_packages/documents.index.d.ts",
49
53
  "peerDependencies": {
50
- "@promptbook/core": "0.89.0-8"
54
+ "@promptbook/core": "0.89.0"
51
55
  },
52
56
  "dependencies": {
53
57
  "colors": "1.4.0",
54
- "crypto": "^1.0.1",
58
+ "crypto": "1.0.1",
55
59
  "crypto-js": "4.2.0",
56
60
  "papaparse": "5.4.1",
57
61
  "prettier": "2.8.1",
58
- "rxjs": "^7.8.1",
62
+ "rxjs": "7.8.1",
59
63
  "spacetrim": "0.11.59",
60
64
  "waitasecond": "1.11.83"
61
65
  }
package/umd/index.umd.js CHANGED
@@ -26,7 +26,7 @@
26
26
  * @generated
27
27
  * @see https://github.com/webgptorg/promptbook
28
28
  */
29
- const PROMPTBOOK_ENGINE_VERSION = '0.89.0-8';
29
+ const PROMPTBOOK_ENGINE_VERSION = '0.89.0';
30
30
  /**
31
31
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
32
32
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -89,6 +89,7 @@
89
89
  * @public exported from `@promptbook/core`
90
90
  */
91
91
  const ADMIN_GITHUB_NAME = 'hejny';
92
+ // <- TODO: [🐊] Pick the best claim
92
93
  /**
93
94
  * When the title is not provided, the default title is used
94
95
  *
@@ -121,6 +122,7 @@
121
122
  infinity: '(infinity; ∞)',
122
123
  negativeInfinity: '(negative infinity; -∞)',
123
124
  unserializable: '(unserializable value)',
125
+ circular: '(circular JSON)',
124
126
  };
125
127
  /**
126
128
  * Small number limit
@@ -160,7 +162,7 @@
160
162
  */
161
163
  const DEFAULT_MAX_EXECUTION_ATTEMPTS = 10; // <- TODO: [🤹‍♂️]
162
164
  // <- TODO: [🕝] Make also `BOOKS_DIRNAME_ALTERNATIVES`
163
- // TODO: !!!!!! Just .promptbook dir, hardocode others
165
+ // TODO: Just `.promptbook` in config, hardcode subfolders like `download-cache` or `execution-cache`
164
166
  /**
165
167
  * Where to store the temporary downloads
166
168
  *
@@ -1068,9 +1070,60 @@
1068
1070
  * TODO: Maybe split `ParseError` and `ApplyError`
1069
1071
  */
1070
1072
 
1073
+ /**
1074
+ * This error type indicates that somewhere in the code non-Error object was thrown and it was wrapped into the `WrappedError`
1075
+ *
1076
+ * @public exported from `@promptbook/core`
1077
+ */
1078
+ class WrappedError extends Error {
1079
+ constructor(whatWasThrown) {
1080
+ const tag = `[🤮]`;
1081
+ console.error(tag, whatWasThrown);
1082
+ super(spaceTrim.spaceTrim(`
1083
+ Non-Error object was thrown
1084
+
1085
+ Note: Look for ${tag} in the console for more details
1086
+ Please report issue on ${ADMIN_EMAIL}
1087
+ `));
1088
+ this.name = 'WrappedError';
1089
+ Object.setPrototypeOf(this, WrappedError.prototype);
1090
+ }
1091
+ }
1092
+
1093
+ /**
1094
+ * Helper used in catch blocks to assert that the error is an instance of `Error`
1095
+ *
1096
+ * @param whatWasThrown Any object that was thrown
1097
+ * @returns Nothing if the error is an instance of `Error`
1098
+ * @throws `WrappedError` or `UnexpectedError` if the error is not standard
1099
+ *
1100
+ * @private within the repository
1101
+ */
1102
+ function assertsError(whatWasThrown) {
1103
+ // Case 1: Handle error which was rethrown as `WrappedError`
1104
+ if (whatWasThrown instanceof WrappedError) {
1105
+ const wrappedError = whatWasThrown;
1106
+ throw wrappedError;
1107
+ }
1108
+ // Case 2: Handle unexpected errors
1109
+ if (whatWasThrown instanceof UnexpectedError) {
1110
+ const unexpectedError = whatWasThrown;
1111
+ throw unexpectedError;
1112
+ }
1113
+ // Case 3: Handle standard errors - keep them up to consumer
1114
+ if (whatWasThrown instanceof Error) {
1115
+ return;
1116
+ }
1117
+ // Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
1118
+ throw new WrappedError(whatWasThrown);
1119
+ }
1120
+
1071
1121
  /**
1072
1122
  * Function isValidJsonString will tell you if the string is valid JSON or not
1073
1123
  *
1124
+ * @param value The string to check
1125
+ * @returns True if the string is a valid JSON string, false otherwise
1126
+ *
1074
1127
  * @public exported from `@promptbook/utils`
1075
1128
  */
1076
1129
  function isValidJsonString(value /* <- [👨‍⚖️] */) {
@@ -1079,9 +1132,7 @@
1079
1132
  return true;
1080
1133
  }
1081
1134
  catch (error) {
1082
- if (!(error instanceof Error)) {
1083
- throw error;
1084
- }
1135
+ assertsError(error);
1085
1136
  if (error.message.includes('Unexpected token')) {
1086
1137
  return false;
1087
1138
  }
@@ -1434,9 +1485,7 @@
1434
1485
  JSON.stringify(value); // <- TODO: [0]
1435
1486
  }
1436
1487
  catch (error) {
1437
- if (!(error instanceof Error)) {
1438
- throw error;
1439
- }
1488
+ assertsError(error);
1440
1489
  throw new UnexpectedError(spaceTrim__default["default"]((block) => `
1441
1490
  \`${name}\` is not serializable
1442
1491
 
@@ -2207,7 +2256,7 @@
2207
2256
  }
2208
2257
  }
2209
2258
  /**
2210
- * TODO: !!!!!! Add id to all errors
2259
+ * TODO: [🧠][🌂] Add id to all errors
2211
2260
  */
2212
2261
 
2213
2262
  /**
@@ -2385,6 +2434,19 @@
2385
2434
  }
2386
2435
  }
2387
2436
 
2437
+ /**
2438
+ * Error thrown when a fetch request fails
2439
+ *
2440
+ * @public exported from `@promptbook/core`
2441
+ */
2442
+ class PromptbookFetchError extends Error {
2443
+ constructor(message) {
2444
+ super(message);
2445
+ this.name = 'PromptbookFetchError';
2446
+ Object.setPrototypeOf(this, PromptbookFetchError.prototype);
2447
+ }
2448
+ }
2449
+
2388
2450
  /**
2389
2451
  * Index of all custom errors
2390
2452
  *
@@ -2405,7 +2467,10 @@
2405
2467
  PipelineExecutionError,
2406
2468
  PipelineLogicError,
2407
2469
  PipelineUrlError,
2470
+ AuthenticationError,
2471
+ PromptbookFetchError,
2408
2472
  UnexpectedError,
2473
+ WrappedError,
2409
2474
  // TODO: [🪑]> VersionMismatchError,
2410
2475
  };
2411
2476
  /**
@@ -2422,7 +2487,6 @@
2422
2487
  TypeError,
2423
2488
  URIError,
2424
2489
  AggregateError,
2425
- AuthenticationError,
2426
2490
  /*
2427
2491
  Note: Not widely supported
2428
2492
  > InternalError,
@@ -2545,8 +2609,8 @@
2545
2609
  updatedAt = new Date();
2546
2610
  errors.push(...executionResult.errors);
2547
2611
  warnings.push(...executionResult.warnings);
2548
- // <- TODO: !!! Only unique errors and warnings should be added (or filtered)
2549
- // TODO: [🧠] !!! errors, warning, isSuccessful are redundant both in `ExecutionTask` and `ExecutionTask.currentValue`
2612
+ // <- TODO: [🌂] Only unique errors and warnings should be added (or filtered)
2613
+ // TODO: [🧠] !! errors, warning, isSuccessful are redundant both in `ExecutionTask` and `ExecutionTask.currentValue`
2550
2614
  // Also maybe move `ExecutionTask.currentValue.usage` -> `ExecutionTask.usage`
2551
2615
  // And delete `ExecutionTask.currentValue.preparedPipeline`
2552
2616
  assertsTaskSuccessful(executionResult);
@@ -2556,6 +2620,7 @@
2556
2620
  partialResultSubject.next(executionResult);
2557
2621
  }
2558
2622
  catch (error) {
2623
+ assertsError(error);
2559
2624
  status = 'ERROR';
2560
2625
  errors.push(error);
2561
2626
  partialResultSubject.error(error);
@@ -2947,14 +3012,15 @@
2947
3012
  }
2948
3013
  }
2949
3014
  catch (error) {
2950
- if (!(error instanceof Error) || error instanceof UnexpectedError) {
3015
+ assertsError(error);
3016
+ if (error instanceof UnexpectedError) {
2951
3017
  throw error;
2952
3018
  }
2953
3019
  errors.push({ llmExecutionTools, error });
2954
3020
  }
2955
3021
  }
2956
3022
  if (errors.length === 1) {
2957
- throw errors[0];
3023
+ throw errors[0].error;
2958
3024
  }
2959
3025
  else if (errors.length > 1) {
2960
3026
  throw new PipelineExecutionError(
@@ -3392,17 +3458,22 @@
3392
3458
  /**
3393
3459
  * The built-in `fetch' function with a lightweight error handling wrapper as default fetch function used in Promptbook scrapers
3394
3460
  *
3395
- * @private as default `fetch` function used in Promptbook scrapers
3461
+ * @public exported from `@promptbook/core`
3396
3462
  */
3397
- const scraperFetch = async (url, init) => {
3463
+ const promptbookFetch = async (urlOrRequest, init) => {
3398
3464
  try {
3399
- return await fetch(url, init);
3465
+ return await fetch(urlOrRequest, init);
3400
3466
  }
3401
3467
  catch (error) {
3402
- if (!(error instanceof Error)) {
3403
- throw error;
3468
+ assertsError(error);
3469
+ let url;
3470
+ if (typeof urlOrRequest === 'string') {
3471
+ url = urlOrRequest;
3472
+ }
3473
+ else if (urlOrRequest instanceof Request) {
3474
+ url = urlOrRequest.url;
3404
3475
  }
3405
- throw new KnowledgeScrapeError(spaceTrim__default["default"]((block) => `
3476
+ throw new PromptbookFetchError(spaceTrim__default["default"]((block) => `
3406
3477
  Can not fetch "${url}"
3407
3478
 
3408
3479
  Fetch error:
@@ -3423,7 +3494,7 @@
3423
3494
  async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
3424
3495
  // console.log('!! makeKnowledgeSourceHandler', knowledgeSource);
3425
3496
  var _a;
3426
- const { fetch = scraperFetch } = tools;
3497
+ const { fetch = promptbookFetch } = tools;
3427
3498
  const { knowledgeSourceContent } = knowledgeSource;
3428
3499
  let { name } = knowledgeSource;
3429
3500
  const { rootDirname = null,
@@ -3625,9 +3696,7 @@
3625
3696
  knowledgePreparedUnflatten[index] = pieces;
3626
3697
  }
3627
3698
  catch (error) {
3628
- if (!(error instanceof Error)) {
3629
- throw error;
3630
- }
3699
+ assertsError(error);
3631
3700
  console.warn(error);
3632
3701
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
3633
3702
  }
@@ -3919,13 +3988,19 @@
3919
3988
  return value.toISOString();
3920
3989
  }
3921
3990
  else {
3922
- return JSON.stringify(value);
3991
+ try {
3992
+ return JSON.stringify(value);
3993
+ }
3994
+ catch (error) {
3995
+ if (error instanceof TypeError && error.message.includes('circular structure')) {
3996
+ return VALUE_STRINGS.circular;
3997
+ }
3998
+ throw error;
3999
+ }
3923
4000
  }
3924
4001
  }
3925
4002
  catch (error) {
3926
- if (!(error instanceof Error)) {
3927
- throw error;
3928
- }
4003
+ assertsError(error);
3929
4004
  console.error(error);
3930
4005
  return VALUE_STRINGS.unserializable;
3931
4006
  }
@@ -3982,9 +4057,7 @@
3982
4057
  }
3983
4058
  }
3984
4059
  catch (error) {
3985
- if (!(error instanceof Error)) {
3986
- throw error;
3987
- }
4060
+ assertsError(error);
3988
4061
  throw new ParseError(spaceTrim.spaceTrim((block) => `
3989
4062
  Can not extract variables from the script
3990
4063
  ${block(error.stack || error.message)}
@@ -4103,6 +4176,28 @@
4103
4176
  // encoding: 'utf-8',
4104
4177
  });
4105
4178
 
4179
+ /**
4180
+ * Function to check if a string is valid CSV
4181
+ *
4182
+ * @param value The string to check
4183
+ * @returns True if the string is a valid CSV string, false otherwise
4184
+ *
4185
+ * @public exported from `@promptbook/utils`
4186
+ */
4187
+ function isValidCsvString(value) {
4188
+ try {
4189
+ // A simple check for CSV format: at least one comma and no invalid characters
4190
+ if (value.includes(',') && /^[\w\s,"']+$/.test(value)) {
4191
+ return true;
4192
+ }
4193
+ return false;
4194
+ }
4195
+ catch (error) {
4196
+ assertsError(error);
4197
+ return false;
4198
+ }
4199
+ }
4200
+
4106
4201
  /**
4107
4202
  * Definition for CSV spreadsheet
4108
4203
  *
@@ -4113,7 +4208,7 @@
4113
4208
  formatName: 'CSV',
4114
4209
  aliases: ['SPREADSHEET', 'TABLE'],
4115
4210
  isValid(value, settings, schema) {
4116
- return true;
4211
+ return isValidCsvString(value);
4117
4212
  },
4118
4213
  canBeValid(partialValue, settings, schema) {
4119
4214
  return true;
@@ -4267,6 +4362,30 @@
4267
4362
  * TODO: [🏢] Allow to expect something inside each item of list and other formats
4268
4363
  */
4269
4364
 
4365
+ /**
4366
+ * Function to check if a string is valid XML
4367
+ *
4368
+ * @param value
4369
+ * @returns True if the string is a valid XML string, false otherwise
4370
+ *
4371
+ * @public exported from `@promptbook/utils`
4372
+ */
4373
+ function isValidXmlString(value) {
4374
+ try {
4375
+ const parser = new DOMParser();
4376
+ const parsedDocument = parser.parseFromString(value, 'application/xml');
4377
+ const parserError = parsedDocument.getElementsByTagName('parsererror');
4378
+ if (parserError.length > 0) {
4379
+ return false;
4380
+ }
4381
+ return true;
4382
+ }
4383
+ catch (error) {
4384
+ assertsError(error);
4385
+ return false;
4386
+ }
4387
+ }
4388
+
4270
4389
  /**
4271
4390
  * Definition for XML format
4272
4391
  *
@@ -4276,7 +4395,7 @@
4276
4395
  formatName: 'XML',
4277
4396
  mimeType: 'application/xml',
4278
4397
  isValid(value, settings, schema) {
4279
- return true;
4398
+ return isValidXmlString(value);
4280
4399
  },
4281
4400
  canBeValid(partialValue, settings, schema) {
4282
4401
  return true;
@@ -4849,9 +4968,7 @@
4849
4968
  break scripts;
4850
4969
  }
4851
4970
  catch (error) {
4852
- if (!(error instanceof Error)) {
4853
- throw error;
4854
- }
4971
+ assertsError(error);
4855
4972
  if (error instanceof UnexpectedError) {
4856
4973
  throw error;
4857
4974
  }
@@ -4921,9 +5038,7 @@
4921
5038
  break scripts;
4922
5039
  }
4923
5040
  catch (error) {
4924
- if (!(error instanceof Error)) {
4925
- throw error;
4926
- }
5041
+ assertsError(error);
4927
5042
  if (error instanceof UnexpectedError) {
4928
5043
  throw error;
4929
5044
  }
@@ -5544,9 +5659,7 @@
5544
5659
  await Promise.all(resolving);
5545
5660
  }
5546
5661
  catch (error /* <- Note: [3] */) {
5547
- if (!(error instanceof Error)) {
5548
- throw error;
5549
- }
5662
+ assertsError(error);
5550
5663
  // Note: No need to rethrow UnexpectedError
5551
5664
  // if (error instanceof UnexpectedError) {
5552
5665
  // Note: Count usage, [🧠] Maybe put to separate function executionReportJsonToUsage + DRY [🤹‍♂️]