@promptbook/remote-server 0.98.0-6 โ 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 +173 -133
- 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 +173 -133
- package/umd/index.umd.js.map +1 -1
package/umd/index.umd.js
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
* @generated
|
|
49
49
|
* @see https://github.com/webgptorg/promptbook
|
|
50
50
|
*/
|
|
51
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-
|
|
51
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-8';
|
|
52
52
|
/**
|
|
53
53
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
54
54
|
* Note: [๐] Ignore a discrepancy between file name and entity name
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
*
|
|
189
189
|
* @public exported from `@promptbook/core`
|
|
190
190
|
*/
|
|
191
|
-
const DEFAULT_MAX_EXECUTION_ATTEMPTS =
|
|
191
|
+
const DEFAULT_MAX_EXECUTION_ATTEMPTS = 7; // <- TODO: [๐คนโโ๏ธ]
|
|
192
192
|
// <- TODO: [๐] Make also `BOOKS_DIRNAME_ALTERNATIVES`
|
|
193
193
|
// TODO: Just `.promptbook` in config, hardcode subfolders like `download-cache` or `execution-cache`
|
|
194
194
|
/**
|
|
@@ -1906,7 +1906,7 @@
|
|
|
1906
1906
|
throw new Error(spaceTrim__default["default"]((block) => `
|
|
1907
1907
|
${block(error.message)}
|
|
1908
1908
|
|
|
1909
|
-
The JSON text:
|
|
1909
|
+
The expected JSON text:
|
|
1910
1910
|
${block(value)}
|
|
1911
1911
|
`));
|
|
1912
1912
|
}
|
|
@@ -4828,6 +4828,94 @@
|
|
|
4828
4828
|
return mappedParameters;
|
|
4829
4829
|
}
|
|
4830
4830
|
|
|
4831
|
+
/**
|
|
4832
|
+
* Just says that the variable is not used but should be kept
|
|
4833
|
+
* No side effects.
|
|
4834
|
+
*
|
|
4835
|
+
* Note: It can be useful for:
|
|
4836
|
+
*
|
|
4837
|
+
* 1) Suppressing eager optimization of unused imports
|
|
4838
|
+
* 2) Suppressing eslint errors of unused variables in the tests
|
|
4839
|
+
* 3) Keeping the type of the variable for type testing
|
|
4840
|
+
*
|
|
4841
|
+
* @param value any values
|
|
4842
|
+
* @returns void
|
|
4843
|
+
* @private within the repository
|
|
4844
|
+
*/
|
|
4845
|
+
function keepUnused(...valuesToKeep) {
|
|
4846
|
+
}
|
|
4847
|
+
|
|
4848
|
+
/**
|
|
4849
|
+
* Replaces parameters in template with values from parameters object
|
|
4850
|
+
*
|
|
4851
|
+
* Note: This function is not places strings into string,
|
|
4852
|
+
* It's more complex and can handle this operation specifically for LLM models
|
|
4853
|
+
*
|
|
4854
|
+
* @param template the template with parameters in {curly} braces
|
|
4855
|
+
* @param parameters the object with parameters
|
|
4856
|
+
* @returns the template with replaced parameters
|
|
4857
|
+
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
4858
|
+
* @public exported from `@promptbook/utils`
|
|
4859
|
+
*/
|
|
4860
|
+
function templateParameters(template, parameters) {
|
|
4861
|
+
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
4862
|
+
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
4863
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
4864
|
+
}
|
|
4865
|
+
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
4866
|
+
// TODO: [๐ต]
|
|
4867
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
4868
|
+
}
|
|
4869
|
+
}
|
|
4870
|
+
let replacedTemplates = template;
|
|
4871
|
+
let match;
|
|
4872
|
+
let loopLimit = LOOP_LIMIT;
|
|
4873
|
+
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
4874
|
+
.exec(replacedTemplates))) {
|
|
4875
|
+
if (loopLimit-- < 0) {
|
|
4876
|
+
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
4877
|
+
}
|
|
4878
|
+
const precol = match.groups.precol;
|
|
4879
|
+
const parameterName = match.groups.parameterName;
|
|
4880
|
+
if (parameterName === '') {
|
|
4881
|
+
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
4882
|
+
continue;
|
|
4883
|
+
}
|
|
4884
|
+
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
4885
|
+
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
4886
|
+
}
|
|
4887
|
+
if (parameters[parameterName] === undefined) {
|
|
4888
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4889
|
+
}
|
|
4890
|
+
let parameterValue = parameters[parameterName];
|
|
4891
|
+
if (parameterValue === undefined) {
|
|
4892
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4893
|
+
}
|
|
4894
|
+
parameterValue = valueToString(parameterValue);
|
|
4895
|
+
// Escape curly braces in parameter values to prevent prompt-injection
|
|
4896
|
+
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
4897
|
+
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
4898
|
+
parameterValue = parameterValue
|
|
4899
|
+
.split('\n')
|
|
4900
|
+
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
4901
|
+
.join('\n');
|
|
4902
|
+
}
|
|
4903
|
+
replacedTemplates =
|
|
4904
|
+
replacedTemplates.substring(0, match.index + precol.length) +
|
|
4905
|
+
parameterValue +
|
|
4906
|
+
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
4907
|
+
}
|
|
4908
|
+
// [๐ซ] Check if there are parameters that are not closed properly
|
|
4909
|
+
if (/{\w+$/.test(replacedTemplates)) {
|
|
4910
|
+
throw new PipelineExecutionError('Parameter is not closed');
|
|
4911
|
+
}
|
|
4912
|
+
// [๐ซ] Check if there are parameters that are not opened properly
|
|
4913
|
+
if (/^\w+}/.test(replacedTemplates)) {
|
|
4914
|
+
throw new PipelineExecutionError('Parameter is not opened');
|
|
4915
|
+
}
|
|
4916
|
+
return replacedTemplates;
|
|
4917
|
+
}
|
|
4918
|
+
|
|
4831
4919
|
/**
|
|
4832
4920
|
* Extracts all code blocks from markdown.
|
|
4833
4921
|
*
|
|
@@ -4930,94 +5018,6 @@
|
|
|
4930
5018
|
* TODO: [๐ข] Make this logic part of `JsonFormatParser` or `isValidJsonString`
|
|
4931
5019
|
*/
|
|
4932
5020
|
|
|
4933
|
-
/**
|
|
4934
|
-
* Just says that the variable is not used but should be kept
|
|
4935
|
-
* No side effects.
|
|
4936
|
-
*
|
|
4937
|
-
* Note: It can be useful for:
|
|
4938
|
-
*
|
|
4939
|
-
* 1) Suppressing eager optimization of unused imports
|
|
4940
|
-
* 2) Suppressing eslint errors of unused variables in the tests
|
|
4941
|
-
* 3) Keeping the type of the variable for type testing
|
|
4942
|
-
*
|
|
4943
|
-
* @param value any values
|
|
4944
|
-
* @returns void
|
|
4945
|
-
* @private within the repository
|
|
4946
|
-
*/
|
|
4947
|
-
function keepUnused(...valuesToKeep) {
|
|
4948
|
-
}
|
|
4949
|
-
|
|
4950
|
-
/**
|
|
4951
|
-
* Replaces parameters in template with values from parameters object
|
|
4952
|
-
*
|
|
4953
|
-
* Note: This function is not places strings into string,
|
|
4954
|
-
* It's more complex and can handle this operation specifically for LLM models
|
|
4955
|
-
*
|
|
4956
|
-
* @param template the template with parameters in {curly} braces
|
|
4957
|
-
* @param parameters the object with parameters
|
|
4958
|
-
* @returns the template with replaced parameters
|
|
4959
|
-
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
4960
|
-
* @public exported from `@promptbook/utils`
|
|
4961
|
-
*/
|
|
4962
|
-
function templateParameters(template, parameters) {
|
|
4963
|
-
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
4964
|
-
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
4965
|
-
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
4966
|
-
}
|
|
4967
|
-
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
4968
|
-
// TODO: [๐ต]
|
|
4969
|
-
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
4970
|
-
}
|
|
4971
|
-
}
|
|
4972
|
-
let replacedTemplates = template;
|
|
4973
|
-
let match;
|
|
4974
|
-
let loopLimit = LOOP_LIMIT;
|
|
4975
|
-
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
4976
|
-
.exec(replacedTemplates))) {
|
|
4977
|
-
if (loopLimit-- < 0) {
|
|
4978
|
-
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
4979
|
-
}
|
|
4980
|
-
const precol = match.groups.precol;
|
|
4981
|
-
const parameterName = match.groups.parameterName;
|
|
4982
|
-
if (parameterName === '') {
|
|
4983
|
-
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
4984
|
-
continue;
|
|
4985
|
-
}
|
|
4986
|
-
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
4987
|
-
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
4988
|
-
}
|
|
4989
|
-
if (parameters[parameterName] === undefined) {
|
|
4990
|
-
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4991
|
-
}
|
|
4992
|
-
let parameterValue = parameters[parameterName];
|
|
4993
|
-
if (parameterValue === undefined) {
|
|
4994
|
-
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4995
|
-
}
|
|
4996
|
-
parameterValue = valueToString(parameterValue);
|
|
4997
|
-
// Escape curly braces in parameter values to prevent prompt-injection
|
|
4998
|
-
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
4999
|
-
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
5000
|
-
parameterValue = parameterValue
|
|
5001
|
-
.split('\n')
|
|
5002
|
-
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
5003
|
-
.join('\n');
|
|
5004
|
-
}
|
|
5005
|
-
replacedTemplates =
|
|
5006
|
-
replacedTemplates.substring(0, match.index + precol.length) +
|
|
5007
|
-
parameterValue +
|
|
5008
|
-
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
5009
|
-
}
|
|
5010
|
-
// [๐ซ] Check if there are parameters that are not closed properly
|
|
5011
|
-
if (/{\w+$/.test(replacedTemplates)) {
|
|
5012
|
-
throw new PipelineExecutionError('Parameter is not closed');
|
|
5013
|
-
}
|
|
5014
|
-
// [๐ซ] Check if there are parameters that are not opened properly
|
|
5015
|
-
if (/^\w+}/.test(replacedTemplates)) {
|
|
5016
|
-
throw new PipelineExecutionError('Parameter is not opened');
|
|
5017
|
-
}
|
|
5018
|
-
return replacedTemplates;
|
|
5019
|
-
}
|
|
5020
|
-
|
|
5021
5021
|
/**
|
|
5022
5022
|
* Counts number of characters in the text
|
|
5023
5023
|
*
|
|
@@ -5178,6 +5178,68 @@
|
|
|
5178
5178
|
* Note: [๐] and [๐ค ] are interconnected together
|
|
5179
5179
|
*/
|
|
5180
5180
|
|
|
5181
|
+
/**
|
|
5182
|
+
* Validates a prompt result against expectations and format requirements.
|
|
5183
|
+
* This function provides a common abstraction for result validation that can be used
|
|
5184
|
+
* by both execution logic and caching logic to ensure consistency.
|
|
5185
|
+
*
|
|
5186
|
+
* @param options - The validation options including result string, expectations, and format
|
|
5187
|
+
* @returns Validation result with processed string and validity status
|
|
5188
|
+
* @private internal function of `createPipelineExecutor` and `cacheLlmTools`
|
|
5189
|
+
*/
|
|
5190
|
+
function validatePromptResult(options) {
|
|
5191
|
+
const { resultString, expectations, format } = options;
|
|
5192
|
+
let processedResultString = resultString;
|
|
5193
|
+
let validationError;
|
|
5194
|
+
try {
|
|
5195
|
+
// TODO: [๐] Unite object for expecting amount and format
|
|
5196
|
+
if (format) {
|
|
5197
|
+
if (format === 'JSON') {
|
|
5198
|
+
if (!isValidJsonString(processedResultString)) {
|
|
5199
|
+
// TODO: [๐ข] Do more universally via `FormatParser`
|
|
5200
|
+
try {
|
|
5201
|
+
processedResultString = extractJsonBlock(processedResultString);
|
|
5202
|
+
}
|
|
5203
|
+
catch (error) {
|
|
5204
|
+
keepUnused(error);
|
|
5205
|
+
throw new ExpectError(spaceTrim.spaceTrim((block) => `
|
|
5206
|
+
Expected valid JSON string
|
|
5207
|
+
|
|
5208
|
+
The expected JSON text:
|
|
5209
|
+
${block(processedResultString)}
|
|
5210
|
+
`));
|
|
5211
|
+
}
|
|
5212
|
+
}
|
|
5213
|
+
}
|
|
5214
|
+
else {
|
|
5215
|
+
throw new UnexpectedError(`Unknown format "${format}"`);
|
|
5216
|
+
}
|
|
5217
|
+
}
|
|
5218
|
+
// TODO: [๐] Unite object for expecting amount and format
|
|
5219
|
+
if (expectations) {
|
|
5220
|
+
checkExpectations(expectations, processedResultString);
|
|
5221
|
+
}
|
|
5222
|
+
return {
|
|
5223
|
+
isValid: true,
|
|
5224
|
+
processedResultString,
|
|
5225
|
+
};
|
|
5226
|
+
}
|
|
5227
|
+
catch (error) {
|
|
5228
|
+
if (error instanceof ExpectError) {
|
|
5229
|
+
validationError = error;
|
|
5230
|
+
}
|
|
5231
|
+
else {
|
|
5232
|
+
// Re-throw non-ExpectError errors (like UnexpectedError)
|
|
5233
|
+
throw error;
|
|
5234
|
+
}
|
|
5235
|
+
return {
|
|
5236
|
+
isValid: false,
|
|
5237
|
+
processedResultString,
|
|
5238
|
+
error: validationError,
|
|
5239
|
+
};
|
|
5240
|
+
}
|
|
5241
|
+
}
|
|
5242
|
+
|
|
5181
5243
|
/**
|
|
5182
5244
|
* Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
|
|
5183
5245
|
* (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
|
|
@@ -5200,13 +5262,13 @@
|
|
|
5200
5262
|
// TODO: [๐] Make arrayable LLMs -> single LLM DRY
|
|
5201
5263
|
const _llms = arrayableToArray(tools.llm);
|
|
5202
5264
|
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
5203
|
-
attempts: for (let
|
|
5204
|
-
const isJokerAttempt =
|
|
5205
|
-
const jokerParameterName = jokerParameterNames[jokerParameterNames.length +
|
|
5265
|
+
attempts: for (let attemptIndex = -jokerParameterNames.length; attemptIndex < maxAttempts; attemptIndex++) {
|
|
5266
|
+
const isJokerAttempt = attemptIndex < 0;
|
|
5267
|
+
const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
|
|
5206
5268
|
// TODO: [๐ง ][๐ญ] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
|
|
5207
5269
|
if (isJokerAttempt && !jokerParameterName) {
|
|
5208
5270
|
throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
|
|
5209
|
-
Joker not found in attempt ${
|
|
5271
|
+
Joker not found in attempt ${attemptIndex}
|
|
5210
5272
|
|
|
5211
5273
|
${block(pipelineIdentification)}
|
|
5212
5274
|
`));
|
|
@@ -5404,35 +5466,18 @@
|
|
|
5404
5466
|
}
|
|
5405
5467
|
}
|
|
5406
5468
|
// TODO: [๐] Unite object for expecting amount and format
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
throw new ExpectError(spaceTrim.spaceTrim((block) => `
|
|
5417
|
-
Expected valid JSON string
|
|
5418
|
-
|
|
5419
|
-
${block(
|
|
5420
|
-
/*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ '')}
|
|
5421
|
-
`));
|
|
5422
|
-
}
|
|
5423
|
-
}
|
|
5424
|
-
}
|
|
5425
|
-
else {
|
|
5426
|
-
throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
|
|
5427
|
-
Unknown format "${task.format}"
|
|
5428
|
-
|
|
5429
|
-
${block(pipelineIdentification)}
|
|
5430
|
-
`));
|
|
5469
|
+
// Use the common validation function for both format and expectations
|
|
5470
|
+
if (task.format || task.expectations) {
|
|
5471
|
+
const validationResult = validatePromptResult({
|
|
5472
|
+
resultString: $ongoingTaskResult.$resultString || '',
|
|
5473
|
+
expectations: task.expectations,
|
|
5474
|
+
format: task.format,
|
|
5475
|
+
});
|
|
5476
|
+
if (!validationResult.isValid) {
|
|
5477
|
+
throw validationResult.error;
|
|
5431
5478
|
}
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
if (task.expectations) {
|
|
5435
|
-
checkExpectations(task.expectations, $ongoingTaskResult.$resultString || '');
|
|
5479
|
+
// Update the result string in case format processing modified it (e.g., JSON extraction)
|
|
5480
|
+
$ongoingTaskResult.$resultString = validationResult.processedResultString;
|
|
5436
5481
|
}
|
|
5437
5482
|
break attempts;
|
|
5438
5483
|
}
|
|
@@ -5446,6 +5491,7 @@
|
|
|
5446
5491
|
$ongoingTaskResult.$failedResults = [];
|
|
5447
5492
|
}
|
|
5448
5493
|
$ongoingTaskResult.$failedResults.push({
|
|
5494
|
+
attemptIndex,
|
|
5449
5495
|
result: $ongoingTaskResult.$resultString,
|
|
5450
5496
|
error: error,
|
|
5451
5497
|
});
|
|
@@ -5470,19 +5516,13 @@
|
|
|
5470
5516
|
});
|
|
5471
5517
|
}
|
|
5472
5518
|
}
|
|
5473
|
-
if ($ongoingTaskResult.$expectError !== null &&
|
|
5474
|
-
//
|
|
5475
|
-
$ongoingTaskResult.$failedResults = $ongoingTaskResult.$failedResults || [];
|
|
5476
|
-
$ongoingTaskResult.$failedResults.push({
|
|
5477
|
-
result: $ongoingTaskResult.$resultString,
|
|
5478
|
-
error: $ongoingTaskResult.$expectError,
|
|
5479
|
-
});
|
|
5480
|
-
// Create a summary of all failures
|
|
5519
|
+
if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
|
|
5520
|
+
// Note: Create a summary of all failures
|
|
5481
5521
|
const failuresSummary = $ongoingTaskResult.$failedResults
|
|
5482
|
-
.map((failure
|
|
5522
|
+
.map((failure) => spaceTrim.spaceTrim((block) => {
|
|
5483
5523
|
var _a, _b;
|
|
5484
5524
|
return `
|
|
5485
|
-
Attempt ${
|
|
5525
|
+
Attempt ${failure.attemptIndex + 1}:
|
|
5486
5526
|
Error ${((_a = failure.error) === null || _a === void 0 ? void 0 : _a.name) || ''}:
|
|
5487
5527
|
${block((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message.split('\n').map((line) => `> ${line}`).join('\n'))}
|
|
5488
5528
|
|