@promptbook/wizard 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.
Files changed (25) hide show
  1. package/README.md +12 -0
  2. package/esm/index.es.js +345 -70
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/src/_packages/anthropic-claude.index.d.ts +2 -2
  5. package/esm/typings/src/_packages/cli.index.d.ts +4 -0
  6. package/esm/typings/src/_packages/core.index.d.ts +2 -0
  7. package/esm/typings/src/_packages/openai.index.d.ts +10 -0
  8. package/esm/typings/src/_packages/types.index.d.ts +12 -2
  9. package/esm/typings/src/_packages/wizard.index.d.ts +4 -0
  10. package/esm/typings/src/config.d.ts +1 -1
  11. package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +8 -0
  12. package/esm/typings/src/execution/utils/validatePromptResult.d.ts +53 -0
  13. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +3 -3
  14. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +2 -2
  15. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionToolsOptions.d.ts +2 -2
  16. package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +4 -4
  17. package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionToolsOptions.d.ts +52 -0
  18. package/esm/typings/src/llm-providers/openai/OpenAiExecutionToolsOptions.d.ts +3 -5
  19. package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +74 -0
  20. package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +11 -0
  21. package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +14 -0
  22. package/esm/typings/src/version.d.ts +1 -1
  23. package/package.json +2 -2
  24. package/umd/index.umd.js +346 -69
  25. 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.95.0';
52
+ const PROMPTBOOK_ENGINE_VERSION = '0.98.0-10';
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 = 10; // <- TODO: [๐Ÿคนโ€โ™‚๏ธ]
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 OpeenAI compatible provider
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
  }
@@ -5098,6 +5099,42 @@
5098
5099
  */
5099
5100
  },
5100
5101
  });
5102
+ /**
5103
+ * Registration of the OpenAI Compatible metadata
5104
+ *
5105
+ * Note: OpenAiCompatibleExecutionTools is an abstract class and cannot be instantiated directly.
5106
+ * It serves as a base class for OpenAiExecutionTools and other compatible implementations.
5107
+ *
5108
+ * @public exported from `@promptbook/core`
5109
+ * @public exported from `@promptbook/wizard`
5110
+ * @public exported from `@promptbook/cli`
5111
+ */
5112
+ const _OpenAiCompatibleMetadataRegistration = $llmToolsMetadataRegister.register({
5113
+ title: 'Open AI Compatible',
5114
+ packageName: '@promptbook/openai',
5115
+ className: 'OpenAiCompatibleExecutionTools',
5116
+ envVariables: ['OPENAI_API_KEY', 'OPENAI_BASE_URL'],
5117
+ trustLevel: 'CLOSED',
5118
+ order: MODEL_ORDERS.TOP_TIER,
5119
+ getBoilerplateConfiguration() {
5120
+ return {
5121
+ title: 'Open AI Compatible',
5122
+ packageName: '@promptbook/openai',
5123
+ className: 'OpenAiCompatibleExecutionTools',
5124
+ options: {
5125
+ apiKey: 'sk-',
5126
+ baseURL: 'https://api.openai.com/v1',
5127
+ defaultModelName: 'gpt-4-turbo',
5128
+ isProxied: false,
5129
+ remoteServerUrl: DEFAULT_REMOTE_SERVER_URL,
5130
+ maxRequestsPerMinute: DEFAULT_MAX_REQUESTS_PER_MINUTE,
5131
+ },
5132
+ };
5133
+ },
5134
+ createConfigurationFromEnv(env) {
5135
+ return null;
5136
+ },
5137
+ });
5101
5138
  /**
5102
5139
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
5103
5140
  */
@@ -5147,7 +5184,7 @@
5147
5184
  * Default model for chat variant.
5148
5185
  */
5149
5186
  getDefaultChatModel() {
5150
- return this.getDefaultModel('gpt-4o');
5187
+ return this.getDefaultModel('gpt-4-turbo');
5151
5188
  }
5152
5189
  /**
5153
5190
  * Default model for completion variant.
@@ -5177,6 +5214,9 @@
5177
5214
  * @param options which are relevant are directly passed to the OpenAI client
5178
5215
  */
