@promptbook/remote-server 0.95.0 โ 0.98.0-10
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 +12 -0
- package/esm/index.es.js +303 -181
- 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/cli.index.d.ts +4 -0
- package/esm/typings/src/_packages/core.index.d.ts +2 -0
- package/esm/typings/src/_packages/openai.index.d.ts +10 -0
- package/esm/typings/src/_packages/types.index.d.ts +12 -2
- package/esm/typings/src/_packages/wizard.index.d.ts +4 -0
- package/esm/typings/src/config.d.ts +1 -1
- package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +8 -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/OpenAiAssistantExecutionToolsOptions.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 +52 -0
- package/esm/typings/src/llm-providers/openai/OpenAiExecutionToolsOptions.d.ts +3 -5
- package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +74 -0
- package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +11 -0
- package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +14 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +303 -181
- 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.
|
|
51
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-10';
|
|
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.
|
|
@@ -5195,17 +5257,18 @@
|
|
|
5195
5257
|
$resultString: null,
|
|
5196
5258
|
$expectError: null,
|
|
5197
5259
|
$scriptPipelineExecutionErrors: [],
|
|
5260
|
+
$failedResults: [], // Track all failed attempts
|
|
5198
5261
|
};
|
|
5199
5262
|
// TODO: [๐] Make arrayable LLMs -> single LLM DRY
|
|
5200
5263
|
const _llms = arrayableToArray(tools.llm);
|
|
5201
5264
|
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
5202
|
-
attempts: for (let
|
|
5203
|
-
const isJokerAttempt =
|
|
5204
|
-
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];
|
|
5205
5268
|
// TODO: [๐ง ][๐ญ] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
|
|
5206
5269
|
if (isJokerAttempt && !jokerParameterName) {
|
|
5207
5270
|
throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
|
|
5208
|
-
Joker not found in attempt ${
|
|
5271
|
+
Joker not found in attempt ${attemptIndex}
|
|
5209
5272
|
|
|
5210
5273
|
${block(pipelineIdentification)}
|
|
5211
5274
|
`));
|
|
@@ -5403,35 +5466,18 @@
|
|
|
5403
5466
|
}
|
|
5404
5467
|
}
|
|
5405
5468
|
// TODO: [๐] Unite object for expecting amount and format
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
throw new ExpectError(spaceTrim.spaceTrim((block) => `
|
|
5416
|
-
Expected valid JSON string
|
|
5417
|
-
|
|
5418
|
-
${block(
|
|
5419
|
-
/*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ '')}
|
|
5420
|
-
`));
|
|
5421
|
-
}
|
|
5422
|
-
}
|
|
5423
|
-
}
|
|
5424
|
-
else {
|
|
5425
|
-
throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
|
|
5426
|
-
Unknown format "${task.format}"
|
|
5427
|
-
|
|
5428
|
-
${block(pipelineIdentification)}
|
|
5429
|
-
`));
|
|
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;
|
|
5430
5478
|
}
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
if (task.expectations) {
|
|
5434
|
-
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;
|
|
5435
5481
|
}
|
|
5436
5482
|
break attempts;
|
|
5437
5483
|
}
|
|
@@ -5440,6 +5486,15 @@
|
|
|
5440
5486
|
throw error;
|
|
5441
5487
|
}
|
|
5442
5488
|
$ongoingTaskResult.$expectError = error;
|
|
5489
|
+
// Store each failed attempt
|
|
5490
|
+
if (!Array.isArray($ongoingTaskResult.$failedResults)) {
|
|
5491
|
+
$ongoingTaskResult.$failedResults = [];
|
|
5492
|
+
}
|
|
5493
|
+
$ongoingTaskResult.$failedResults.push({
|
|
5494
|
+
attemptIndex,
|
|
5495
|
+
result: $ongoingTaskResult.$resultString,
|
|
5496
|
+
error: error,
|
|
5497
|
+
});
|
|
5443
5498
|
}
|
|
5444
5499
|
finally {
|
|
5445
5500
|
if (!isJokerAttempt &&
|
|
@@ -5461,35 +5516,41 @@
|
|
|
5461
5516
|
});
|
|
5462
5517
|
}
|
|
5463
5518
|
}
|
|
5464
|
-
if ($ongoingTaskResult.$expectError !== null &&
|
|
5519
|
+
if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
|
|
5520
|
+
// Note: Create a summary of all failures
|
|
5521
|
+
const failuresSummary = $ongoingTaskResult.$failedResults
|
|
5522
|
+
.map((failure) => spaceTrim.spaceTrim((block) => {
|
|
5523
|
+
var _a, _b;
|
|
5524
|
+
return `
|
|
5525
|
+
Attempt ${failure.attemptIndex + 1}:
|
|
5526
|
+
Error ${((_a = failure.error) === null || _a === void 0 ? void 0 : _a.name) || ''}:
|
|
5527
|
+
${block((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message.split('\n').map((line) => `> ${line}`).join('\n'))}
|
|
5528
|
+
|
|
5529
|
+
Result:
|
|
5530
|
+
${block(failure.result === null
|
|
5531
|
+
? 'null'
|
|
5532
|
+
: spaceTrim.spaceTrim(failure.result)
|
|
5533
|
+
.split('\n')
|
|
5534
|
+
.map((line) => `> ${line}`)
|
|
5535
|
+
.join('\n'))}
|
|
5536
|
+
`;
|
|
5537
|
+
}))
|
|
5538
|
+
.join('\n\n---\n\n');
|
|
5465
5539
|
throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => {
|
|
5466
|
-
var _a
|
|
5540
|
+
var _a;
|
|
5467
5541
|
return `
|
|
5468
5542
|
LLM execution failed ${maxExecutionAttempts}x
|
|
5469
5543
|
|
|
5470
5544
|
${block(pipelineIdentification)}
|
|
5471
5545
|
|
|
5472
|
-
---
|
|
5473
5546
|
The Prompt:
|
|
5474
5547
|
${block((((_a = $ongoingTaskResult.$prompt) === null || _a === void 0 ? void 0 : _a.content) || '')
|
|
5475
5548
|
.split('\n')
|
|
5476
5549
|
.map((line) => `> ${line}`)
|
|
5477
5550
|
.join('\n'))}
|
|
5478
5551
|
|
|
5479
|
-
|
|
5480
|
-
${block(
|
|
5481
|
-
.split('\n')
|
|
5482
|
-
.map((line) => `> ${line}`)
|
|
5483
|
-
.join('\n'))}
|
|
5484
|
-
|
|
5485
|
-
Last result:
|
|
5486
|
-
${block($ongoingTaskResult.$resultString === null
|
|
5487
|
-
? 'null'
|
|
5488
|
-
: spaceTrim.spaceTrim($ongoingTaskResult.$resultString)
|
|
5489
|
-
.split('\n')
|
|
5490
|
-
.map((line) => `> ${line}`)
|
|
5491
|
-
.join('\n'))}
|
|
5492
|
-
---
|
|
5552
|
+
All Failed Attempts:
|
|
5553
|
+
${block(failuresSummary)}
|
|
5493
5554
|
`;
|
|
5494
5555
|
}));
|
|
5495
5556
|
}
|
|
@@ -6320,6 +6381,46 @@
|
|
|
6320
6381
|
return pipelineExecutor;
|
|
6321
6382
|
}
|
|
6322
6383
|
|
|
6384
|
+
/**
|
|
6385
|
+
* Detects if the code is running in a browser environment in main thread (Not in a web worker)
|
|
6386
|
+
*
|
|
6387
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
6388
|
+
*
|
|
6389
|
+
* @public exported from `@promptbook/utils`
|
|
6390
|
+
*/
|
|
6391
|
+
const $isRunningInBrowser = new Function(`
|
|
6392
|
+
try {
|
|
6393
|
+
return this === window;
|
|
6394
|
+
} catch (e) {
|
|
6395
|
+
return false;
|
|
6396
|
+
}
|
|
6397
|
+
`);
|
|
6398
|
+
/**
|
|
6399
|
+
* TODO: [๐บ]
|
|
6400
|
+
*/
|
|
6401
|
+
|
|
6402
|
+
/**
|
|
6403
|
+
* Detects if the code is running in a web worker
|
|
6404
|
+
*
|
|
6405
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
6406
|
+
*
|
|
6407
|
+
* @public exported from `@promptbook/utils`
|
|
6408
|
+
*/
|
|
6409
|
+
const $isRunningInWebWorker = new Function(`
|
|
6410
|
+
try {
|
|
6411
|
+
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
|
|
6412
|
+
return true;
|
|
6413
|
+
} else {
|
|
6414
|
+
return false;
|
|
6415
|
+
}
|
|
6416
|
+
} catch (e) {
|
|
6417
|
+
return false;
|
|
6418
|
+
}
|
|
6419
|
+
`);
|
|
6420
|
+
/**
|
|
6421
|
+
* TODO: [๐บ]
|
|
6422
|
+
*/
|
|
6423
|
+
|
|
6323
6424
|
/**
|
|
6324
6425
|
* Register for LLM tools.
|
|
6325
6426
|
*
|
|
@@ -6488,8 +6589,10 @@
|
|
|
6488
6589
|
.list()
|
|
6489
6590
|
.find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
|
|
6490
6591
|
if (registeredItem === undefined) {
|
|
6592
|
+
console.log('!!! $llmToolsRegister.list()', $llmToolsRegister.list());
|
|
6491
6593
|
throw new Error(spaceTrim__default["default"]((block) => `
|
|
6492
6594
|
There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
|
|
6595
|
+
Running in ${!$isRunningInBrowser() ? '' : 'browser environment'}${!$isRunningInNode() ? '' : 'node environment'}${!$isRunningInWebWorker() ? '' : 'worker environment'}
|
|
6493
6596
|
|
|
6494
6597
|
You have probably forgotten install and import the provider package.
|
|
6495
6598
|
To fix this issue, you can:
|
|
@@ -6607,24 +6710,6 @@
|
|
|
6607
6710
|
* TODO: [๐บ] Use some intermediate util splitWords
|
|
6608
6711
|
*/
|
|
6609
6712
|
|
|
6610
|
-
/**
|
|
6611
|
-
* Detects if the code is running in a browser environment in main thread (Not in a web worker)
|
|
6612
|
-
*
|
|
6613
|
-
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
6614
|
-
*
|
|
6615
|
-
* @public exported from `@promptbook/utils`
|
|
6616
|
-
*/
|
|
6617
|
-
new Function(`
|
|
6618
|
-
try {
|
|
6619
|
-
return this === window;
|
|
6620
|
-
} catch (e) {
|
|
6621
|
-
return false;
|
|
6622
|
-
}
|
|
6623
|
-
`);
|
|
6624
|
-
/**
|
|
6625
|
-
* TODO: [๐บ]
|
|
6626
|
-
*/
|
|
6627
|
-
|
|
6628
6713
|
/**
|
|
6629
6714
|
* Detects if the code is running in jest environment
|
|
6630
6715
|
*
|
|
@@ -6643,28 +6728,6 @@
|
|
|
6643
6728
|
* TODO: [๐บ]
|
|
6644
6729
|
*/
|
|
6645
6730
|
|
|
6646
|
-
/**
|
|
6647
|
-
* Detects if the code is running in a web worker
|
|
6648
|
-
*
|
|
6649
|
-
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
6650
|
-
*
|
|
6651
|
-
* @public exported from `@promptbook/utils`
|
|
6652
|
-
*/
|
|
6653
|
-
new Function(`
|
|
6654
|
-
try {
|
|
6655
|
-
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
|
|
6656
|
-
return true;
|
|
6657
|
-
} else {
|
|
6658
|
-
return false;
|
|
6659
|
-
}
|
|
6660
|
-
} catch (e) {
|
|
6661
|
-
return false;
|
|
6662
|
-
}
|
|
6663
|
-
`);
|
|
6664
|
-
/**
|
|
6665
|
-
* TODO: [๐บ]
|
|
6666
|
-
*/
|
|
6667
|
-
|
|
6668
6731
|
/**
|
|
6669
6732
|
* Makes first letter of a string uppercase
|
|
6670
6733
|
*
|
|
@@ -7836,6 +7899,66 @@
|
|
|
7836
7899
|
response.setHeader('X-Powered-By', 'Promptbook engine');
|
|
7837
7900
|
next();
|
|
7838
7901
|
});
|
|
7902
|
+
// Note: OpenAI-compatible chat completions endpoint
|
|
7903
|
+
app.post('/v1/chat/completions', async (request, response) => {
|
|
7904
|
+
// TODO: !!!! Make more promptbook-native:
|
|
7905
|
+
try {
|
|
7906
|
+
const params = request.body;
|
|
7907
|
+
const { model, messages } = params;
|
|
7908
|
+
// Convert messages to a single prompt
|
|
7909
|
+
const prompt = messages
|
|
7910
|
+
.map((message) => `${message.role}: ${message.content}`)
|
|
7911
|
+
.join('\n');
|
|
7912
|
+
// Get pipeline for the book
|
|
7913
|
+
if (!collection) {
|
|
7914
|
+
throw new Error('No collection available');
|
|
7915
|
+
}
|
|
7916
|
+
const pipeline = await collection.getPipelineByUrl(model);
|
|
7917
|
+
const pipelineExecutor = createPipelineExecutor({
|
|
7918
|
+
pipeline,
|
|
7919
|
+
tools: await getExecutionToolsFromIdentification({
|
|
7920
|
+
isAnonymous: true,
|
|
7921
|
+
llmToolsConfiguration: [],
|
|
7922
|
+
}),
|
|
7923
|
+
});
|
|
7924
|
+
// Execute the pipeline with the prompt content as input
|
|
7925
|
+
const result = await pipelineExecutor({ prompt }).asPromise({ isCrashedOnError: true });
|
|
7926
|
+
if (!result.isSuccessful) {
|
|
7927
|
+
throw new Error(`Failed to execute book: ${result.errors.join(', ')}`);
|
|
7928
|
+
}
|
|
7929
|
+
// Return the result in OpenAI-compatible format
|
|
7930
|
+
response.json({
|
|
7931
|
+
id: 'chatcmpl-' + Math.random().toString(36).substring(2),
|
|
7932
|
+
object: 'chat.completion',
|
|
7933
|
+
created: Math.floor(Date.now() / 1000),
|
|
7934
|
+
model,
|
|
7935
|
+
choices: [
|
|
7936
|
+
{
|
|
7937
|
+
index: 0,
|
|
7938
|
+
message: {
|
|
7939
|
+
role: 'assistant',
|
|
7940
|
+
content: result.outputParameters.response,
|
|
7941
|
+
},
|
|
7942
|
+
finish_reason: 'stop',
|
|
7943
|
+
},
|
|
7944
|
+
],
|
|
7945
|
+
usage: {
|
|
7946
|
+
prompt_tokens: 0,
|
|
7947
|
+
completion_tokens: 0,
|
|
7948
|
+
total_tokens: 0,
|
|
7949
|
+
},
|
|
7950
|
+
});
|
|
7951
|
+
}
|
|
7952
|
+
catch (error) {
|
|
7953
|
+
response.status(500).json({
|
|
7954
|
+
error: {
|
|
7955
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
7956
|
+
type: 'server_error',
|
|
7957
|
+
code: 'internal_error',
|
|
7958
|
+
},
|
|
7959
|
+
});
|
|
7960
|
+
}
|
|
7961
|
+
});
|
|
7839
7962
|
// TODO: [๐ฅบ] Expose openapiJson to consumer and also allow to add new routes
|
|
7840
7963
|
app.use(OpenApiValidator__namespace.middleware({
|
|
7841
7964
|
apiSpec: openapiJson,
|
|
@@ -8196,7 +8319,6 @@
|
|
|
8196
8319
|
catch (error) {
|
|
8197
8320
|
assertsError(error);
|
|
8198
8321
|
socket.emit('error', serializeError(error));
|
|
8199
|
-
// <- TODO: [๐] There is a problem with the remote server handling errors and sending them back to the client
|
|
8200
8322
|
}
|
|
8201
8323
|
finally {
|
|
8202
8324
|
socket.disconnect();
|