@promptbook/node 0.92.0-4 → 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 +116 -10
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/core.index.d.ts +4 -0
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/cli/common/$provideLlmToolsForCli.d.ts +1 -1
- package/esm/typings/src/conversion/archive/loadArchive.d.ts +2 -2
- package/esm/typings/src/execution/createPipelineExecutor/getKnowledgeForTask.d.ts +12 -0
- package/esm/typings/src/execution/createPipelineExecutor/getReservedParametersForTask.d.ts +5 -0
- package/esm/typings/src/formats/json/utils/jsonParse.d.ts +11 -0
- package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +43 -0
- package/esm/typings/src/remote-server/openapi.d.ts +397 -3
- package/package.json +2 -2
- package/umd/index.umd.js +116 -10
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -30,7 +30,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
30
30
|
* @generated
|
|
31
31
|
* @see https://github.com/webgptorg/promptbook
|
|
32
32
|
*/
|
|
33
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-
|
|
33
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-6';
|
|
34
34
|
/**
|
|
35
35
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
36
36
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -299,6 +299,45 @@ class UnexpectedError extends Error {
|
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Converts a JavaScript Object Notation (JSON) string into an object.
|
|
304
|
+
*
|
|
305
|
+
* Note: This is wrapper around `JSON.parse()` with better error and type handling
|
|
306
|
+
*
|
|
307
|
+
* @public exported from `@promptbook/utils`
|
|
308
|
+
*/
|
|
309
|
+
function jsonParse(value) {
|
|
310
|
+
if (value === undefined) {
|
|
311
|
+
throw new Error(`Can not parse JSON from undefined value.`);
|
|
312
|
+
}
|
|
313
|
+
else if (typeof value !== 'string') {
|
|
314
|
+
console.error('Can not parse JSON from non-string value.', { text: value });
|
|
315
|
+
throw new Error(spaceTrim(`
|
|
316
|
+
Can not parse JSON from non-string value.
|
|
317
|
+
|
|
318
|
+
The value type: ${typeof value}
|
|
319
|
+
See more in console.
|
|
320
|
+
`));
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
return JSON.parse(value);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
if (!(error instanceof Error)) {
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
throw new Error(spaceTrim((block) => `
|
|
330
|
+
${block(error.message)}
|
|
331
|
+
|
|
332
|
+
The JSON text:
|
|
333
|
+
${block(value)}
|
|
334
|
+
`));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* TODO: !!!! Use in Promptbook.studio
|
|
339
|
+
*/
|
|
340
|
+
|
|
302
341
|
/**
|
|
303
342
|
* Orders JSON object by keys
|
|
304
343
|
*
|
|
@@ -1088,7 +1127,7 @@ async function loadArchive(filePath, fs) {
|
|
|
1088
1127
|
if (!indexFile) {
|
|
1089
1128
|
throw new UnexpectedError(`Archive does not contain 'index.book.json' file`);
|
|
1090
1129
|
}
|
|
1091
|
-
const collectionJson =
|
|
1130
|
+
const collectionJson = jsonParse(await indexFile.async('text'));
|
|
1092
1131
|
for (const pipeline of collectionJson) {
|
|
1093
1132
|
validatePipeline(pipeline);
|
|
1094
1133
|
}
|
|
@@ -1682,7 +1721,7 @@ function jsonStringsToJsons(object) {
|
|
|
1682
1721
|
const newObject = { ...object };
|
|
1683
1722
|
for (const [key, value] of Object.entries(object)) {
|
|
1684
1723
|
if (typeof value === 'string' && isValidJsonString(value)) {
|
|
1685
|
-
newObject[key] =
|
|
1724
|
+
newObject[key] = jsonParse(value);
|
|
1686
1725
|
}
|
|
1687
1726
|
else {
|
|
1688
1727
|
newObject[key] = jsonStringsToJsons(value);
|
|
@@ -4076,13 +4115,79 @@ async function getExamplesForTask(task) {
|
|
|
4076
4115
|
/**
|
|
4077
4116
|
* @@@
|
|
4078
4117
|
*
|
|
4118
|
+
* Here is the place where RAG (retrieval-augmented generation) happens
|
|
4119
|
+
*
|
|
4079
4120
|
* @private internal utility of `createPipelineExecutor`
|
|
4080
4121
|
*/
|
|
4081
4122
|
async function getKnowledgeForTask(options) {
|
|
4082
|
-
const { preparedPipeline, task } = options;
|
|
4083
|
-
|
|
4123
|
+
const { tools, preparedPipeline, task } = options;
|
|
4124
|
+
const firstKnowlegePiece = preparedPipeline.knowledgePieces[0];
|
|
4125
|
+
const firstKnowlegeIndex = firstKnowlegePiece === null || firstKnowlegePiece === void 0 ? void 0 : firstKnowlegePiece.index[0];
|
|
4126
|
+
// <- TODO: Do not use just first knowledge piece and first index to determine embedding model, use also keyword search
|
|
4127
|
+
if (firstKnowlegePiece === undefined || firstKnowlegeIndex === undefined) {
|
|
4128
|
+
return 'No knowledge pieces found';
|
|
4129
|
+
}
|
|
4130
|
+
// TODO: [🚐] Make arrayable LLMs -> single LLM DRY
|
|
4131
|
+
const _llms = arrayableToArray(tools.llm);
|
|
4132
|
+
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
4133
|
+
const taskEmbeddingPrompt = {
|
|
4134
|
+
title: 'Knowledge Search',
|
|
4135
|
+
modelRequirements: {
|
|
4136
|
+
modelVariant: 'EMBEDDING',
|
|
4137
|
+
modelName: firstKnowlegeIndex.modelName,
|
|
4138
|
+
},
|
|
4139
|
+
content: task.content,
|
|
4140
|
+
parameters: {
|
|
4141
|
+
/* !!!!!!!! */
|
|
4142
|
+
},
|
|
4143
|
+
};
|
|
4144
|
+
const taskEmbeddingResult = await llmTools.callEmbeddingModel(taskEmbeddingPrompt);
|
|
4145
|
+
const knowledgePiecesWithRelevance = preparedPipeline.knowledgePieces.map((knowledgePiece) => {
|
|
4146
|
+
const { index } = knowledgePiece;
|
|
4147
|
+
const knowledgePieceIndex = index.find((i) => i.modelName === firstKnowlegeIndex.modelName);
|
|
4148
|
+
// <- TODO: Do not use just first knowledge piece and first index to determine embedding model
|
|
4149
|
+
if (knowledgePieceIndex === undefined) {
|
|
4150
|
+
return {
|
|
4151
|
+
content: knowledgePiece.content,
|
|
4152
|
+
relevance: 0,
|
|
4153
|
+
};
|
|
4154
|
+
}
|
|
4155
|
+
const relevance = computeCosineSimilarity(knowledgePieceIndex.position, taskEmbeddingResult.content);
|
|
4156
|
+
return {
|
|
4157
|
+
content: knowledgePiece.content,
|
|
4158
|
+
relevance,
|
|
4159
|
+
};
|
|
4160
|
+
});
|
|
4161
|
+
const knowledgePiecesSorted = knowledgePiecesWithRelevance.sort((a, b) => a.relevance - b.relevance);
|
|
4162
|
+
const knowledgePiecesLimited = knowledgePiecesSorted.slice(0, 5);
|
|
4163
|
+
console.log('!!! Embedding', {
|
|
4164
|
+
task,
|
|
4165
|
+
taskEmbeddingPrompt,
|
|
4166
|
+
taskEmbeddingResult,
|
|
4167
|
+
firstKnowlegePiece,
|
|
4168
|
+
firstKnowlegeIndex,
|
|
4169
|
+
knowledgePiecesWithRelevance,
|
|
4170
|
+
knowledgePiecesSorted,
|
|
4171
|
+
knowledgePiecesLimited,
|
|
4172
|
+
});
|
|
4173
|
+
return knowledgePiecesLimited.map(({ content }) => `- ${content}`).join('\n');
|
|
4084
4174
|
// <- TODO: [🧠] Some smart aggregation of knowledge pieces, single-line vs multi-line vs mixed
|
|
4085
4175
|
}
|
|
4176
|
+
// TODO: !!!!!! Annotate + to new file
|
|
4177
|
+
function computeCosineSimilarity(embeddingVector1, embeddingVector2) {
|
|
4178
|
+
if (embeddingVector1.length !== embeddingVector2.length) {
|
|
4179
|
+
throw new TypeError('Embedding vectors must have the same length');
|
|
4180
|
+
}
|
|
4181
|
+
const dotProduct = embeddingVector1.reduce((sum, value, index) => sum + value * embeddingVector2[index], 0);
|
|
4182
|
+
const magnitude1 = Math.sqrt(embeddingVector1.reduce((sum, value) => sum + value * value, 0));
|
|
4183
|
+
const magnitude2 = Math.sqrt(embeddingVector2.reduce((sum, value) => sum + value * value, 0));
|
|
4184
|
+
return 1 - dotProduct / (magnitude1 * magnitude2);
|
|
4185
|
+
}
|
|
4186
|
+
/**
|
|
4187
|
+
* TODO: !!!! Verify if this is working
|
|
4188
|
+
* TODO: [♨] Implement Better - use keyword search
|
|
4189
|
+
* TODO: [♨] Examples of values
|
|
4190
|
+
*/
|
|
4086
4191
|
|
|
4087
4192
|
/**
|
|
4088
4193
|
* @@@
|
|
@@ -4090,9 +4195,9 @@ async function getKnowledgeForTask(options) {
|
|
|
4090
4195
|
* @private internal utility of `createPipelineExecutor`
|
|
4091
4196
|
*/
|
|
4092
4197
|
async function getReservedParametersForTask(options) {
|
|
4093
|
-
const { preparedPipeline, task, pipelineIdentification } = options;
|
|
4198
|
+
const { tools, preparedPipeline, task, pipelineIdentification } = options;
|
|
4094
4199
|
const context = await getContextForTask(); // <- [🏍]
|
|
4095
|
-
const knowledge = await getKnowledgeForTask({ preparedPipeline, task });
|
|
4200
|
+
const knowledge = await getKnowledgeForTask({ tools, preparedPipeline, task });
|
|
4096
4201
|
const examples = await getExamplesForTask();
|
|
4097
4202
|
const currentDate = new Date().toISOString(); // <- TODO: [🧠][💩] Better
|
|
4098
4203
|
const modelName = RESERVED_PARAMETER_MISSING_VALUE;
|
|
@@ -4154,6 +4259,7 @@ async function executeTask(options) {
|
|
|
4154
4259
|
}
|
|
4155
4260
|
const definedParameters = Object.freeze({
|
|
4156
4261
|
...(await getReservedParametersForTask({
|
|
4262
|
+
tools,
|
|
4157
4263
|
preparedPipeline,
|
|
4158
4264
|
task: currentTask,
|
|
4159
4265
|
pipelineIdentification,
|
|
@@ -4725,7 +4831,7 @@ async function preparePersona(personaDescription, tools, options) {
|
|
|
4725
4831
|
}).asPromise();
|
|
4726
4832
|
const { outputParameters } = result;
|
|
4727
4833
|
const { modelsRequirements: modelsRequirementsJson } = outputParameters;
|
|
4728
|
-
const modelsRequirementsUnchecked =
|
|
4834
|
+
const modelsRequirementsUnchecked = jsonParse(modelsRequirementsJson);
|
|
4729
4835
|
if (isVerbose) {
|
|
4730
4836
|
console.info(`PERSONA ${personaDescription}`, modelsRequirementsUnchecked);
|
|
4731
4837
|
}
|
|
@@ -5306,7 +5412,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
|
|
|
5306
5412
|
> },
|
|
5307
5413
|
*/
|
|
5308
5414
|
async asJson() {
|
|
5309
|
-
return
|
|
5415
|
+
return jsonParse(await tools.fs.readFile(filename, 'utf-8'));
|
|
5310
5416
|
},
|
|
5311
5417
|
async asText() {
|
|
5312
5418
|
return await tools.fs.readFile(filename, 'utf-8');
|
|
@@ -10826,7 +10932,7 @@ class FileCacheStorage {
|
|
|
10826
10932
|
return null;
|
|
10827
10933
|
}
|
|
10828
10934
|
const fileContent = await readFile(filename, 'utf-8');
|
|
10829
|
-
const value =
|
|
10935
|
+
const value = jsonParse(fileContent);
|
|
10830
10936
|
// TODO: [🌗]
|
|
10831
10937
|
return value;
|
|
10832
10938
|
}
|