@promptbook/core 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 +247 -151
- 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 +1 -1
- package/umd/index.umd.js +247 -151
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -27,7 +27,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
27
27
|
* @generated
|
|
28
28
|
* @see https://github.com/webgptorg/promptbook
|
|
29
29
|
*/
|
|
30
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-
|
|
30
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-8';
|
|
31
31
|
/**
|
|
32
32
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
33
33
|
* Note: [๐] Ignore a discrepancy between file name and entity name
|
|
@@ -354,7 +354,7 @@ const DEFAULT_MAX_PARALLEL_COUNT = 5; // <- TODO: [๐คนโโ๏ธ]
|
|
|
354
354
|
*
|
|
355
355
|
* @public exported from `@promptbook/core`
|
|
356
356
|
*/
|
|
357
|
-
const DEFAULT_MAX_EXECUTION_ATTEMPTS =
|
|
357
|
+
const DEFAULT_MAX_EXECUTION_ATTEMPTS = 7; // <- TODO: [๐คนโโ๏ธ]
|
|
358
358
|
/**
|
|
359
359
|
* The maximum depth to which knowledge sources will be scraped when building a knowledge base.
|
|
360
360
|
* This prevents infinite recursion and limits resource usage.
|
|
@@ -2255,7 +2255,7 @@ function jsonParse(value) {
|
|
|
2255
2255
|
throw new Error(spaceTrim((block) => `
|
|
2256
2256
|
${block(error.message)}
|
|
2257
2257
|
|
|
2258
|
-
The JSON text:
|
|
2258
|
+
The expected JSON text:
|
|
2259
2259
|
${block(value)}
|
|
2260
2260
|
`));
|
|
2261
2261
|
}
|
|
@@ -3387,108 +3387,6 @@ function joinLlmExecutionTools(...llmExecutionTools) {
|
|
|
3387
3387
|
* TODO: [๐ทโโ๏ธ] @@@ Manual about construction of llmTools
|
|
3388
3388
|
*/
|
|
3389
3389
|
|
|
3390
|
-
/**
|
|
3391
|
-
* Extracts all code blocks from markdown.
|
|
3392
|
-
*
|
|
3393
|
-
* Note: There are multiple similar functions:
|
|
3394
|
-
* - `extractBlock` just extracts the content of the code block which is also used as built-in function for postprocessing
|
|
3395
|
-
* - `extractJsonBlock` extracts exactly one valid JSON code block
|
|
3396
|
-
* - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
|
|
3397
|
-
* - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
|
|
3398
|
-
*
|
|
3399
|
-
* @param markdown any valid markdown
|
|
3400
|
-
* @returns code blocks with language and content
|
|
3401
|
-
* @throws {ParseError} if block is not closed properly
|
|
3402
|
-
* @public exported from `@promptbook/markdown-utils`
|
|
3403
|
-
*/
|
|
3404
|
-
function extractAllBlocksFromMarkdown(markdown) {
|
|
3405
|
-
const codeBlocks = [];
|
|
3406
|
-
const lines = markdown.split('\n');
|
|
3407
|
-
// Note: [0] Ensure that the last block notated by gt > will be closed
|
|
3408
|
-
lines.push('');
|
|
3409
|
-
let currentCodeBlock = null;
|
|
3410
|
-
for (const line of lines) {
|
|
3411
|
-
if (line.startsWith('> ') || line === '>') {
|
|
3412
|
-
if (currentCodeBlock === null) {
|
|
3413
|
-
currentCodeBlock = { blockNotation: '>', language: null, content: '' };
|
|
3414
|
-
} /* not else */
|
|
3415
|
-
if (currentCodeBlock.blockNotation === '>') {
|
|
3416
|
-
if (currentCodeBlock.content !== '') {
|
|
3417
|
-
currentCodeBlock.content += '\n';
|
|
3418
|
-
}
|
|
3419
|
-
currentCodeBlock.content += line.slice(2);
|
|
3420
|
-
}
|
|
3421
|
-
}
|
|
3422
|
-
else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
|
|
3423
|
-
codeBlocks.push(currentCodeBlock);
|
|
3424
|
-
currentCodeBlock = null;
|
|
3425
|
-
}
|
|
3426
|
-
/* not else */
|
|
3427
|
-
if (line.startsWith('```')) {
|
|
3428
|
-
const language = line.slice(3).trim() || null;
|
|
3429
|
-
if (currentCodeBlock === null) {
|
|
3430
|
-
currentCodeBlock = { blockNotation: '```', language, content: '' };
|
|
3431
|
-
}
|
|
3432
|
-
else {
|
|
3433
|
-
if (language !== null) {
|
|
3434
|
-
throw new ParseError(`${capitalize(currentCodeBlock.language || 'the')} code block was not closed and already opening new ${language} code block`);
|
|
3435
|
-
}
|
|
3436
|
-
codeBlocks.push(currentCodeBlock);
|
|
3437
|
-
currentCodeBlock = null;
|
|
3438
|
-
}
|
|
3439
|
-
}
|
|
3440
|
-
else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
|
|
3441
|
-
if (currentCodeBlock.content !== '') {
|
|
3442
|
-
currentCodeBlock.content += '\n';
|
|
3443
|
-
}
|
|
3444
|
-
currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make proper unescape */;
|
|
3445
|
-
}
|
|
3446
|
-
}
|
|
3447
|
-
if (currentCodeBlock !== null) {
|
|
3448
|
-
throw new ParseError(`${capitalize(currentCodeBlock.language || 'the')} code block was not closed at the end of the markdown`);
|
|
3449
|
-
}
|
|
3450
|
-
return codeBlocks;
|
|
3451
|
-
}
|
|
3452
|
-
/**
|
|
3453
|
-
* TODO: Maybe name for `blockNotation` instead of '```' and '>'
|
|
3454
|
-
*/
|
|
3455
|
-
|
|
3456
|
-
/**
|
|
3457
|
-
* Extracts extracts exactly one valid JSON code block
|
|
3458
|
-
*
|
|
3459
|
-
* - When given string is a valid JSON as it is, it just returns it
|
|
3460
|
-
* - When there is no JSON code block the function throws a `ParseError`
|
|
3461
|
-
* - When there are multiple JSON code blocks the function throws a `ParseError`
|
|
3462
|
-
*
|
|
3463
|
-
* Note: It is not important if marked as ```json BUT if it is VALID JSON
|
|
3464
|
-
* Note: There are multiple similar function:
|
|
3465
|
-
* - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
|
|
3466
|
-
* - `extractJsonBlock` extracts exactly one valid JSON code block
|
|
3467
|
-
* - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
|
|
3468
|
-
* - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
|
|
3469
|
-
*
|
|
3470
|
-
* @public exported from `@promptbook/markdown-utils`
|
|
3471
|
-
* @throws {ParseError} if there is no valid JSON block in the markdown
|
|
3472
|
-
*/
|
|
3473
|
-
function extractJsonBlock(markdown) {
|
|
3474
|
-
if (isValidJsonString(markdown)) {
|
|
3475
|
-
return markdown;
|
|
3476
|
-
}
|
|
3477
|
-
const codeBlocks = extractAllBlocksFromMarkdown(markdown);
|
|
3478
|
-
const jsonBlocks = codeBlocks.filter(({ content }) => isValidJsonString(content));
|
|
3479
|
-
if (jsonBlocks.length === 0) {
|
|
3480
|
-
throw new Error('There is no valid JSON block in the markdown');
|
|
3481
|
-
}
|
|
3482
|
-
if (jsonBlocks.length > 1) {
|
|
3483
|
-
throw new Error('There are multiple JSON code blocks in the markdown');
|
|
3484
|
-
}
|
|
3485
|
-
return jsonBlocks[0].content;
|
|
3486
|
-
}
|
|
3487
|
-
/**
|
|
3488
|
-
* TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
|
|
3489
|
-
* TODO: [๐ข] Make this logic part of `JsonFormatParser` or `isValidJsonString`
|
|
3490
|
-
*/
|
|
3491
|
-
|
|
3492
3390
|
/**
|
|
3493
3391
|
* Takes an item or an array of items and returns an array of items
|
|
3494
3392
|
*
|
|
@@ -3596,6 +3494,108 @@ function templateParameters(template, parameters) {
|
|
|
3596
3494
|
return replacedTemplates;
|
|
3597
3495
|
}
|
|
3598
3496
|
|
|
3497
|
+
/**
|
|
3498
|
+
* Extracts all code blocks from markdown.
|
|
3499
|
+
*
|
|
3500
|
+
* Note: There are multiple similar functions:
|
|
3501
|
+
* - `extractBlock` just extracts the content of the code block which is also used as built-in function for postprocessing
|
|
3502
|
+
* - `extractJsonBlock` extracts exactly one valid JSON code block
|
|
3503
|
+
* - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
|
|
3504
|
+
* - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
|
|
3505
|
+
*
|
|
3506
|
+
* @param markdown any valid markdown
|
|
3507
|
+
* @returns code blocks with language and content
|
|
3508
|
+
* @throws {ParseError} if block is not closed properly
|
|
3509
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
3510
|
+
*/
|
|
3511
|
+
function extractAllBlocksFromMarkdown(markdown) {
|
|
3512
|
+
const codeBlocks = [];
|
|
3513
|
+
const lines = markdown.split('\n');
|
|
3514
|
+
// Note: [0] Ensure that the last block notated by gt > will be closed
|
|
3515
|
+
lines.push('');
|
|
3516
|
+
let currentCodeBlock = null;
|
|
3517
|
+
for (const line of lines) {
|
|
3518
|
+
if (line.startsWith('> ') || line === '>') {
|
|
3519
|
+
if (currentCodeBlock === null) {
|
|
3520
|
+
currentCodeBlock = { blockNotation: '>', language: null, content: '' };
|
|
3521
|
+
} /* not else */
|
|
3522
|
+
if (currentCodeBlock.blockNotation === '>') {
|
|
3523
|
+
if (currentCodeBlock.content !== '') {
|
|
3524
|
+
currentCodeBlock.content += '\n';
|
|
3525
|
+
}
|
|
3526
|
+
currentCodeBlock.content += line.slice(2);
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3529
|
+
else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
|
|
3530
|
+
codeBlocks.push(currentCodeBlock);
|
|
3531
|
+
currentCodeBlock = null;
|
|
3532
|
+
}
|
|
3533
|
+
/* not else */
|
|
3534
|
+
if (line.startsWith('```')) {
|
|
3535
|
+
const language = line.slice(3).trim() || null;
|
|
3536
|
+
if (currentCodeBlock === null) {
|
|
3537
|
+
currentCodeBlock = { blockNotation: '```', language, content: '' };
|
|
3538
|
+
}
|
|
3539
|
+
else {
|
|
3540
|
+
if (language !== null) {
|
|
3541
|
+
throw new ParseError(`${capitalize(currentCodeBlock.language || 'the')} code block was not closed and already opening new ${language} code block`);
|
|
3542
|
+
}
|
|
3543
|
+
codeBlocks.push(currentCodeBlock);
|
|
3544
|
+
currentCodeBlock = null;
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
|
|
3548
|
+
if (currentCodeBlock.content !== '') {
|
|
3549
|
+
currentCodeBlock.content += '\n';
|
|
3550
|
+
}
|
|
3551
|
+
currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make proper unescape */;
|
|
3552
|
+
}
|
|
3553
|
+
}
|
|
3554
|
+
if (currentCodeBlock !== null) {
|
|
3555
|
+
throw new ParseError(`${capitalize(currentCodeBlock.language || 'the')} code block was not closed at the end of the markdown`);
|
|
3556
|
+
}
|
|
3557
|
+
return codeBlocks;
|
|
3558
|
+
}
|
|
3559
|
+
/**
|
|
3560
|
+
* TODO: Maybe name for `blockNotation` instead of '```' and '>'
|
|
3561
|
+
*/
|
|
3562
|
+
|
|
3563
|
+
/**
|
|
3564
|
+
* Extracts extracts exactly one valid JSON code block
|
|
3565
|
+
*
|
|
3566
|
+
* - When given string is a valid JSON as it is, it just returns it
|
|
3567
|
+
* - When there is no JSON code block the function throws a `ParseError`
|
|
3568
|
+
* - When there are multiple JSON code blocks the function throws a `ParseError`
|
|
3569
|
+
*
|
|
3570
|
+
* Note: It is not important if marked as ```json BUT if it is VALID JSON
|
|
3571
|
+
* Note: There are multiple similar function:
|
|
3572
|
+
* - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
|
|
3573
|
+
* - `extractJsonBlock` extracts exactly one valid JSON code block
|
|
3574
|
+
* - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
|
|
3575
|
+
* - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
|
|
3576
|
+
*
|
|
3577
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
3578
|
+
* @throws {ParseError} if there is no valid JSON block in the markdown
|
|
3579
|
+
*/
|
|
3580
|
+
function extractJsonBlock(markdown) {
|
|
3581
|
+
if (isValidJsonString(markdown)) {
|
|
3582
|
+
return markdown;
|
|
3583
|
+
}
|
|
3584
|
+
const codeBlocks = extractAllBlocksFromMarkdown(markdown);
|
|
3585
|
+
const jsonBlocks = codeBlocks.filter(({ content }) => isValidJsonString(content));
|
|
3586
|
+
if (jsonBlocks.length === 0) {
|
|
3587
|
+
throw new Error('There is no valid JSON block in the markdown');
|
|
3588
|
+
}
|
|
3589
|
+
if (jsonBlocks.length > 1) {
|
|
3590
|
+
throw new Error('There are multiple JSON code blocks in the markdown');
|
|
3591
|
+
}
|
|
3592
|
+
return jsonBlocks[0].content;
|
|
3593
|
+
}
|
|
3594
|
+
/**
|
|
3595
|
+
* TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
|
|
3596
|
+
* TODO: [๐ข] Make this logic part of `JsonFormatParser` or `isValidJsonString`
|
|
3597
|
+
*/
|
|
3598
|
+
|
|
3599
3599
|
/**
|
|
3600
3600
|
* Counts number of characters in the text
|
|
3601
3601
|
*
|
|
@@ -4039,6 +4039,68 @@ function isPassingExpectations(expectations, value) {
|
|
|
4039
4039
|
* Note: [๐] and [๐ค ] are interconnected together
|
|
4040
4040
|
*/
|
|
4041
4041
|
|
|
4042
|
+
/**
|
|
4043
|
+
* Validates a prompt result against expectations and format requirements.
|
|
4044
|
+
* This function provides a common abstraction for result validation that can be used
|
|
4045
|
+
* by both execution logic and caching logic to ensure consistency.
|
|
4046
|
+
*
|
|
4047
|
+
* @param options - The validation options including result string, expectations, and format
|
|
4048
|
+
* @returns Validation result with processed string and validity status
|
|
4049
|
+
* @private internal function of `createPipelineExecutor` and `cacheLlmTools`
|
|
4050
|
+
*/
|
|
4051
|
+
function validatePromptResult(options) {
|
|
4052
|
+
const { resultString, expectations, format } = options;
|
|
4053
|
+
let processedResultString = resultString;
|
|
4054
|
+
let validationError;
|
|
4055
|
+
try {
|
|
4056
|
+
// TODO: [๐] Unite object for expecting amount and format
|
|
4057
|
+
if (format) {
|
|
4058
|
+
if (format === 'JSON') {
|
|
4059
|
+
if (!isValidJsonString(processedResultString)) {
|
|
4060
|
+
// TODO: [๐ข] Do more universally via `FormatParser`
|
|
4061
|
+
try {
|
|
4062
|
+
processedResultString = extractJsonBlock(processedResultString);
|
|
4063
|
+
}
|
|
4064
|
+
catch (error) {
|
|
4065
|
+
keepUnused(error);
|
|
4066
|
+
throw new ExpectError(spaceTrim$1((block) => `
|
|
4067
|
+
Expected valid JSON string
|
|
4068
|
+
|
|
4069
|
+
The expected JSON text:
|
|
4070
|
+
${block(processedResultString)}
|
|
4071
|
+
`));
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
}
|
|
4075
|
+
else {
|
|
4076
|
+
throw new UnexpectedError(`Unknown format "${format}"`);
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
// TODO: [๐] Unite object for expecting amount and format
|
|
4080
|
+
if (expectations) {
|
|
4081
|
+
checkExpectations(expectations, processedResultString);
|
|
4082
|
+
}
|
|
4083
|
+
return {
|
|
4084
|
+
isValid: true,
|
|
4085
|
+
processedResultString,
|
|
4086
|
+
};
|
|
4087
|
+
}
|
|
4088
|
+
catch (error) {
|
|
4089
|
+
if (error instanceof ExpectError) {
|
|
4090
|
+
validationError = error;
|
|
4091
|
+
}
|
|
4092
|
+
else {
|
|
4093
|
+
// Re-throw non-ExpectError errors (like UnexpectedError)
|
|
4094
|
+
throw error;
|
|
4095
|
+
}
|
|
4096
|
+
return {
|
|
4097
|
+
isValid: false,
|
|
4098
|
+
processedResultString,
|
|
4099
|
+
error: validationError,
|
|
4100
|
+
};
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
|
|
4042
4104
|
/**
|
|
4043
4105
|
* Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
|
|
4044
4106
|
* (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
|
|
@@ -4061,13 +4123,13 @@ async function executeAttempts(options) {
|
|
|
4061
4123
|
// TODO: [๐] Make arrayable LLMs -> single LLM DRY
|
|
4062
4124
|
const _llms = arrayableToArray(tools.llm);
|
|
4063
4125
|
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
4064
|
-
attempts: for (let
|
|
4065
|
-
const isJokerAttempt =
|
|
4066
|
-
const jokerParameterName = jokerParameterNames[jokerParameterNames.length +
|
|
4126
|
+
attempts: for (let attemptIndex = -jokerParameterNames.length; attemptIndex < maxAttempts; attemptIndex++) {
|
|
4127
|
+
const isJokerAttempt = attemptIndex < 0;
|
|
4128
|
+
const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
|
|
4067
4129
|
// TODO: [๐ง ][๐ญ] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
|
|
4068
4130
|
if (isJokerAttempt && !jokerParameterName) {
|
|
4069
4131
|
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
4070
|
-
Joker not found in attempt ${
|
|
4132
|
+
Joker not found in attempt ${attemptIndex}
|
|
4071
4133
|
|
|
4072
4134
|
${block(pipelineIdentification)}
|
|
4073
4135
|
`));
|
|
@@ -4265,35 +4327,18 @@ async function executeAttempts(options) {
|
|
|
4265
4327
|
}
|
|
4266
4328
|
}
|
|
4267
4329
|
// TODO: [๐] Unite object for expecting amount and format
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
throw new ExpectError(spaceTrim$1((block) => `
|
|
4278
|
-
Expected valid JSON string
|
|
4279
|
-
|
|
4280
|
-
${block(
|
|
4281
|
-
/*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ '')}
|
|
4282
|
-
`));
|
|
4283
|
-
}
|
|
4284
|
-
}
|
|
4285
|
-
}
|
|
4286
|
-
else {
|
|
4287
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
4288
|
-
Unknown format "${task.format}"
|
|
4289
|
-
|
|
4290
|
-
${block(pipelineIdentification)}
|
|
4291
|
-
`));
|
|
4330
|
+
// Use the common validation function for both format and expectations
|
|
4331
|
+
if (task.format || task.expectations) {
|
|
4332
|
+
const validationResult = validatePromptResult({
|
|
4333
|
+
resultString: $ongoingTaskResult.$resultString || '',
|
|
4334
|
+
expectations: task.expectations,
|
|
4335
|
+
format: task.format,
|
|
4336
|
+
});
|
|
4337
|
+
if (!validationResult.isValid) {
|
|
4338
|
+
throw validationResult.error;
|
|
4292
4339
|
}
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
if (task.expectations) {
|
|
4296
|
-
checkExpectations(task.expectations, $ongoingTaskResult.$resultString || '');
|
|
4340
|
+
// Update the result string in case format processing modified it (e.g., JSON extraction)
|
|
4341
|
+
$ongoingTaskResult.$resultString = validationResult.processedResultString;
|
|
4297
4342
|
}
|
|
4298
4343
|
break attempts;
|
|
4299
4344
|
}
|
|
@@ -4307,6 +4352,7 @@ async function executeAttempts(options) {
|
|
|
4307
4352
|
$ongoingTaskResult.$failedResults = [];
|
|
4308
4353
|
}
|
|
4309
4354
|
$ongoingTaskResult.$failedResults.push({
|
|
4355
|
+
attemptIndex,
|
|
4310
4356
|
result: $ongoingTaskResult.$resultString,
|
|
4311
4357
|
error: error,
|
|
4312
4358
|
});
|
|
@@ -4331,19 +4377,13 @@ async function executeAttempts(options) {
|
|
|
4331
4377
|
});
|
|
4332
4378
|
}
|
|
4333
4379
|
}
|
|
4334
|
-
if ($ongoingTaskResult.$expectError !== null &&
|
|
4335
|
-
//
|
|
4336
|
-
$ongoingTaskResult.$failedResults = $ongoingTaskResult.$failedResults || [];
|
|
4337
|
-
$ongoingTaskResult.$failedResults.push({
|
|
4338
|
-
result: $ongoingTaskResult.$resultString,
|
|
4339
|
-
error: $ongoingTaskResult.$expectError,
|
|
4340
|
-
});
|
|
4341
|
-
// Create a summary of all failures
|
|
4380
|
+
if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
|
|
4381
|
+
// Note: Create a summary of all failures
|
|
4342
4382
|
const failuresSummary = $ongoingTaskResult.$failedResults
|
|
4343
|
-
.map((failure
|
|
4383
|
+
.map((failure) => spaceTrim$1((block) => {
|
|
4344
4384
|
var _a, _b;
|
|
4345
4385
|
return `
|
|
4346
|
-
Attempt ${
|
|
4386
|
+
Attempt ${failure.attemptIndex + 1}:
|
|
4347
4387
|
Error ${((_a = failure.error) === null || _a === void 0 ? void 0 : _a.name) || ''}:
|
|
4348
4388
|
${block((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message.split('\n').map((line) => `> ${line}`).join('\n'))}
|
|
4349
4389
|
|
|
@@ -10780,6 +10820,7 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
10780
10820
|
},
|
|
10781
10821
|
};
|
|
10782
10822
|
const callCommonModel = async (prompt) => {
|
|
10823
|
+
var _a;
|
|
10783
10824
|
const { parameters, content, modelRequirements } = prompt;
|
|
10784
10825
|
// <- Note: These are relevant things from the prompt that the cache key should depend on.
|
|
10785
10826
|
// TODO: Maybe some standalone function for normalization of content for cache
|
|
@@ -10835,11 +10876,42 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
10835
10876
|
// 1. It has a content property that is null or undefined
|
|
10836
10877
|
// 2. It has an error property that is truthy
|
|
10837
10878
|
// 3. It has a success property that is explicitly false
|
|
10838
|
-
|
|
10879
|
+
// 4. It doesn't meet the prompt's expectations or format requirements
|
|
10880
|
+
const isBasicFailedResult = promptResult.content === null ||
|
|
10839
10881
|
promptResult.content === undefined ||
|
|
10840
10882
|
promptResult.error ||
|
|
10841
10883
|
promptResult.success === false;
|
|
10842
|
-
|
|
10884
|
+
let shouldCache = !isBasicFailedResult;
|
|
10885
|
+
// If the basic result is valid, check against expectations and format
|
|
10886
|
+
if (shouldCache && promptResult.content) {
|
|
10887
|
+
try {
|
|
10888
|
+
const validationResult = validatePromptResult({
|
|
10889
|
+
resultString: promptResult.content,
|
|
10890
|
+
expectations: prompt.expectations,
|
|
10891
|
+
format: prompt.format,
|
|
10892
|
+
});
|
|
10893
|
+
shouldCache = validationResult.isValid;
|
|
10894
|
+
if (!shouldCache && isVerbose) {
|
|
10895
|
+
console.info('Not caching result that fails expectations/format validation for key:', key, {
|
|
10896
|
+
content: promptResult.content,
|
|
10897
|
+
expectations: prompt.expectations,
|
|
10898
|
+
format: prompt.format,
|
|
10899
|
+
validationError: (_a = validationResult.error) === null || _a === void 0 ? void 0 : _a.message,
|
|
10900
|
+
});
|
|
10901
|
+
}
|
|
10902
|
+
}
|
|
10903
|
+
catch (error) {
|
|
10904
|
+
// If validation throws an unexpected error, don't cache
|
|
10905
|
+
shouldCache = false;
|
|
10906
|
+
if (isVerbose) {
|
|
10907
|
+
console.info('Not caching result due to validation error for key:', key, {
|
|
10908
|
+
content: promptResult.content,
|
|
10909
|
+
validationError: error instanceof Error ? error.message : String(error),
|
|
10910
|
+
});
|
|
10911
|
+
}
|
|
10912
|
+
}
|
|
10913
|
+
}
|
|
10914
|
+
if (shouldCache) {
|
|
10843
10915
|
await storage.setItem(key, {
|
|
10844
10916
|
date: $getCurrentDate(),
|
|
10845
10917
|
promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
|
|
@@ -10856,7 +10928,7 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
10856
10928
|
promptResult,
|
|
10857
10929
|
});
|
|
10858
10930
|
}
|
|
10859
|
-
else if (isVerbose) {
|
|
10931
|
+
else if (isVerbose && isBasicFailedResult) {
|
|
10860
10932
|
console.info('Not caching failed result for key:', key, {
|
|
10861
10933
|
content: promptResult.content,
|
|
10862
10934
|
error: promptResult.error,
|
|
@@ -11326,7 +11398,7 @@ const _OpenAiCompatibleMetadataRegistration = $llmToolsMetadataRegister.register
|
|
|
11326
11398
|
title: 'Open AI Compatible',
|
|
11327
11399
|
packageName: '@promptbook/openai',
|
|
11328
11400
|
className: 'OpenAiCompatibleExecutionTools',
|
|
11329
|
-
envVariables: ['OPENAI_API_KEY'],
|
|
11401
|
+
envVariables: ['OPENAI_API_KEY', 'OPENAI_BASE_URL'],
|
|
11330
11402
|
trustLevel: 'CLOSED',
|
|
11331
11403
|
order: MODEL_ORDERS.TOP_TIER,
|
|
11332
11404
|
getBoilerplateConfiguration() {
|
|
@@ -11336,11 +11408,35 @@ const _OpenAiCompatibleMetadataRegistration = $llmToolsMetadataRegister.register
|
|
|
11336
11408
|
className: 'OpenAiCompatibleExecutionTools',
|
|
11337
11409
|
options: {
|
|
11338
11410
|
apiKey: 'sk-',
|
|
11411
|
+
baseURL: 'https://api.openai.com/v1',
|
|
11412
|
+
isProxied: false,
|
|
11413
|
+
remoteServerUrl: DEFAULT_REMOTE_SERVER_URL,
|
|
11339
11414
|
maxRequestsPerMinute: DEFAULT_MAX_REQUESTS_PER_MINUTE,
|
|
11340
11415
|
},
|
|
11341
11416
|
};
|
|
11342
11417
|
},
|
|
11343
11418
|
createConfigurationFromEnv(env) {
|
|
11419
|
+
// Note: OpenAiCompatibleExecutionTools is an abstract class and cannot be instantiated directly
|
|
11420
|
+
// However, we can provide configuration for users who want to manually instantiate it
|
|
11421
|
+
if (typeof env.OPENAI_API_KEY === 'string') {
|
|
11422
|
+
const options = {
|
|
11423
|
+
apiKey: env.OPENAI_API_KEY,
|
|
11424
|
+
isProxied: false,
|
|
11425
|
+
remoteServerUrl: DEFAULT_REMOTE_SERVER_URL,
|
|
11426
|
+
maxRequestsPerMinute: DEFAULT_MAX_REQUESTS_PER_MINUTE,
|
|
11427
|
+
defaultModelName: 'gpt-4-turbo',
|
|
11428
|
+
};
|
|
11429
|
+
// Add baseURL if provided in environment
|
|
11430
|
+
if (typeof env.OPENAI_BASE_URL === 'string') {
|
|
11431
|
+
options.baseURL = env.OPENAI_BASE_URL;
|
|
11432
|
+
}
|
|
11433
|
+
return {
|
|
11434
|
+
title: 'Open AI Compatible (from env)',
|
|
11435
|
+
packageName: '@promptbook/openai',
|
|
11436
|
+
className: 'OpenAiCompatibleExecutionTools',
|
|
11437
|
+
options,
|
|
11438
|
+
};
|
|
11439
|
+
}
|
|
11344
11440
|
return null;
|
|
11345
11441
|
},
|
|
11346
11442
|
});
|