@promptbook/cli 0.88.0-8 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,10 +23,6 @@
23
23
 
24
24
 
25
25
 
26
- <blockquote style="color: #ff8811">
27
- <b>⚠ Warning:</b> This is a pre-release version of the library. It is not yet ready for production use. Please look at <a href="https://www.npmjs.com/package/@promptbook/core?activeTab=versions">latest stable release</a>.
28
- </blockquote>
29
-
30
26
  ## 📦 Package `@promptbook/cli`
31
27
 
32
28
  - Promptbooks are [divided into several](#-packages) packages, all are published from [single monorepo](https://github.com/webgptorg/promptbook).
@@ -124,6 +120,9 @@ This shift is going to happen, whether we are ready for it or not. Our mission i
124
120
 
125
121
 
126
122
 
123
+
124
+
125
+
127
126
  ## 🚀 Get started
128
127
 
129
128
  Take a look at the simple starter kit with books integrated into the **Hello World** sample applications:
@@ -135,6 +134,8 @@ Take a look at the simple starter kit with books integrated into the **Hello Wor
135
134
 
136
135
 
137
136
 
137
+
138
+
138
139
  ## 💜 The Promptbook Project
139
140
 
140
141
  Promptbook project is ecosystem of multiple projects and tools, following is a list of most important pieces of the project:
@@ -170,6 +171,14 @@ Promptbook project is ecosystem of multiple projects and tools, following is a l
170
171
  </tbody>
171
172
  </table>
172
173
 
174
+ Hello world examples:
175
+
176
+ - [Hello world](https://github.com/webgptorg/hello-world)
177
+ - [Hello world in Node.js](https://github.com/webgptorg/hello-world-node-js)
178
+ - [Hello world in Next.js](https://github.com/webgptorg/hello-world-next-js)
179
+
180
+
181
+
173
182
  We also have a community of developers and users of **Promptbook**:
174
183
 
175
184
  - [Discord community](https://discord.gg/x3QWNaa89N)
@@ -336,16 +345,9 @@ Or you can install them separately:
336
345
 
337
346
  ## 📚 Dictionary
338
347
 
339
-
340
-
341
-
342
-
343
-
344
- ### 📚 Dictionary
345
-
346
348
  The following glossary is used to clarify certain concepts:
347
349
 
348
- #### General LLM / AI terms
350
+ ### General LLM / AI terms
349
351
 
350
352
  - **Prompt drift** is a phenomenon where the AI model starts to generate outputs that are not aligned with the original prompt. This can happen due to the model's training data, the prompt's wording, or the model's architecture.
351
353
  - **Pipeline, workflow or chain** is a sequence of tasks that are executed in a specific order. In the context of AI, a pipeline can refer to a sequence of AI models that are used to process data.
@@ -358,11 +360,11 @@ The following glossary is used to clarify certain concepts:
358
360
 
359
361
 
360
362
 
361
- _Note: Thos section is not complete dictionary, more list of general AI / LLM terms that has connection with Promptbook_
363
+ _Note: This section is not complete dictionary, more list of general AI / LLM terms that has connection with Promptbook_
362
364
 
363
365
 
364
366
 
365
- #### 💯 Core concepts
367
+ ### 💯 Core concepts
366
368
 
367
369
  - [📚 Collection of pipelines](https://github.com/webgptorg/promptbook/discussions/65)
368
370
  - [📯 Pipeline](https://github.com/webgptorg/promptbook/discussions/64)
@@ -375,7 +377,7 @@ _Note: Thos section is not complete dictionary, more list of general AI / LLM te
375
377
  - [🔣 Words not tokens](https://github.com/webgptorg/promptbook/discussions/29)
376
378
  - [☯ Separation of concerns](https://github.com/webgptorg/promptbook/discussions/32)
377
379
 
378
- ##### Advanced concepts
380
+ #### Advanced concepts
379
381
 
380
382
  - [📚 Knowledge (Retrieval-augmented generation)](https://github.com/webgptorg/promptbook/discussions/41)
381
383
  - [🌏 Remote server](https://github.com/webgptorg/promptbook/discussions/89)
@@ -392,17 +394,9 @@ _Note: Thos section is not complete dictionary, more list of general AI / LLM te
392
394
 
393
395
 
394
396
 
395
- ### Terms specific to Promptbook TypeScript implementation
396
-
397
- - Anonymous mode
398
- - Application mode
399
-
400
-
401
-
402
- ## 🔌 Usage in Typescript / Javascript
397
+ ## 🚂 Promptbook Engine
403
398
 
404
- - [Simple usage](./examples/usage/simple-script)
405
- - [Usage with client and remote server](./examples/usage/remote)
399
+ ![Schema of Promptbook Engine](./documents/promptbook-engine.svg)
406
400
 
407
401
  ## ➕➖ When to use Promptbook?
408
402
 
@@ -468,11 +462,11 @@ See [TODO.md](./TODO.md)
468
462
  <div style="display: flex; align-items: center; gap: 20px;">
469
463
 
470
464
  <a href="https://promptbook.studio/">
471
- <img src="./design/promptbook-studio-logo.png" alt="Partner 3" height="100">
465
+ <img src="./design/promptbook-studio-logo.png" alt="Partner 3" height="70">
472
466
  </a>
473
467
 
474
468
  <a href="https://technologickainkubace.org/en/about-technology-incubation/about-the-project/">
475
- <img src="./other/partners/CI-Technology-Incubation.png" alt="Technology Incubation" height="100">
469
+ <img src="./other/partners/CI-Technology-Incubation.png" alt="Technology Incubation" height="70">
476
470
  </a>
477
471
 
478
472
  </div>
package/esm/index.es.js CHANGED
@@ -6,13 +6,13 @@ import { basename, join, dirname, relative } from 'path';
6
6
  import { stat, access, constants, readFile, writeFile, readdir, mkdir, unlink, rm, rename, rmdir } from 'fs/promises';
7
7
  import hexEncoder from 'crypto-js/enc-hex';
8
8
  import sha256 from 'crypto-js/sha256';
9
+ import { randomBytes } from 'crypto';
9
10
  import * as dotenv from 'dotenv';
10
11
  import { spawn } from 'child_process';
11
12
  import JSZip from 'jszip';
12
13
  import { format } from 'prettier';
13
14
  import parserHtml from 'prettier/parser-html';
14
15
  import { Subject } from 'rxjs';
15
- import { randomBytes } from 'crypto';
16
16
  import { parse, unparse } from 'papaparse';
17
17
  import { SHA256 } from 'crypto-js';
18
18
  import { lookup, extension } from 'mime-types';
@@ -44,7 +44,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
44
44
  * @generated
45
45
  * @see https://github.com/webgptorg/promptbook
46
46
  */
47
- const PROMPTBOOK_ENGINE_VERSION = '0.88.0-8';
47
+ const PROMPTBOOK_ENGINE_VERSION = '0.88.0';
48
48
  /**
49
49
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
50
50
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -204,7 +204,7 @@ const DEFAULT_MAX_PARALLEL_COUNT = 5; // <- TODO: [🤹‍♂️]
204
204
  *
205
205
  * @public exported from `@promptbook/core`
206
206
  */
207
- const DEFAULT_MAX_EXECUTION_ATTEMPTS = 3; // <- TODO: [🤹‍♂️]
207
+ const DEFAULT_MAX_EXECUTION_ATTEMPTS = 10; // <- TODO: [🤹‍♂️]
208
208
  /**
209
209
  * Where to store your books
210
210
  * This is kind of a "src" for your books
@@ -1498,6 +1498,21 @@ class FileCacheStorage {
1498
1498
  * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
1499
1499
  */
1500
1500
 
1501
+ /**
1502
+ * Generates random token
1503
+ *
1504
+ * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
1505
+ *
1506
+ * @private internal helper function
1507
+ * @returns secure random token
1508
+ */
1509
+ function $randomToken(randomness) {
1510
+ return randomBytes(randomness).toString('hex');
1511
+ }
1512
+ /**
1513
+ * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
1514
+ */
1515
+
1501
1516
  /**
1502
1517
  * This error indicates errors during the execution of the pipeline
1503
1518
  *
@@ -1505,11 +1520,17 @@ class FileCacheStorage {
1505
1520
  */
1506
1521
  class PipelineExecutionError extends Error {
1507
1522
  constructor(message) {
1523
+ // Added id parameter
1508
1524
  super(message);
1509
1525
  this.name = 'PipelineExecutionError';
1526
+ // TODO: [🐙] DRY - Maybe $randomId
1527
+ this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid simmilar char conflicts */)}`;
1510
1528
  Object.setPrototypeOf(this, PipelineExecutionError.prototype);
1511
1529
  }
1512
1530
  }
1531
+ /**
1532
+ * TODO: !!!!!! Add id to all errors
1533
+ */
1513
1534
 
1514
1535
  /**
1515
1536
  * Stores data in memory (HEAP)
@@ -4074,18 +4095,33 @@ function isPipelinePrepared(pipeline) {
4074
4095
  */
4075
4096
 
4076
4097
  /**
4077
- * Generates random token
4078
- *
4079
- * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
4080
- *
4081
- * @private internal helper function
4082
- * @returns secure random token
4098
+ * Recursively converts JSON strings to JSON objects
4099
+
4100
+ * @public exported from `@promptbook/utils`
4083
4101
  */
4084
- function $randomToken(randomness) {
4085
- return randomBytes(randomness).toString('hex');
4102
+ function jsonStringsToJsons(object) {
4103
+ if (object === null) {
4104
+ return object;
4105
+ }
4106
+ if (Array.isArray(object)) {
4107
+ return object.map(jsonStringsToJsons);
4108
+ }
4109
+ if (typeof object !== 'object') {
4110
+ return object;
4111
+ }
4112
+ const newObject = { ...object };
4113
+ for (const [key, value] of Object.entries(object)) {
4114
+ if (typeof value === 'string' && isValidJsonString(value)) {
4115
+ newObject[key] = JSON.parse(value);
4116
+ }
4117
+ else {
4118
+ newObject[key] = jsonStringsToJsons(value);
4119
+ }
4120
+ }
4121
+ return newObject;
4086
4122
  }
4087
4123
  /**
4088
- * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
4124
+ * TODO: Type the return type correctly
4089
4125
  */
4090
4126
 
4091
4127
  /**
@@ -4238,7 +4274,7 @@ const ALL_ERRORS = {
4238
4274
  * @public exported from `@promptbook/utils`
4239
4275
  */
4240
4276
  function deserializeError(error) {
4241
- const { name, stack } = error;
4277
+ const { name, stack, id } = error; // Added id
4242
4278
  let { message } = error;
4243
4279
  let ErrorClass = ALL_ERRORS[error.name];
4244
4280
  if (ErrorClass === undefined) {
@@ -4253,7 +4289,9 @@ function deserializeError(error) {
4253
4289
  ${block(stack || '')}
4254
4290
  `);
4255
4291
  }
4256
- return new ErrorClass(message);
4292
+ const deserializedError = new ErrorClass(message);
4293
+ deserializedError.id = id; // Assign id to the error object
4294
+ return deserializedError;
4257
4295
  }
4258
4296
 
4259
4297
  /**
@@ -4303,17 +4341,19 @@ function assertsTaskSuccessful(executionResult) {
4303
4341
  */
4304
4342
  function createTask(options) {
4305
4343
  const { taskType, taskProcessCallback } = options;
4344
+ // TODO: [🐙] DRY
4306
4345
  const taskId = `${taskType.toLowerCase().substring(0, 4)}-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid simmilar char conflicts */)}`;
4307
4346
  let status = 'RUNNING';
4308
4347
  const createdAt = new Date();
4309
4348
  let updatedAt = createdAt;
4310
4349
  const errors = [];
4311
4350
  const warnings = [];
4312
- const currentValue = {};
4351
+ let currentValue = {};
4313
4352
  const partialResultSubject = new Subject();
4314
4353
  // <- Note: Not using `BehaviorSubject` because on error we can't access the last value
4315
4354
  const finalResultPromise = /* not await */ taskProcessCallback((newOngoingResult) => {
4316
4355
  Object.assign(currentValue, newOngoingResult);
4356
+ // <- TODO: assign deep
4317
4357
  partialResultSubject.next(newOngoingResult);
4318
4358
  });
4319
4359
  finalResultPromise
@@ -4333,7 +4373,8 @@ function createTask(options) {
4333
4373
  // And delete `ExecutionTask.currentValue.preparedPipeline`
4334
4374
  assertsTaskSuccessful(executionResult);
4335
4375
  status = 'FINISHED';
4336
- Object.assign(currentValue, executionResult);
4376
+ currentValue = jsonStringsToJsons(executionResult);
4377
+ // <- TODO: [🧠] Is this a good idea to convert JSON strins to JSONs?
4337
4378
  partialResultSubject.next(executionResult);
4338
4379
  }
4339
4380
  catch (error) {
@@ -4397,19 +4438,21 @@ function createTask(options) {
4397
4438
  */
4398
4439
  function serializeError(error) {
4399
4440
  const { name, message, stack } = error;
4441
+ const { id } = error;
4400
4442
  if (!Object.keys(ALL_ERRORS).includes(name)) {
4401
4443
  console.error(spaceTrim((block) => `
4402
-
4444
+
4403
4445
  Cannot serialize error with name "${name}"
4404
4446
 
4405
4447
  ${block(stack || message)}
4406
-
4448
+
4407
4449
  `));
4408
4450
  }
4409
4451
  return {
4410
4452
  name: name,
4411
4453
  message,
4412
4454
  stack,
4455
+ id, // Include id in the serialized object
4413
4456
  };
4414
4457
  }
4415
4458
 
@@ -5142,6 +5185,9 @@ function countCharacters(text) {
5142
5185
  text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
5143
5186
  return text.length;
5144
5187
  }
5188
+ /**
5189
+ * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
5190
+ */
5145
5191
 
5146
5192
  /**
5147
5193
  * Number of characters per standard line with 11pt Arial font size.
@@ -5173,6 +5219,9 @@ function countLines(text) {
5173
5219
  const lines = text.split('\n');
5174
5220
  return lines.reduce((count, line) => count + Math.ceil(line.length / CHARACTERS_PER_STANDARD_LINE), 0);
5175
5221
  }
5222
+ /**
5223
+ * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
5224
+ */
5176
5225
 
5177
5226
  /**
5178
5227
  * Counts number of pages in the text
@@ -5184,6 +5233,9 @@ function countLines(text) {
5184
5233
  function countPages(text) {
5185
5234
  return Math.ceil(countLines(text) / LINES_PER_STANDARD_PAGE);
5186
5235
  }
5236
+ /**
5237
+ * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
5238
+ */
5187
5239
 
5188
5240
  /**
5189
5241
  * Counts number of paragraphs in the text
@@ -5193,6 +5245,9 @@ function countPages(text) {
5193
5245
  function countParagraphs(text) {
5194
5246
  return text.split(/\n\s*\n/).filter((paragraph) => paragraph.trim() !== '').length;
5195
5247
  }
5248
+ /**
5249
+ * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
5250
+ */
5196
5251
 
5197
5252
  /**
5198
5253
  * Split text into sentences
@@ -5210,6 +5265,9 @@ function splitIntoSentences(text) {
5210
5265
  function countSentences(text) {
5211
5266
  return splitIntoSentences(text).length;
5212
5267
  }
5268
+ /**
5269
+ * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
5270
+ */
5213
5271
 
5214
5272
  /**
5215
5273
  * Counts number of words in the text
@@ -5223,6 +5281,9 @@ function countWords(text) {
5223
5281
  text = text.replace(/([a-z])([A-Z])/g, '$1 $2');
5224
5282
  return text.split(/[^a-zа-я0-9]+/i).filter((word) => word.length > 0).length;
5225
5283
  }
5284
+ /**
5285
+ * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
5286
+ */
5226
5287
 
5227
5288
  /**
5228
5289
  * Index of all counter functions
@@ -12309,7 +12370,7 @@ function $initializeRunCommand(program) {
12309
12370
  pipeline,
12310
12371
  tools,
12311
12372
  isNotPreparedWarningSupressed: true,
12312
- maxExecutionAttempts: 3,
12373
+ maxExecutionAttempts: DEFAULT_MAX_EXECUTION_ATTEMPTS,
12313
12374
  // <- TODO: Why "LLM execution failed undefinedx"
12314
12375
  maxParallelCount: 1, // <- TODO: Pass CLI argument
12315
12376
  });