5179
5216
  constructor(options) {
5217
+ if (options.isProxied) {
5218
+ throw new NotYetImplementedError(`Proxy mode is not yet implemented for OpenAI assistants`);
5219
+ }
5180
5220
  super(options);
5181
5221
  this.assistantId = options.assistantId;
5182
5222
  // TODO: [๐Ÿ‘ฑ] Make limiter same as in `OpenAiExecutionTools`
@@ -5350,6 +5390,110 @@
5350
5390
  * TODO: [๐ŸŽถ] Naming "constructor" vs "creator" vs "factory"
5351
5391
  */
5352
5392
 
5393
+ /**
5394
+ * Execution Tools for calling OpenAI compatible API
5395
+ *
5396
+ * Note: This can be used for any OpenAI compatible APIs
5397
+ *
5398
+ * @public exported from `@promptbook/openai`
5399
+ */
5400
+ const createOpenAiCompatibleExecutionTools = Object.assign((options) => {
5401
+ if (options.isProxied) {
5402
+ return new RemoteLlmExecutionTools({
5403
+ ...options,
5404
+ identification: {
5405
+ isAnonymous: true,
5406
+ llmToolsConfiguration: [
5407
+ {
5408
+ title: 'OpenAI Compatible (proxied)',
5409
+ packageName: '@promptbook/openai',
5410
+ className: 'OpenAiCompatibleExecutionTools',
5411
+ options: {
5412
+ ...options,
5413
+ isProxied: false,
5414
+ },
5415
+ },
5416
+ ],
5417
+ },
5418
+ });
5419
+ }
5420
+ if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
5421
+ options = { ...options, dangerouslyAllowBrowser: true };
5422
+ }
5423
+ return new HardcodedOpenAiCompatibleExecutionTools(options.defaultModelName, options);
5424
+ }, {
5425
+ packageName: '@promptbook/openai',
5426
+ className: 'OpenAiCompatibleExecutionTools',
5427
+ });
5428
+ /**
5429
+ * Execution Tools for calling ONE SPECIFIC PRECONFIGURED OpenAI compatible provider
5430
+ *
5431
+ * @private for `createOpenAiCompatibleExecutionTools`
5432
+ */
5433
+ class HardcodedOpenAiCompatibleExecutionTools extends OpenAiCompatibleExecutionTools {
5434
+ /**
5435
+ * Creates OpenAI compatible Execution Tools.
5436
+ *
5437
+ * @param options which are relevant are directly passed to the OpenAI compatible client
5438
+ */
5439
+ constructor(defaultModelName, options) {
5440
+ super(options);
5441
+ this.defaultModelName = defaultModelName;
5442
+ this.options = options;
5443
+ }
5444
+ get title() {
5445
+ return `${this.defaultModelName} on ${this.options.baseURL}`;
5446
+ }
5447
+ get description() {
5448
+ return `OpenAI compatible connected to "${this.options.baseURL}" model "${this.defaultModelName}"`;
5449
+ }
5450
+ /**
5451
+ * List all available models (non dynamically)
5452
+ *
5453
+ * Note: Purpose of this is to provide more information about models than standard listing from API
5454
+ */
5455
+ get HARDCODED_MODELS() {
5456
+ return [
5457
+ {
5458
+ modelName: this.defaultModelName,
5459
+ modelVariant: 'CHAT',
5460
+ modelDescription: '', // <- TODO: What is the best value here, maybe `this.description`?
5461
+ },
5462
+ ];
5463
+ }
5464
+ /**
5465
+ * Computes the usage
5466
+ */
5467
+ computeUsage(...args) {
5468
+ return {
5469
+ ...computeOpenAiUsage(...args),
5470
+ price: UNCERTAIN_ZERO_VALUE, // <- TODO: Maybe in future pass this counting mechanism, but for now, we dont know
5471
+ };
5472
+ }
5473
+ /**
5474
+ * Default model for chat variant.
5475
+ */
5476
+ getDefaultChatModel() {
5477
+ return this.getDefaultModel(this.defaultModelName);
5478
+ }
5479
+ /**
5480
+ * Default model for completion variant.
5481
+ */
5482
+ getDefaultCompletionModel() {
5483
+ throw new PipelineExecutionError(`${this.title} does not support COMPLETION model variant`);
5484
+ }
5485
+ /**
5486
+ * Default model for completion variant.
5487
+ */
5488
+ getDefaultEmbeddingModel() {
5489
+ throw new PipelineExecutionError(`${this.title} does not support EMBEDDING model variant`);
5490
+ }
5491
+ }
5492
+ /**
5493
+ * TODO: [๐Ÿฆบ] Is there some way how to put `packageName` and `className` on top and function definition on bottom?
5494
+ * TODO: [๐ŸŽถ] Naming "constructor" vs "creator" vs "factory"
5495
+ */
5496
+
5353
5497
  /**
5354
5498
  * Execution Tools for calling OpenAI API
5355
5499
  *
@@ -5361,6 +5505,9 @@
5361
5505
  if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
5362
5506
  options = { ...options, dangerouslyAllowBrowser: true };
5363
5507
  }
5508
+ if (options.isProxied) {
5509
+ throw new NotYetImplementedError(`Proxy mode is not yet implemented in createOpenAiExecutionTools`);
5510
+ }
5364
5511
  return new OpenAiExecutionTools(options);
5365
5512
  }, {
5366
5513
  packageName: '@promptbook/openai',
@@ -5371,6 +5518,7 @@
5371
5518
  * TODO: [๐ŸŽถ] Naming "constructor" vs "creator" vs "factory"
5372
5519
  */
