@promptbook/wizard 0.98.0-5 โ 0.98.0-9
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 +218 -52
- 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 +218 -52
- package/umd/index.umd.js.map +1 -1
package/umd/index.umd.js
CHANGED
@@ -49,7 +49,7 @@
|
|
49
49
|
* @generated
|
50
50
|
* @see https://github.com/webgptorg/promptbook
|
51
51
|
*/
|
52
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-
|
52
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-9';
|
53
53
|
/**
|
54
54
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
55
55
|
* Note: [๐] Ignore a discrepancy between file name and entity name
|
@@ -243,7 +243,7 @@
|
|
243
243
|
*
|
244
244
|
* @public exported from `@promptbook/core`
|
245
245
|
*/
|
246
|
-
const DEFAULT_MAX_EXECUTION_ATTEMPTS =
|
246
|
+
const DEFAULT_MAX_EXECUTION_ATTEMPTS = 7; // <- TODO: [๐คนโโ๏ธ]
|
247
247
|
// <- TODO: [๐]
|
248
248
|
/**
|
249
249
|
* Where to store your books
|
@@ -4356,7 +4356,7 @@
|
|
4356
4356
|
*/
|
4357
4357
|
|
4358
4358
|
/**
|
4359
|
-
* Execution Tools for calling OpenAI API or other
|
4359
|
+
* Execution Tools for calling OpenAI API or other OpenAI compatible provider
|
4360
4360
|
*
|
4361
4361
|
* @public exported from `@promptbook/openai`
|
4362
4362
|
*/
|
@@ -4926,6 +4926,7 @@
|
|
4926
4926
|
baseURL: DEFAULT_OLLAMA_BASE_URL,
|
4927
4927
|
...ollamaOptions,
|
4928
4928
|
apiKey: 'ollama',
|
4929
|
+
isProxied: false, // <- Note: Ollama is always local
|
4929
4930
|
};
|
4930
4931
|
super(openAiCompatibleOptions);
|
4931
4932
|
}
|
@@ -5112,7 +5113,7 @@
|
|
5112
5113
|
title: 'Open AI Compatible',
|
5113
5114
|
packageName: '@promptbook/openai',
|
5114
5115
|
className: 'OpenAiCompatibleExecutionTools',
|
5115
|
-
envVariables: ['OPENAI_API_KEY'],
|
5116
|
+
envVariables: ['OPENAI_API_KEY', 'OPENAI_BASE_URL'],
|
5116
5117
|
trustLevel: 'CLOSED',
|
5117
5118
|
order: MODEL_ORDERS.TOP_TIER,
|
5118
5119
|
getBoilerplateConfiguration() {
|
@@ -5122,6 +5123,9 @@
|
|
5122
5123
|
className: 'OpenAiCompatibleExecutionTools',
|
5123
5124
|
options: {
|
5124
5125
|
apiKey: 'sk-',
|
5126
|
+
baseURL: 'https://api.openai.com/v1',
|
5127
|
+
isProxied: false,
|
5128
|
+
remoteServerUrl: DEFAULT_REMOTE_SERVER_URL,
|
5125
5129
|
maxRequestsPerMinute: DEFAULT_MAX_REQUESTS_PER_MINUTE,
|
5126
5130
|
},
|
5127
5131
|
};
|
@@ -5179,7 +5183,7 @@
|
|
5179
5183
|
* Default model for chat variant.
|
5180
5184
|
*/
|
5181
5185
|
getDefaultChatModel() {
|
5182
|
-
return this.getDefaultModel('gpt-
|
5186
|
+
return this.getDefaultModel('gpt-4-turbo');
|
5183
5187
|
}
|
5184
5188
|
/**
|
5185
5189
|
* Default model for completion variant.
|
@@ -5209,6 +5213,9 @@
|
|
5209
5213
|
* @param options which are relevant are directly passed to the OpenAI client
|
5210
5214
|
*/
|
5211
5215
|
constructor(options) {
|
5216
|
+
if (options.isProxied) {
|
5217
|
+
throw new NotYetImplementedError(`Proxy mode is not yet implemented for OpenAI assistants`);
|
5218
|
+
}
|
5212
5219
|
super(options);
|
5213
5220
|
this.assistantId = options.assistantId;
|
5214
5221
|
// TODO: [๐ฑ] Make limiter same as in `OpenAiExecutionTools`
|
@@ -5390,14 +5397,97 @@
|
|
5390
5397
|
* @public exported from `@promptbook/openai`
|
5391
5398
|
*/
|
5392
5399
|
const createOpenAiCompatibleExecutionTools = Object.assign((options) => {
|
5400
|
+
if (options.isProxied) {
|
5401
|
+
return new RemoteLlmExecutionTools({
|
5402
|
+
...options,
|
5403
|
+
identification: {
|
5404
|
+
isAnonymous: true,
|
5405
|
+
llmToolsConfiguration: [
|
5406
|
+
{
|
5407
|
+
title: 'OpenAI Compatible (proxied)',
|
5408
|
+
packageName: '@promptbook/openai',
|
5409
|
+
className: 'OpenAiCompatibleExecutionTools',
|
5410
|
+
options: {
|
5411
|
+
...options,
|
5412
|
+
isProxied: false,
|
5413
|
+
},
|
5414
|
+
},
|
5415
|
+
],
|
5416
|
+
},
|
5417
|
+
});
|
5418
|
+
}
|
5393
5419
|
if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
|
5394
5420
|
options = { ...options, dangerouslyAllowBrowser: true };
|
5395
5421
|
}
|
5396
|
-
return new
|
5422
|
+
return new HardcodedOpenAiCompatibleExecutionTools(options.defaultModelName, options);
|
5397
5423
|
}, {
|
5398
5424
|
packageName: '@promptbook/openai',
|
5399
5425
|
className: 'OpenAiCompatibleExecutionTools',
|
5400
5426
|
});
|
5427
|
+
/**
|
5428
|
+
* Execution Tools for calling ONE SPECIFIC PRECONFIGURED OpenAI compatible provider
|
5429
|
+
*
|
5430
|
+
* @private for `createOpenAiCompatibleExecutionTools`
|
5431
|
+
*/
|
5432
|
+
class HardcodedOpenAiCompatibleExecutionTools extends OpenAiCompatibleExecutionTools {
|
5433
|
+
/**
|
5434
|
+
* Creates OpenAI compatible Execution Tools.
|
5435
|
+
*
|
5436
|
+
* @param options which are relevant are directly passed to the OpenAI compatible client
|
5437
|
+
*/
|
5438
|
+
constructor(defaultModelName, options) {
|
5439
|
+
super(options);
|
5440
|
+
this.defaultModelName = defaultModelName;
|
5441
|
+
this.options = options;
|
5442
|
+
}
|
5443
|
+
get title() {
|
5444
|
+
return `${this.defaultModelName} on ${this.options.baseURL}`;
|
5445
|
+
}
|
5446
|
+
get description() {
|
5447
|
+
return `OpenAI compatible connected to "${this.options.baseURL}" model "${this.defaultModelName}"`;
|
5448
|
+
}
|
5449
|
+
/**
|
5450
|
+
* List all available models (non dynamically)
|
5451
|
+
*
|
5452
|
+
* Note: Purpose of this is to provide more information about models than standard listing from API
|
5453
|
+
*/
|
5454
|
+
get HARDCODED_MODELS() {
|
5455
|
+
return [
|
5456
|
+
{
|
5457
|
+
modelName: this.defaultModelName,
|
5458
|
+
modelVariant: 'CHAT',
|
5459
|
+
modelDescription: '', // <- TODO: What is the best value here, maybe `this.description`?
|
5460
|
+
},
|
5461
|
+
];
|
5462
|
+
}
|
5463
|
+
/**
|
5464
|
+
* Computes the usage
|
5465
|
+
*/
|
5466
|
+
computeUsage(...args) {
|
5467
|
+
return {
|
5468
|
+
...computeOpenAiUsage(...args),
|
5469
|
+
price: UNCERTAIN_ZERO_VALUE, // <- TODO: Maybe in future pass this counting mechanism, but for now, we dont know
|
5470
|
+
};
|
5471
|
+
}
|
5472
|
+
/**
|
5473
|
+
* Default model for chat variant.
|
5474
|
+
*/
|
5475
|
+
getDefaultChatModel() {
|
5476
|
+
return this.getDefaultModel(this.defaultModelName);
|
5477
|
+
}
|
5478
|
+
/**
|
5479
|
+
* Default model for completion variant.
|
5480
|
+
*/
|
5481
|
+
getDefaultCompletionModel() {
|
5482
|
+
throw new PipelineExecutionError(`${this.title} does not support COMPLETION model variant`);
|
5483
|
+
}
|
5484
|
+
/**
|
5485
|
+
* Default model for completion variant.
|
5486
|
+
*/
|
5487
|
+
getDefaultEmbeddingModel() {
|
5488
|
+
throw new PipelineExecutionError(`${this.title} does not support EMBEDDING model variant`);
|
5489
|
+
}
|
5490
|
+
}
|
5401
5491
|
/**
|
5402
5492
|
* TODO: [๐ฆบ] Is there some way how to put `packageName` and `className` on top and function definition on bottom?
|
5403
5493
|
* TODO: [๐ถ] Naming "constructor" vs "creator" vs "factory"
|
@@ -5414,6 +5504,9 @@
|
|
5414
5504
|
if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
|
5415
5505
|
options = { ...options, dangerouslyAllowBrowser: true };
|
5416
5506
|
}
|
5507
|
+
if (options.isProxied) {
|
5508
|
+
throw new NotYetImplementedError(`Proxy mode is not yet implemented in createOpenAiExecutionTools`);
|
5509
|
+
}
|
5417
5510
|
return new OpenAiExecutionTools(options);
|
5418
5511
|
}, {
|
5419
5512
|
packageName: '@promptbook/openai',
|
@@ -6793,7 +6886,7 @@
|
|
6793
6886
|
throw new Error(spaceTrim__default["default"]((block) => `
|
6794
6887
|
${block(error.message)}
|
6795
6888
|
|
6796
|
-
The JSON text:
|
6889
|
+
The expected JSON text:
|
6797
6890
|
${block(value)}
|
6798
6891
|
`));
|
6799
6892
|
}
|
@@ -8702,6 +8795,68 @@
|
|
8702
8795
|
* Note: [๐] and [๐ค ] are interconnected together
|
8703
8796
|
*/
|
8704
8797
|
|
8798
|
+
/**
|
8799
|
+
* Validates a prompt result against expectations and format requirements.
|
8800
|
+
* This function provides a common abstraction for result validation that can be used
|
8801
|
+
* by both execution logic and caching logic to ensure consistency.
|
8802
|
+
*
|
8803
|
+
* @param options - The validation options including result string, expectations, and format
|
8804
|
+
* @returns Validation result with processed string and validity status
|
8805
|
+
* @private internal function of `createPipelineExecutor` and `cacheLlmTools`
|
8806
|
+
*/
|
8807
|
+
function validatePromptResult(options) {
|
8808
|
+
const { resultString, expectations, format } = options;
|
8809
|
+
let processedResultString = resultString;
|
8810
|
+
let validationError;
|
8811
|
+
try {
|
8812
|
+
// TODO: [๐] Unite object for expecting amount and format
|
8813
|
+
if (format) {
|
8814
|
+
if (format === 'JSON') {
|
8815
|
+
if (!isValidJsonString(processedResultString)) {
|
8816
|
+
// TODO: [๐ข] Do more universally via `FormatParser`
|
8817
|
+
try {
|
8818
|
+
processedResultString = extractJsonBlock(processedResultString);
|
8819
|
+
}
|
8820
|
+
catch (error) {
|
8821
|
+
keepUnused(error);
|
8822
|
+
throw new ExpectError(spaceTrim.spaceTrim((block) => `
|
8823
|
+
Expected valid JSON string
|
8824
|
+
|
8825
|
+
The expected JSON text:
|
8826
|
+
${block(processedResultString)}
|
8827
|
+
`));
|
8828
|
+
}
|
8829
|
+
}
|
8830
|
+
}
|
8831
|
+
else {
|
8832
|
+
throw new UnexpectedError(`Unknown format "${format}"`);
|
8833
|
+
}
|
8834
|
+
}
|
8835
|
+
// TODO: [๐] Unite object for expecting amount and format
|
8836
|
+
if (expectations) {
|
8837
|
+
checkExpectations(expectations, processedResultString);
|
8838
|
+
}
|
8839
|
+
return {
|
8840
|
+
isValid: true,
|
8841
|
+
processedResultString,
|
8842
|
+
};
|
8843
|
+
}
|
8844
|
+
catch (error) {
|
8845
|
+
if (error instanceof ExpectError) {
|
8846
|
+
validationError = error;
|
8847
|
+
}
|
8848
|
+
else {
|
8849
|
+
// Re-throw non-ExpectError errors (like UnexpectedError)
|
8850
|
+
throw error;
|
8851
|
+
}
|
8852
|
+
return {
|
8853
|
+
isValid: false,
|
8854
|
+
processedResultString,
|
8855
|
+
error: validationError,
|
8856
|
+
};
|
8857
|
+
}
|
8858
|
+
}
|
8859
|
+
|
8705
8860
|
/**
|
8706
8861
|
* Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
|
8707
8862
|
* (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
|
@@ -8724,13 +8879,13 @@
|
|
8724
8879
|
// TODO: [๐] Make arrayable LLMs -> single LLM DRY
|
8725
8880
|
const _llms = arrayableToArray(tools.llm);
|
8726
8881
|
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
8727
|
-
attempts: for (let
|
8728
|
-
const isJokerAttempt =
|
8729
|
-
const jokerParameterName = jokerParameterNames[jokerParameterNames.length +
|
8882
|
+
attempts: for (let attemptIndex = -jokerParameterNames.length; attemptIndex < maxAttempts; attemptIndex++) {
|
8883
|
+
const isJokerAttempt = attemptIndex < 0;
|
8884
|
+
const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
|
8730
8885
|
// TODO: [๐ง ][๐ญ] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
|
8731
8886
|
if (isJokerAttempt && !jokerParameterName) {
|
8732
8887
|
throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
|
8733
|
-
Joker not found in attempt ${
|
8888
|
+
Joker not found in attempt ${attemptIndex}
|
8734
8889
|
|
8735
8890
|
${block(pipelineIdentification)}
|
8736
8891
|
`));
|
@@ -8928,35 +9083,18 @@
|
|
8928
9083
|
}
|
8929
9084
|
}
|
8930
9085
|
// TODO: [๐] Unite object for expecting amount and format
|
8931
|
-
|
8932
|
-
|
8933
|
-
|
8934
|
-
|
8935
|
-
|
8936
|
-
|
8937
|
-
|
8938
|
-
|
8939
|
-
|
8940
|
-
throw new ExpectError(spaceTrim.spaceTrim((block) => `
|
8941
|
-
Expected valid JSON string
|
8942
|
-
|
8943
|
-
${block(
|
8944
|
-
/*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ '')}
|
8945
|
-
`));
|
8946
|
-
}
|
8947
|
-
}
|
8948
|
-
}
|
8949
|
-
else {
|
8950
|
-
throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
|
8951
|
-
Unknown format "${task.format}"
|
8952
|
-
|
8953
|
-
${block(pipelineIdentification)}
|
8954
|
-
`));
|
9086
|
+
// Use the common validation function for both format and expectations
|
9087
|
+
if (task.format || task.expectations) {
|
9088
|
+
const validationResult = validatePromptResult({
|
9089
|
+
resultString: $ongoingTaskResult.$resultString || '',
|
9090
|
+
expectations: task.expectations,
|
9091
|
+
format: task.format,
|
9092
|
+
});
|
9093
|
+
if (!validationResult.isValid) {
|
9094
|
+
throw validationResult.error;
|
8955
9095
|
}
|
8956
|
-
|
8957
|
-
|
8958
|
-
if (task.expectations) {
|
8959
|
-
checkExpectations(task.expectations, $ongoingTaskResult.$resultString || '');
|
9096
|
+
// Update the result string in case format processing modified it (e.g., JSON extraction)
|
9097
|
+
$ongoingTaskResult.$resultString = validationResult.processedResultString;
|
8960
9098
|
}
|
8961
9099
|
break attempts;
|
8962
9100
|
}
|
@@ -8970,6 +9108,7 @@
|
|
8970
9108
|
$ongoingTaskResult.$failedResults = [];
|
8971
9109
|
}
|
8972
9110
|
$ongoingTaskResult.$failedResults.push({
|
9111
|
+
attemptIndex,
|
8973
9112
|
result: $ongoingTaskResult.$resultString,
|
8974
9113
|
error: error,
|
8975
9114
|
});
|
@@ -8994,19 +9133,13 @@
|
|
8994
9133
|
});
|
8995
9134
|
}
|
8996
9135
|
}
|
8997
|
-
if ($ongoingTaskResult.$expectError !== null &&
|
8998
|
-
//
|
8999
|
-
$ongoingTaskResult.$failedResults = $ongoingTaskResult.$failedResults || [];
|
9000
|
-
$ongoingTaskResult.$failedResults.push({
|
9001
|
-
result: $ongoingTaskResult.$resultString,
|
9002
|
-
error: $ongoingTaskResult.$expectError,
|
9003
|
-
});
|
9004
|
-
// Create a summary of all failures
|
9136
|
+
if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
|
9137
|
+
// Note: Create a summary of all failures
|
9005
9138
|
const failuresSummary = $ongoingTaskResult.$failedResults
|
9006
|
-
.map((failure
|
9139
|
+
.map((failure) => spaceTrim.spaceTrim((block) => {
|
9007
9140
|
var _a, _b;
|
9008
9141
|
return `
|
9009
|
-
Attempt ${
|
9142
|
+
Attempt ${failure.attemptIndex + 1}:
|
9010
9143
|
Error ${((_a = failure.error) === null || _a === void 0 ? void 0 : _a.name) || ''}:
|
9011
9144
|
${block((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message.split('\n').map((line) => `> ${line}`).join('\n'))}
|
9012
9145
|
|
@@ -11813,6 +11946,7 @@
|
|
11813
11946
|
},
|
11814
11947
|
};
|
11815
11948
|
const callCommonModel = async (prompt) => {
|
11949
|
+
var _a;
|
11816
11950
|
const { parameters, content, modelRequirements } = prompt;
|
11817
11951
|
// <- Note: These are relevant things from the prompt that the cache key should depend on.
|
11818
11952
|
// TODO: Maybe some standalone function for normalization of content for cache
|
@@ -11868,11 +12002,42 @@
|
|
11868
12002
|
// 1. It has a content property that is null or undefined
|
11869
12003
|
// 2. It has an error property that is truthy
|
11870
12004
|
// 3. It has a success property that is explicitly false
|
11871
|
-
|
12005
|
+
// 4. It doesn't meet the prompt's expectations or format requirements
|
12006
|
+
const isBasicFailedResult = promptResult.content === null ||
|
11872
12007
|
promptResult.content === undefined ||
|
11873
12008
|
promptResult.error ||
|
11874
12009
|
promptResult.success === false;
|
11875
|
-
|
12010
|
+
let shouldCache = !isBasicFailedResult;
|
12011
|
+
// If the basic result is valid, check against expectations and format
|
12012
|
+
if (shouldCache && promptResult.content) {
|
12013
|
+
try {
|
12014
|
+
const validationResult = validatePromptResult({
|
12015
|
+
resultString: promptResult.content,
|
12016
|
+
expectations: prompt.expectations,
|
12017
|
+
format: prompt.format,
|
12018
|
+
});
|
12019
|
+
shouldCache = validationResult.isValid;
|
12020
|
+
if (!shouldCache && isVerbose) {
|
12021
|
+
console.info('Not caching result that fails expectations/format validation for key:', key, {
|
12022
|
+
content: promptResult.content,
|
12023
|
+
expectations: prompt.expectations,
|
12024
|
+
format: prompt.format,
|
12025
|
+
validationError: (_a = validationResult.error) === null || _a === void 0 ? void 0 : _a.message,
|
12026
|
+
});
|
12027
|
+
}
|
12028
|
+
}
|
12029
|
+
catch (error) {
|
12030
|
+
// If validation throws an unexpected error, don't cache
|
12031
|
+
shouldCache = false;
|
12032
|
+
if (isVerbose) {
|
12033
|
+
console.info('Not caching result due to validation error for key:', key, {
|
12034
|
+
content: promptResult.content,
|
12035
|
+
validationError: error instanceof Error ? error.message : String(error),
|
12036
|
+
});
|
12037
|
+
}
|
12038
|
+
}
|
12039
|
+
}
|
12040
|
+
if (shouldCache) {
|
11876
12041
|
await storage.setItem(key, {
|
11877
12042
|
date: $getCurrentDate(),
|
11878
12043
|
promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
|
@@ -11889,7 +12054,7 @@
|
|
11889
12054
|
promptResult,
|
11890
12055
|
});
|
11891
12056
|
}
|
11892
|
-
else if (isVerbose) {
|
12057
|
+
else if (isVerbose && isBasicFailedResult) {
|
11893
12058
|
console.info('Not caching failed result for key:', key, {
|
11894
12059
|
content: promptResult.content,
|
11895
12060
|
error: promptResult.error,
|
@@ -11976,6 +12141,7 @@
|
|
11976
12141
|
.list()
|
11977
12142
|
.find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
|
11978
12143
|
if (registeredItem === undefined) {
|
12144
|
+
console.log('!!! $llmToolsRegister.list()', $llmToolsRegister.list());
|
11979
12145
|
throw new Error(spaceTrim__default["default"]((block) => `
|
11980
12146
|
There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
|
11981
12147
|
|