@promptbook/pdf 0.92.0-5 → 0.92.0-6

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/esm/index.es.js CHANGED
@@ -26,7 +26,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
26
26
  * @generated
27
27
  * @see https://github.com/webgptorg/promptbook
28
28
  */
29
- const PROMPTBOOK_ENGINE_VERSION = '0.92.0-5';
29
+ const PROMPTBOOK_ENGINE_VERSION = '0.92.0-6';
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
@@ -2137,6 +2137,45 @@ function isPipelinePrepared(pipeline) {
2137
2137
  * - [♨] Are tasks prepared
2138
2138
  */
2139
2139
 
2140
+ /**
2141
+ * Converts a JavaScript Object Notation (JSON) string into an object.
2142
+ *
2143
+ * Note: This is wrapper around `JSON.parse()` with better error and type handling
2144
+ *
2145
+ * @public exported from `@promptbook/utils`
2146
+ */
2147
+ function jsonParse(value) {
2148
+ if (value === undefined) {
2149
+ throw new Error(`Can not parse JSON from undefined value.`);
2150
+ }
2151
+ else if (typeof value !== 'string') {
2152
+ console.error('Can not parse JSON from non-string value.', { text: value });
2153
+ throw new Error(spaceTrim(`
2154
+ Can not parse JSON from non-string value.
2155
+
2156
+ The value type: ${typeof value}
2157
+ See more in console.
2158
+ `));
2159
+ }
2160
+ try {
2161
+ return JSON.parse(value);
2162
+ }
2163
+ catch (error) {
2164
+ if (!(error instanceof Error)) {
2165
+ throw error;
2166
+ }
2167
+ throw new Error(spaceTrim((block) => `
2168
+ ${block(error.message)}
2169
+
2170
+ The JSON text:
2171
+ ${block(value)}
2172
+ `));
2173
+ }
2174
+ }
2175
+ /**
2176
+ * TODO: !!!! Use in Promptbook.studio
2177
+ */
2178
+
2140
2179
  /**
2141
2180
  * Recursively converts JSON strings to JSON objects
2142
2181
 
@@ -2155,7 +2194,7 @@ function jsonStringsToJsons(object) {
2155
2194
  const newObject = { ...object };
2156
2195
  for (const [key, value] of Object.entries(object)) {
2157
2196
  if (typeof value === 'string' && isValidJsonString(value)) {
2158
- newObject[key] = JSON.parse(value);
2197
+ newObject[key] = jsonParse(value);
2159
2198
  }
2160
2199
  else {
2161
2200
  newObject[key] = jsonStringsToJsons(value);
@@ -3002,7 +3041,7 @@ async function preparePersona(personaDescription, tools, options) {
3002
3041
  }).asPromise();
3003
3042
  const { outputParameters } = result;
3004
3043
  const { modelsRequirements: modelsRequirementsJson } = outputParameters;
3005
- const modelsRequirementsUnchecked = JSON.parse(modelsRequirementsJson);
3044
+ const modelsRequirementsUnchecked = jsonParse(modelsRequirementsJson);
3006
3045
  if (isVerbose) {
3007
3046
  console.info(`PERSONA ${personaDescription}`, modelsRequirementsUnchecked);
3008
3047
  }
@@ -3458,7 +3497,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
3458
3497
  > },
3459
3498
  */
3460
3499
  async asJson() {
3461
- return JSON.parse(await tools.fs.readFile(filename, 'utf-8'));
3500
+ return jsonParse(await tools.fs.readFile(filename, 'utf-8'));
3462
3501
  },
3463
3502
  async asText() {
3464
3503
  return await tools.fs.readFile(filename, 'utf-8');
@@ -5145,13 +5184,79 @@ async function getExamplesForTask(task) {
5145
5184
  /**
5146
5185
  * @@@
5147
5186
  *
5187
+ * Here is the place where RAG (retrieval-augmented generation) happens
5188
+ *
5148
5189
  * @private internal utility of `createPipelineExecutor`
5149
5190
  */
5150
5191
  async function getKnowledgeForTask(options) {
5151
- const { preparedPipeline, task } = options;
5152
- return preparedPipeline.knowledgePieces.map(({ content }) => `- ${content}`).join('\n');
5192
+ const { tools, preparedPipeline, task } = options;
5193
+ const firstKnowlegePiece = preparedPipeline.knowledgePieces[0];
5194
+ const firstKnowlegeIndex = firstKnowlegePiece === null || firstKnowlegePiece === void 0 ? void 0 : firstKnowlegePiece.index[0];
5195
+ // <- TODO: Do not use just first knowledge piece and first index to determine embedding model, use also keyword search
5196
+ if (firstKnowlegePiece === undefined || firstKnowlegeIndex === undefined) {
5197
+ return 'No knowledge pieces found';
5198
+ }
5199
+ // TODO: [🚐] Make arrayable LLMs -> single LLM DRY
5200
+ const _llms = arrayableToArray(tools.llm);
5201
+ const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
5202
+ const taskEmbeddingPrompt = {
5203
+ title: 'Knowledge Search',
5204
+ modelRequirements: {
5205
+ modelVariant: 'EMBEDDING',
5206
+ modelName: firstKnowlegeIndex.modelName,
5207
+ },
5208
+ content: task.content,
5209
+ parameters: {
5210
+ /* !!!!!!!! */
5211
+ },
5212
+ };
5213
+ const taskEmbeddingResult = await llmTools.callEmbeddingModel(taskEmbeddingPrompt);
5214
+ const knowledgePiecesWithRelevance = preparedPipeline.knowledgePieces.map((knowledgePiece) => {
5215
+ const { index } = knowledgePiece;
5216
+ const knowledgePieceIndex = index.find((i) => i.modelName === firstKnowlegeIndex.modelName);
5217
+ // <- TODO: Do not use just first knowledge piece and first index to determine embedding model
5218
+ if (knowledgePieceIndex === undefined) {
5219
+ return {
5220
+ content: knowledgePiece.content,
5221
+ relevance: 0,
5222
+ };
5223
+ }
5224
+ const relevance = computeCosineSimilarity(knowledgePieceIndex.position, taskEmbeddingResult.content);
5225
+ return {
5226
+ content: knowledgePiece.content,
5227
+ relevance,
5228
+ };
5229
+ });
5230
+ const knowledgePiecesSorted = knowledgePiecesWithRelevance.sort((a, b) => a.relevance - b.relevance);
5231
+ const knowledgePiecesLimited = knowledgePiecesSorted.slice(0, 5);
5232
+ console.log('!!! Embedding', {
5233
+ task,
5234
+ taskEmbeddingPrompt,
5235
+ taskEmbeddingResult,
5236
+ firstKnowlegePiece,
5237
+ firstKnowlegeIndex,
5238
+ knowledgePiecesWithRelevance,
5239
+ knowledgePiecesSorted,
5240
+ knowledgePiecesLimited,
5241
+ });
5242
+ return knowledgePiecesLimited.map(({ content }) => `- ${content}`).join('\n');
5153
5243
  // <- TODO: [🧠] Some smart aggregation of knowledge pieces, single-line vs multi-line vs mixed
5154
5244
  }
5245
+ // TODO: !!!!!! Annotate + to new file
5246
+ function computeCosineSimilarity(embeddingVector1, embeddingVector2) {
5247
+ if (embeddingVector1.length !== embeddingVector2.length) {
5248
+ throw new TypeError('Embedding vectors must have the same length');
5249
+ }
5250
+ const dotProduct = embeddingVector1.reduce((sum, value, index) => sum + value * embeddingVector2[index], 0);
5251
+ const magnitude1 = Math.sqrt(embeddingVector1.reduce((sum, value) => sum + value * value, 0));
5252
+ const magnitude2 = Math.sqrt(embeddingVector2.reduce((sum, value) => sum + value * value, 0));
5253
+ return 1 - dotProduct / (magnitude1 * magnitude2);
5254
+ }
5255
+ /**
5256
+ * TODO: !!!! Verify if this is working
5257
+ * TODO: [♨] Implement Better - use keyword search
5258
+ * TODO: [♨] Examples of values
5259
+ */
5155
5260
 
5156
5261
  /**
5157
5262
  * @@@
@@ -5159,9 +5264,9 @@ async function getKnowledgeForTask(options) {
5159
5264
  * @private internal utility of `createPipelineExecutor`
5160
5265
  */
5161
5266
  async function getReservedParametersForTask(options) {
5162
- const { preparedPipeline, task, pipelineIdentification } = options;
5267
+ const { tools, preparedPipeline, task, pipelineIdentification } = options;
5163
5268
  const context = await getContextForTask(); // <- [🏍]
5164
- const knowledge = await getKnowledgeForTask({ preparedPipeline, task });
5269
+ const knowledge = await getKnowledgeForTask({ tools, preparedPipeline, task });
5165
5270
  const examples = await getExamplesForTask();
5166
5271
  const currentDate = new Date().toISOString(); // <- TODO: [🧠][💩] Better
5167
5272
  const modelName = RESERVED_PARAMETER_MISSING_VALUE;
@@ -5223,6 +5328,7 @@ async function executeTask(options) {
5223
5328
  }
5224
5329
  const definedParameters = Object.freeze({
5225
5330
  ...(await getReservedParametersForTask({
5331
+ tools,
5226
5332
  preparedPipeline,
5227
5333
  task: currentTask,
5228
5334
  pipelineIdentification,