5373
5520
 
5521
+ // Note: OpenAiCompatibleExecutionTools is an abstract class and cannot be instantiated directly
5374
5522
  /**
5375
5523
  * Registration of LLM provider
5376
5524
  *
@@ -5391,6 +5539,20 @@
5391
5539
  * @public exported from `@promptbook/cli`
5392
5540
  */
5393
5541
  const _OpenAiAssistantRegistration = $llmToolsRegister.register(createOpenAiAssistantExecutionTools);
5542
+ /**
5543
+ * Registration of the OpenAI Compatible provider
5544
+ *
5545
+ * Note: [๐Ÿ] Configurations registrations are done in register-constructor.ts BUT constructor register-constructor.ts
5546
+ *
5547
+ * @public exported from `@promptbook/openai`
5548
+ * @public exported from `@promptbook/wizard`
5549
+ * @public exported from `@promptbook/cli`
5550
+ */
5551
+ const _OpenAiCompatibleRegistration = $llmToolsRegister.register(createOpenAiCompatibleExecutionTools);
5552
+ /**
5553
+ * Note: OpenAiCompatibleExecutionTools is an abstract class and cannot be registered directly.
5554
+ * It serves as a base class for OpenAiExecutionTools and other compatible implementations.
5555
+ */
5394
5556
  /**
5395
5557
  * TODO: [๐ŸŽถ] Naming "constructor" vs "creator" vs "factory"
5396
5558
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
@@ -6725,7 +6887,7 @@
6725
6887
  throw new Error(spaceTrim__default["default"]((block) => `
6726
6888
  ${block(error.message)}
6727
6889
 
6728
- The JSON text:
6890
+ The expected JSON text:
6729
6891
  ${block(value)}
6730
6892
  `));
6731
6893
  }
@@ -8634,6 +8796,68 @@
8634
8796
  * Note: [๐Ÿ’] and [๐Ÿค ] are interconnected together
8635
8797
  */
8636
8798
 
