@promptbook/legacy-documents 0.98.0-5 โ 0.98.0-8
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 +156 -116
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/anthropic-claude.index.d.ts +2 -2
- package/esm/typings/src/_packages/openai.index.d.ts +4 -0
- package/esm/typings/src/_packages/types.index.d.ts +10 -2
- package/esm/typings/src/config.d.ts +1 -1
- package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +1 -0
- package/esm/typings/src/execution/utils/validatePromptResult.d.ts +53 -0
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +3 -3
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +2 -2
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +4 -4
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionToolsOptions.d.ts +42 -1
- package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +58 -1
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +156 -116
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -28,7 +28,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
28
28
|
* @generated
|
|
29
29
|
* @see https://github.com/webgptorg/promptbook
|
|
30
30
|
*/
|
|
31
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-
|
|
31
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-8';
|
|
32
32
|
/**
|
|
33
33
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
34
34
|
* Note: [๐] Ignore a discrepancy between file name and entity name
|
|
@@ -177,7 +177,7 @@ const DEFAULT_MAX_PARALLEL_COUNT = 5; // <- TODO: [๐คนโโ๏ธ]
|
|
|
177
177
|
*
|
|
178
178
|
* @public exported from `@promptbook/core`
|
|
179
179
|
*/
|
|
180
|
-
const DEFAULT_MAX_EXECUTION_ATTEMPTS =
|
|
180
|
+
const DEFAULT_MAX_EXECUTION_ATTEMPTS = 7; // <- TODO: [๐คนโโ๏ธ]
|
|
181
181
|
// <- TODO: [๐] Make also `BOOKS_DIRNAME_ALTERNATIVES`
|
|
182
182
|
// TODO: Just `.promptbook` in config, hardcode subfolders like `download-cache` or `execution-cache`
|
|
183
183
|
/**
|
|
@@ -2562,7 +2562,7 @@ function jsonParse(value) {
|
|
|
2562
2562
|
throw new Error(spaceTrim$1((block) => `
|
|
2563
2563
|
${block(error.message)}
|
|
2564
2564
|
|
|
2565
|
-
The JSON text:
|
|
2565
|
+
The expected JSON text:
|
|
2566
2566
|
${block(value)}
|
|
2567
2567
|
`));
|
|
2568
2568
|
}
|
|
@@ -4639,6 +4639,77 @@ function mapAvailableToExpectedParameters(options) {
|
|
|
4639
4639
|
return mappedParameters;
|
|
4640
4640
|
}
|
|
4641
4641
|
|
|
4642
|
+
/**
|
|
4643
|
+
* Replaces parameters in template with values from parameters object
|
|
4644
|
+
*
|
|
4645
|
+
* Note: This function is not places strings into string,
|
|
4646
|
+
* It's more complex and can handle this operation specifically for LLM models
|
|
4647
|
+
*
|
|
4648
|
+
* @param template the template with parameters in {curly} braces
|
|
4649
|
+
* @param parameters the object with parameters
|
|
4650
|
+
* @returns the template with replaced parameters
|
|
4651
|
+
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
4652
|
+
* @public exported from `@promptbook/utils`
|
|
4653
|
+
*/
|
|
4654
|
+
function templateParameters(template, parameters) {
|
|
4655
|
+
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
4656
|
+
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
4657
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
4658
|
+
}
|
|
4659
|
+
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
4660
|
+
// TODO: [๐ต]
|
|
4661
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
4662
|
+
}
|
|
4663
|
+
}
|
|
4664
|
+
let replacedTemplates = template;
|
|
4665
|
+
let match;
|
|
4666
|
+
let loopLimit = LOOP_LIMIT;
|
|
4667
|
+
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
4668
|
+
.exec(replacedTemplates))) {
|
|
4669
|
+
if (loopLimit-- < 0) {
|
|
4670
|
+
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
4671
|
+
}
|
|
4672
|
+
const precol = match.groups.precol;
|
|
4673
|
+
const parameterName = match.groups.parameterName;
|
|
4674
|
+
if (parameterName === '') {
|
|
4675
|
+
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
4676
|
+
continue;
|
|
4677
|
+
}
|
|
4678
|
+
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
4679
|
+
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
4680
|
+
}
|
|
4681
|
+
if (parameters[parameterName] === undefined) {
|
|
4682
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4683
|
+
}
|
|
4684
|
+
let parameterValue = parameters[parameterName];
|
|
4685
|
+
if (parameterValue === undefined) {
|
|
4686
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4687
|
+
}
|
|
4688
|
+
parameterValue = valueToString(parameterValue);
|
|
4689
|
+
// Escape curly braces in parameter values to prevent prompt-injection
|
|
4690
|
+
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
4691
|
+
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
4692
|
+
parameterValue = parameterValue
|
|
4693
|
+
.split('\n')
|
|
4694
|
+
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
4695
|
+
.join('\n');
|
|
4696
|
+
}
|
|
4697
|
+
replacedTemplates =
|
|
4698
|
+
replacedTemplates.substring(0, match.index + precol.length) +
|
|
4699
|
+
parameterValue +
|
|
4700
|
+
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
4701
|
+
}
|
|
4702
|
+
// [๐ซ] Check if there are parameters that are not closed properly
|
|
4703
|
+
if (/{\w+$/.test(replacedTemplates)) {
|
|
4704
|
+
throw new PipelineExecutionError('Parameter is not closed');
|
|
4705
|
+
}
|
|
4706
|
+
// [๐ซ] Check if there are parameters that are not opened properly
|
|
4707
|
+
if (/^\w+}/.test(replacedTemplates)) {
|
|
4708
|
+
throw new PipelineExecutionError('Parameter is not opened');
|
|
4709
|
+
}
|
|
4710
|
+
return replacedTemplates;
|
|
4711
|
+
}
|
|
4712
|
+
|
|
4642
4713
|
/**
|
|
4643
4714
|
* Extracts all code blocks from markdown.
|
|
4644
4715
|
*
|
|
@@ -4741,77 +4812,6 @@ function extractJsonBlock(markdown) {
|
|
|
4741
4812
|
* TODO: [๐ข] Make this logic part of `JsonFormatParser` or `isValidJsonString`
|
|
4742
4813
|
*/
|
|
4743
4814
|
|
|
4744
|
-
/**
|
|
4745
|
-
* Replaces parameters in template with values from parameters object
|
|
4746
|
-
*
|
|
4747
|
-
* Note: This function is not places strings into string,
|
|
4748
|
-
* It's more complex and can handle this operation specifically for LLM models
|
|
4749
|
-
*
|
|
4750
|
-
* @param template the template with parameters in {curly} braces
|
|
4751
|
-
* @param parameters the object with parameters
|
|
4752
|
-
* @returns the template with replaced parameters
|
|
4753
|
-
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
4754
|
-
* @public exported from `@promptbook/utils`
|
|
4755
|
-
*/
|
|
4756
|
-
function templateParameters(template, parameters) {
|
|
4757
|
-
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
4758
|
-
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
4759
|
-
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
4760
|
-
}
|
|
4761
|
-
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
4762
|
-
// TODO: [๐ต]
|
|
4763
|
-
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
4764
|
-
}
|
|
4765
|
-
}
|
|
4766
|
-
let replacedTemplates = template;
|
|
4767
|
-
let match;
|
|
4768
|
-
let loopLimit = LOOP_LIMIT;
|
|
4769
|
-
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
4770
|
-
.exec(replacedTemplates))) {
|
|
4771
|
-
if (loopLimit-- < 0) {
|
|
4772
|
-
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
4773
|
-
}
|
|
4774
|
-
const precol = match.groups.precol;
|
|
4775
|
-
const parameterName = match.groups.parameterName;
|
|
4776
|
-
if (parameterName === '') {
|
|
4777
|
-
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
4778
|
-
continue;
|
|
4779
|
-
}
|
|
4780
|
-
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
4781
|
-
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
4782
|
-
}
|
|
4783
|
-
if (parameters[parameterName] === undefined) {
|
|
4784
|
-
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4785
|
-
}
|
|
4786
|
-
let parameterValue = parameters[parameterName];
|
|
4787
|
-
if (parameterValue === undefined) {
|
|
4788
|
-
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4789
|
-
}
|
|
4790
|
-
parameterValue = valueToString(parameterValue);
|
|
4791
|
-
// Escape curly braces in parameter values to prevent prompt-injection
|
|
4792
|
-
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
4793
|
-
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
4794
|
-
parameterValue = parameterValue
|
|
4795
|
-
.split('\n')
|
|
4796
|
-
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
4797
|
-
.join('\n');
|
|
4798
|
-
}
|
|
4799
|
-
replacedTemplates =
|
|
4800
|
-
replacedTemplates.substring(0, match.index + precol.length) +
|
|
4801
|
-
parameterValue +
|
|
4802
|
-
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
4803
|
-
}
|
|
4804
|
-
// [๐ซ] Check if there are parameters that are not closed properly
|
|
4805
|
-
if (/{\w+$/.test(replacedTemplates)) {
|
|
4806
|
-
throw new PipelineExecutionError('Parameter is not closed');
|
|
4807
|
-
}
|
|
4808
|
-
// [๐ซ] Check if there are parameters that are not opened properly
|
|
4809
|
-
if (/^\w+}/.test(replacedTemplates)) {
|
|
4810
|
-
throw new PipelineExecutionError('Parameter is not opened');
|
|
4811
|
-
}
|
|
4812
|
-
return replacedTemplates;
|
|
4813
|
-
}
|
|
4814
|
-
|
|
4815
4815
|
/**
|
|
4816
4816
|
* Counts number of characters in the text
|
|
4817
4817
|
*
|
|
@@ -4972,6 +4972,68 @@ function checkExpectations(expectations, value) {
|
|
|
4972
4972
|
* Note: [๐] and [๐ค ] are interconnected together
|
|
4973
4973
|
*/
|
|
4974
4974
|
|
|
4975
|
+
/**
|
|
4976
|
+
* Validates a prompt result against expectations and format requirements.
|
|
4977
|
+
* This function provides a common abstraction for result validation that can be used
|
|
4978
|
+
* by both execution logic and caching logic to ensure consistency.
|
|
4979
|
+
*
|
|
4980
|
+
* @param options - The validation options including result string, expectations, and format
|
|
4981
|
+
* @returns Validation result with processed string and validity status
|
|
4982
|
+
* @private internal function of `createPipelineExecutor` and `cacheLlmTools`
|
|
4983
|
+
*/
|
|
4984
|
+
function validatePromptResult(options) {
|
|
4985
|
+
const { resultString, expectations, format } = options;
|
|
4986
|
+
let processedResultString = resultString;
|
|
4987
|
+
let validationError;
|
|
4988
|
+
try {
|
|
4989
|
+
// TODO: [๐] Unite object for expecting amount and format
|
|
4990
|
+
if (format) {
|
|
4991
|
+
if (format === 'JSON') {
|
|
4992
|
+
if (!isValidJsonString(processedResultString)) {
|
|
4993
|
+
// TODO: [๐ข] Do more universally via `FormatParser`
|
|
4994
|
+
try {
|
|
4995
|
+
processedResultString = extractJsonBlock(processedResultString);
|
|
4996
|
+
}
|
|
4997
|
+
catch (error) {
|
|
4998
|
+
keepUnused(error);
|
|
4999
|
+
throw new ExpectError(spaceTrim((block) => `
|
|
5000
|
+
Expected valid JSON string
|
|
5001
|
+
|
|
5002
|
+
The expected JSON text:
|
|
5003
|
+
${block(processedResultString)}
|
|
5004
|
+
`));
|
|
5005
|
+
}
|
|
5006
|
+
}
|
|
5007
|
+
}
|
|
5008
|
+
else {
|
|
5009
|
+
throw new UnexpectedError(`Unknown format "${format}"`);
|
|
5010
|
+
}
|
|
5011
|
+
}
|
|
5012
|
+
// TODO: [๐] Unite object for expecting amount and format
|
|
5013
|
+
if (expectations) {
|
|
5014
|
+
checkExpectations(expectations, processedResultString);
|
|
5015
|
+
}
|
|
5016
|
+
return {
|
|
5017
|
+
isValid: true,
|
|
5018
|
+
processedResultString,
|
|
5019
|
+
};
|
|
5020
|
+
}
|
|
5021
|
+
catch (error) {
|
|
5022
|
+
if (error instanceof ExpectError) {
|
|
5023
|
+
validationError = error;
|
|
5024
|
+
}
|
|
5025
|
+
else {
|
|
5026
|
+
// Re-throw non-ExpectError errors (like UnexpectedError)
|
|
5027
|
+
throw error;
|
|
5028
|
+
}
|
|
5029
|
+
return {
|
|
5030
|
+
isValid: false,
|
|
5031
|
+
processedResultString,
|
|
5032
|
+
error: validationError,
|
|
5033
|
+
};
|
|
5034
|
+
}
|
|
5035
|
+
}
|
|
5036
|
+
|
|
4975
5037
|
/**
|
|
4976
5038
|
* Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
|
|
4977
5039
|
* (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
|
|
@@ -4994,13 +5056,13 @@ async function executeAttempts(options) {
|
|
|
4994
5056
|
// TODO: [๐] Make arrayable LLMs -> single LLM DRY
|
|
4995
5057
|
const _llms = arrayableToArray(tools.llm);
|
|
4996
5058
|
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
4997
|
-
attempts: for (let
|
|
4998
|
-
const isJokerAttempt =
|
|
4999
|
-
const jokerParameterName = jokerParameterNames[jokerParameterNames.length +
|
|
5059
|
+
attempts: for (let attemptIndex = -jokerParameterNames.length; attemptIndex < maxAttempts; attemptIndex++) {
|
|
5060
|
+
const isJokerAttempt = attemptIndex < 0;
|
|
5061
|
+
const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
|
|
5000
5062
|
// TODO: [๐ง ][๐ญ] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
|
|
5001
5063
|
if (isJokerAttempt && !jokerParameterName) {
|
|
5002
5064
|
throw new UnexpectedError(spaceTrim((block) => `
|
|
5003
|
-
Joker not found in attempt ${
|
|
5065
|
+
Joker not found in attempt ${attemptIndex}
|
|
5004
5066
|
|
|
5005
5067
|
${block(pipelineIdentification)}
|
|
5006
5068
|
`));
|
|
@@ -5198,35 +5260,18 @@ async function executeAttempts(options) {
|
|
|
5198
5260
|
}
|
|
5199
5261
|
}
|
|
5200
5262
|
// TODO: [๐] Unite object for expecting amount and format
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
throw new ExpectError(spaceTrim((block) => `
|
|
5211
|
-
Expected valid JSON string
|
|
5212
|
-
|
|
5213
|
-
${block(
|
|
5214
|
-
/*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ '')}
|
|
5215
|
-
`));
|
|
5216
|
-
}
|
|
5217
|
-
}
|
|
5218
|
-
}
|
|
5219
|
-
else {
|
|
5220
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
5221
|
-
Unknown format "${task.format}"
|
|
5222
|
-
|
|
5223
|
-
${block(pipelineIdentification)}
|
|
5224
|
-
`));
|
|
5263
|
+
// Use the common validation function for both format and expectations
|
|
5264
|
+
if (task.format || task.expectations) {
|
|
5265
|
+
const validationResult = validatePromptResult({
|
|
5266
|
+
resultString: $ongoingTaskResult.$resultString || '',
|
|
5267
|
+
expectations: task.expectations,
|
|
5268
|
+
format: task.format,
|
|
5269
|
+
});
|
|
5270
|
+
if (!validationResult.isValid) {
|
|
5271
|
+
throw validationResult.error;
|
|
5225
5272
|
}
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
if (task.expectations) {
|
|
5229
|
-
checkExpectations(task.expectations, $ongoingTaskResult.$resultString || '');
|
|
5273
|
+
// Update the result string in case format processing modified it (e.g., JSON extraction)
|
|
5274
|
+
$ongoingTaskResult.$resultString = validationResult.processedResultString;
|
|
5230
5275
|
}
|
|
5231
5276
|
break attempts;
|
|
5232
5277
|
}
|
|
@@ -5240,6 +5285,7 @@ async function executeAttempts(options) {
|
|
|
5240
5285
|
$ongoingTaskResult.$failedResults = [];
|
|
5241
5286
|
}
|
|
5242
5287
|
$ongoingTaskResult.$failedResults.push({
|
|
5288
|
+
attemptIndex,
|
|
5243
5289
|
result: $ongoingTaskResult.$resultString,
|
|
5244
5290
|
error: error,
|
|
5245
5291
|
});
|
|
@@ -5264,19 +5310,13 @@ async function executeAttempts(options) {
|
|
|
5264
5310
|
});
|
|
5265
5311
|
}
|
|
5266
5312
|
}
|
|
5267
|
-
if ($ongoingTaskResult.$expectError !== null &&
|
|
5268
|
-
//
|
|
5269
|
-
$ongoingTaskResult.$failedResults = $ongoingTaskResult.$failedResults || [];
|
|
5270
|
-
$ongoingTaskResult.$failedResults.push({
|
|
5271
|
-
result: $ongoingTaskResult.$resultString,
|
|
5272
|
-
error: $ongoingTaskResult.$expectError,
|
|
5273
|
-
});
|
|
5274
|
-
// Create a summary of all failures
|
|
5313
|
+
if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
|
|
5314
|
+
// Note: Create a summary of all failures
|
|
5275
5315
|
const failuresSummary = $ongoingTaskResult.$failedResults
|
|
5276
|
-
.map((failure
|
|
5316
|
+
.map((failure) => spaceTrim((block) => {
|
|
5277
5317
|
var _a, _b;
|
|
5278
5318
|
return `
|
|
5279
|
-
Attempt ${
|
|
5319
|
+
Attempt ${failure.attemptIndex + 1}:
|
|
5280
5320
|
Error ${((_a = failure.error) === null || _a === void 0 ? void 0 : _a.name) || ''}:
|
|
5281
5321
|
${block((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message.split('\n').map((line) => `> ${line}`).join('\n'))}
|
|
5282
5322
|
|