8799
+ /**
8800
+ * Validates a prompt result against expectations and format requirements.
8801
+ * This function provides a common abstraction for result validation that can be used
8802
+ * by both execution logic and caching logic to ensure consistency.
8803
+ *
8804
+ * @param options - The validation options including result string, expectations, and format
8805
+ * @returns Validation result with processed string and validity status
8806
+ * @private internal function of `createPipelineExecutor` and `cacheLlmTools`
8807
+ */
8808
+ function validatePromptResult(options) {
8809
+ const { resultString, expectations, format } = options;
8810
+ let processedResultString = resultString;
8811
+ let validationError;
8812
+ try {
8813
+ // TODO: [๐Ÿ’] Unite object for expecting amount and format
8814
+ if (format) {
8815
+ if (format === 'JSON') {
8816
+ if (!isValidJsonString(processedResultString)) {
8817
+ // TODO: [๐Ÿข] Do more universally via `FormatParser`
8818
+ try {
8819
+ processedResultString = extractJsonBlock(processedResultString);
8820
+ }
8821
+ catch (error) {
8822
+ keepUnused(error);
8823
+ throw new ExpectError(spaceTrim.spaceTrim((block) => `
8824
+ Expected valid JSON string
8825
+
8826
+ The expected JSON text:
8827
+ ${block(processedResultString)}
8828
+ `));
8829
+ }
8830
+ }
8831
+ }
8832
+ else {
8833
+ throw new UnexpectedError(`Unknown format "${format}"`);
8834
+ }
8835
+ }
8836
+ // TODO: [๐Ÿ’] Unite object for expecting amount and format
8837
+ if (expectations) {
8838
+ checkExpectations(expectations, processedResultString);
8839
+ }
8840
+ return {
8841
+ isValid: true,
8842
+ processedResultString,
8843
+ };
8844
+ }
8845
+ catch (error) {
8846
+ if (error instanceof ExpectError) {
8847
+ validationError = error;
8848
+ }
8849
+ else {
8850
+ // Re-throw non-ExpectError errors (like UnexpectedError)
8851
+ throw error;
8852
+ }
8853
+ return {
8854
+ isValid: false,
8855
+ processedResultString,
8856
+ error: validationError,
8857
+ };
8858
+ }
8859
+ }
8860
+
8637
8861
  /**
8638
8862
  * Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
8639
8863
  * (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
@@ -8651,17 +8875,18 @@
8651
8875
  $resultString: null,
8652
8876
  $expectError: null,
8653
8877
  $scriptPipelineExecutionErrors: [],
8878
+ $failedResults: [], // Track all failed attempts
8654
8879
  };
8655
8880
  // TODO: [๐Ÿš] Make arrayable LLMs -> single LLM DRY
8656
8881
  const _llms = arrayableToArray(tools.llm);
8657
8882
  const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
8658
- attempts: for (let attempt = -jokerParameterNames.length; attempt < maxAttempts; attempt++) {
8659
- const isJokerAttempt = attempt < 0;
8660
- const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
8883
+ attempts: for (let attemptIndex = -jokerParameterNames.length; attemptIndex < maxAttempts; attemptIndex++) {
8884
+ const isJokerAttempt = attemptIndex < 0;
8885
+ const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
8661
8886
  // TODO: [๐Ÿง ][๐Ÿญ] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
8662
8887
  if (isJokerAttempt && !jokerParameterName) {
8663
8888
  throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
8664
- Joker not found in attempt ${attempt}
8889
+ Joker not found in attempt ${attemptIndex}
8665
8890
 
8666
8891
  ${block(pipelineIdentification)}
8667
8892
  `));
@@ -8859,35 +9084,18 @@
8859
9084
  }
8860
9085
  }
8861
9086
  // TODO: [๐Ÿ’] Unite object for expecting amount and format
8862
- if (task.format) {
8863
- if (task.format === 'JSON') {
8864
- if (!isValidJsonString($ongoingTaskResult.$resultString || '')) {
8865
- // TODO: [๐Ÿข] Do more universally via `FormatParser`
8866
- try {
8867
- $ongoingTaskResult.$resultString = extractJsonBlock($ongoingTaskResult.$resultString || '');
8868
- }
8869
- catch (error) {
8870
- keepUnused(error);
8871
- throw new ExpectError(spaceTrim.spaceTrim((block) => `
8872
- Expected valid JSON string
8873
-
8874
- ${block(
8875
- /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ '')}
8876
- `));
8877
- }
8878
- }
8879
- }
8880
- else {
8881
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
8882
- Unknown format "${task.format}"
8883
-
8884
- ${block(pipelineIdentification)}
8885
- `));
9087
+ // Use the common validation function for both format and expectations
9088
+ if (task.format || task.expectations) {
9089
+ const validationResult = validatePromptResult({
9090
+ resultString: $ongoingTaskResult.$resultString || '',
9091
+ expectations: task.expectations,
9092
+ format: task.format,
9093
+ });
9094
+ if (!validationResult.isValid) {
9095
+ throw validationResult.error;
8886
9096
  }
8887
- }
8888
- // TODO: [๐Ÿ’] Unite object for expecting amount and format
8889
- if (task.expectations) {
8890
- checkExpectations(task.expectations, $ongoingTaskResult.$resultString || '');
9097
+ // Update the result string in case format processing modified it (e.g., JSON extraction)
9098
+ $ongoingTaskResult.$resultString = validationResult.processedResultString;
8891
9099
  }
8892
9100
  break attempts;
8893
9101
  }
@@ -8896,6 +9104,15 @@
8896
9104
  throw error;
8897
9105
  }
8898
9106
  $ongoingTaskResult.$expectError = error;
9107
+ // Store each failed attempt
9108
+ if (!Array.isArray($ongoingTaskResult.$failedResults)) {
9109
+ $ongoingTaskResult.$failedResults = [];
9110
+ }
9111
+ $ongoingTaskResult.$failedResults.push({
9112
+ attemptIndex,
9113
+ result: $ongoingTaskResult.$resultString,
9114
+ error: error,
9115
+ });
8899
9116
  }
8900
9117
  finally {
8901
9118
  if (!isJokerAttempt &&
@@ -8917,35 +9134,41 @@
8917
9134
  });
8918
9135
  }
8919
9136
  }
8920
- if ($ongoingTaskResult.$expectError !== null && attempt === maxAttempts - 1) {
9137
+ if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
9138
+ // Note: Create a summary of all failures
9139
+ const failuresSummary = $ongoingTaskResult.$failedResults
9140
+ .map((failure) => spaceTrim.spaceTrim((block) => {
9141
+ var _a, _b;
9142
+ return `
9143
+ Attempt ${failure.attemptIndex + 1}:
9144
+ Error ${((_a = failure.error) === null || _a === void 0 ? void 0 : _a.name) || ''}:
9145
+ ${block((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message.split('\n').map((line) => `> ${line}`).join('\n'))}
9146
+
9147
+ Result:
9148
+ ${block(failure.result === null
9149
+ ? 'null'
9150
+ : spaceTrim.spaceTrim(failure.result)
9151
+ .split('\n')
9152
+ .map((line) => `> ${line}`)
9153
+ .join('\n'))}
9154
+ `;
9155
+ }))
9156
+ .join('\n\n---\n\n');
8921
9157
  throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => {
8922
- var _a, _b, _c;
9158
+ var _a;
8923
9159
  return `
8924
9160
  LLM execution failed ${maxExecutionAttempts}x
8925
9161
 
8926
9162
  ${block(pipelineIdentification)}
8927
9163
 
8928
- ---
8929
9164
  The Prompt:
8930
9165
  ${block((((_a = $ongoingTaskResult.$prompt) === null || _a === void 0 ? void 0 : _a.content) || '')
8931
9166
  .split('\n')
8932
9167
  .map((line) => `> ${line}`)
8933
9168
  .join('\n'))}
8934
9169
 
8935
- Last error ${((_b = $ongoingTaskResult.$expectError) === null || _b === void 0 ? void 0 : _b.name) || ''}:
8936
- ${block((((_c = $ongoingTaskResult.$expectError) === null || _c === void 0 ? void 0 : _c.message) || '')
8937
- .split('\n')
8938
- .map((line) => `> ${line}`)
8939
- .join('\n'))}
8940
-
8941
- Last result:
8942
- ${block($ongoingTaskResult.$resultString === null
8943
- ? 'null'
8944
- : spaceTrim.spaceTrim($ongoingTaskResult.$resultString)
8945
- .split('\n')
8946
- .map((line) => `> ${line}`)
8947
- .join('\n'))}
8948
- ---
9170
+ All Failed Attempts:
9171
+ ${block(failuresSummary)}
8949
9172
  `;
8950
9173
  }));
8951
9174
  }
@@ -11724,6 +11947,7 @@
11724
11947
  },
11725
11948
  };
11726
11949
  const callCommonModel = async (prompt) => {
11950
+ var _a;
11727
11951
  const { parameters, content, modelRequirements } = prompt;
11728
11952
  // <- Note: These are relevant things from the prompt that the cache key should depend on.
11729
11953
  // TODO: Maybe some standalone function for normalization of content for cache
@@ -11774,21 +11998,70 @@
11774
11998
  }
11775
11999
  // TODO: [๐Ÿง ] !!5 How to do timing in mixed cache / non-cache situation
11776
12000
  // promptResult.timing: FromtoItems
11777
- await storage.setItem(key, {
11778
- date: $getCurrentDate(),
11779
- promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
11780
- bookVersion: BOOK_LANGUAGE_VERSION,
11781
- prompt: {
11782
- ...prompt,
11783
- parameters: Object.entries(parameters).length === Object.entries(relevantParameters).length
11784
- ? parameters
11785
- : {
11786
- ...relevantParameters,
11787
- note: `<- Note: Only relevant parameters are stored in the cache`,
11788
- },
11789
- },
11790
- promptResult,
11791
- });
12001
+ // Check if the result is valid and should be cached
12002
+ // A result is considered failed if:
12003
+ // 1. It has a content property that is null or undefined
12004
+ // 2. It has an error property that is truthy
12005
+ // 3. It has a success property that is explicitly false
12006
+ // 4. It doesn't meet the prompt's expectations or format requirements
12007
+ const isBasicFailedResult = promptResult.content === null ||
12008
+ promptResult.content === undefined ||
12009
+ promptResult.error ||
12010
+ promptResult.success === false;
12011
+ let shouldCache = !isBasicFailedResult;
12012
+ // If the basic result is valid, check against expectations and format
12013
+ if (shouldCache && promptResult.content) {
12014
+ try {
12015
+ const validationResult = validatePromptResult({
12016
+ resultString: promptResult.content,
12017
+ expectations: prompt.expectations,
12018
+ format: prompt.format,
12019
+ });
12020
+ shouldCache = validationResult.isValid;
12021
+ if (!shouldCache && isVerbose) {
12022
+ console.info('Not caching result that fails expectations/format validation for key:', key, {
12023
+ content: promptResult.content,
12024
+ expectations: prompt.expectations,
12025
+ format: prompt.format,
12026
+ validationError: (_a = validationResult.error) === null || _a === void 0 ? void 0 : _a.message,
12027
+ });
12028
+ }
12029
+ }
12030
+ catch (error) {
12031
+ // If validation throws an unexpected error, don't cache
12032
+ shouldCache = false;
12033
+ if (isVerbose) {
12034
+ console.info('Not caching result due to validation error for key:', key, {
12035
+ content: promptResult.content,
12036
+ validationError: error instanceof Error ? error.message : String(error),
12037
+ });
12038
+ }
12039
+ }
12040
+ }
12041
+ if (shouldCache) {
12042
+ await storage.setItem(key, {
12043
+ date: $getCurrentDate(),
12044
+ promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
12045
+ bookVersion: BOOK_LANGUAGE_VERSION,
12046
+ prompt: {
12047
+ ...prompt,
12048
+ parameters: Object.entries(parameters).length === Object.entries(relevantParameters).length
12049
+ ? parameters
12050
+ : {
12051
+ ...relevantParameters,
12052
+ note: `<- Note: Only relevant parameters are stored in the cache`,
12053
+ },
12054
+ },
12055
+ promptResult,
12056
+ });
12057
+ }
12058
+ else if (isVerbose && isBasicFailedResult) {
12059
+ console.info('Not caching failed result for key:', key, {
12060
+ content: promptResult.content,
12061
+ error: promptResult.error,
12062
+ success: promptResult.success,
12063
+ });
12064
+ }
11792
12065
  return promptResult;
11793
12066
  };
11794
12067
  if (llmTools.callChatModel !== undefined) {
@@ -11869,8 +12142,10 @@
11869
12142
  .list()
11870
12143
  .find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
11871
12144
  if (registeredItem === undefined) {
12145
+ console.log('!!! $llmToolsRegister.list()', $llmToolsRegister.list());
11872
12146
  throw new Error(spaceTrim__default["default"]((block) => `
11873
12147
  There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
12148
+ Running in ${!$isRunningInBrowser() ? '' : 'browser environment'}${!$isRunningInNode() ? '' : 'node environment'}${!$isRunningInWebWorker() ? '' : 'worker environment'}
11874
12149
 
11875
12150
  You have probably forgotten install and import the provider package.
11876
12151
  To fix this issue, you can:
@@ -16680,6 +16955,8 @@
16680
16955
  exports._OllamaRegistration = _OllamaRegistration;
16681
16956
  exports._OpenAiAssistantMetadataRegistration = _OpenAiAssistantMetadataRegistration;
16682
16957
  exports._OpenAiAssistantRegistration = _OpenAiAssistantRegistration;
16958
+ exports._OpenAiCompatibleMetadataRegistration = _OpenAiCompatibleMetadataRegistration;
16959
+ exports._OpenAiCompatibleRegistration = _OpenAiCompatibleRegistration;
16683
16960
  exports._OpenAiMetadataRegistration = _OpenAiMetadataRegistration;
16684
16961
  exports._OpenAiRegistration = _OpenAiRegistration;
16685
16962
  exports._PdfScraperMetadataRegistration = _PdfScraperMetadataRegistration;