@promptbook/core 0.67.1 β†’ 0.67.3

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/umd/index.umd.js CHANGED
@@ -16,7 +16,7 @@
16
16
  /**
17
17
  * The version of the Promptbook library
18
18
  */
19
- var PROMPTBOOK_VERSION = '0.67.0';
19
+ var PROMPTBOOK_VERSION = '0.67.2';
20
20
  // TODO: !!!! List here all the versions and annotate + put into script
21
21
 
22
22
  /*! *****************************************************************************
@@ -1786,7 +1786,7 @@
1786
1786
  });
1787
1787
  }
1788
1788
 
1789
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.67.0",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",dependentParameterNames:["knowledgeContent"],resultingParameterName:"knowledgePieces"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.67.0",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"keywords"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.67.0",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"title"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.67.0",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",modelRequirements:{modelVariant:"CHAT"},content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n### Option `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Option `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Option `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",expectFormat:"JSON",dependentParameterNames:["availableModelNames","personaDescription"],resultingParameterName:"modelRequirements"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
1789
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.67.2",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT"},content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",dependentParameterNames:["knowledgeContent"],resultingParameterName:"knowledgePieces"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.67.2",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT"},content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"keywords"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.67.2",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT"},content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"title"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.67.2",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",modelRequirements:{modelVariant:"CHAT"},content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",expectFormat:"JSON",dependentParameterNames:["availableModelNames","personaDescription"],resultingParameterName:"modelRequirements"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
1790
1790
 
1791
1791
  var defaultDiacriticsRemovalMap = [
1792
1792
  {
@@ -2199,6 +2199,25 @@
2199
2199
  return EnvironmentMismatchError;
2200
2200
  }(Error));
2201
2201
 
2202
+ /**
2203
+ * This error occurs when some expectation is not met in the execution of the pipeline
2204
+ *
2205
+ * @public exported from `@promptbook/core`
2206
+ * Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server
2207
+ * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
2208
+ * Note: This is a kindof subtype of PipelineExecutionError
2209
+ */
2210
+ var ExpectError = /** @class */ (function (_super) {
2211
+ __extends(ExpectError, _super);
2212
+ function ExpectError(message) {
2213
+ var _this = _super.call(this, message) || this;
2214
+ _this.name = 'ExpectError';
2215
+ Object.setPrototypeOf(_this, ExpectError.prototype);
2216
+ return _this;
2217
+ }
2218
+ return ExpectError;
2219
+ }(Error));
2220
+
2202
2221
  /**
2203
2222
  * This error type indicates that some limit was reached
2204
2223
  *
@@ -2237,6 +2256,7 @@
2237
2256
  * @public exported from `@promptbook/core`
2238
2257
  */
2239
2258
  var ERRORS = {
2259
+ ExpectError: ExpectError,
2240
2260
  CollectionError: CollectionError,
2241
2261
  EnvironmentMismatchError: EnvironmentMismatchError,
2242
2262
  LimitReachedError: LimitReachedError,
@@ -2404,24 +2424,6 @@
2404
2424
  * TODO: [πŸ”£] If script require contentLanguage
2405
2425
  */
2406
2426
 
2407
- /**
2408
- * This error occurs when some expectation is not met in the execution of the pipeline
2409
- *
2410
- * @private error of `checkExpectations` and `createPipelineExecutor`
2411
- * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
2412
- * Note: This is a kindof subtype of PipelineExecutionError
2413
- */
2414
- var ExpectError = /** @class */ (function (_super) {
2415
- __extends(ExpectError, _super);
2416
- function ExpectError(message) {
2417
- var _this = _super.call(this, message) || this;
2418
- _this.name = 'ExpectError';
2419
- Object.setPrototypeOf(_this, ExpectError.prototype);
2420
- return _this;
2421
- }
2422
- return ExpectError;
2423
- }(Error));
2424
-
2425
2427
  /**
2426
2428
  * Serializes an error into a [πŸš‰] JSON-serializable object
2427
2429
  *
@@ -3136,13 +3138,24 @@
3136
3138
  var pipeline = options.pipeline, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
3137
3139
  var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? MAX_EXECUTION_ATTEMPTS : _b, _c = settings.maxParallelCount, maxParallelCount = _c === void 0 ? MAX_PARALLEL_COUNT : _c, _d = settings.isVerbose, isVerbose = _d === void 0 ? IS_VERBOSE : _d, _e = settings.isNotPreparedWarningSupressed, isNotPreparedWarningSupressed = _e === void 0 ? false : _e;
3138
3140
  validatePipeline(pipeline);
3141
+ var pipelineIdentification = (function () {
3142
+ // Note: This is a 😐 implementation of [🚞]
3143
+ var _ = [];
3144
+ if (pipeline.sourceFile !== undefined) {
3145
+ _.push("File: ".concat(pipeline.sourceFile));
3146
+ }
3147
+ if (pipeline.pipelineUrl !== undefined) {
3148
+ _.push("Url: ".concat(pipeline.pipelineUrl));
3149
+ }
3150
+ return _.join('\n');
3151
+ })();
3139
3152
  var llmTools = joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(arrayableToArray(tools.llm)), false));
3140
3153
  var preparedPipeline;
3141
3154
  if (isPipelinePrepared(pipeline)) {
3142
3155
  preparedPipeline = pipeline;
3143
3156
  }
3144
3157
  else if (isNotPreparedWarningSupressed !== true) {
3145
- console.warn(spaceTrim.spaceTrim("\n Pipeline ".concat(pipeline.pipelineUrl || pipeline.sourceFile || pipeline.title, " is not prepared\n\n ").concat(pipeline.sourceFile, "\n\n It will be prepared ad-hoc before the first execution and **returned as `preparedPipeline` in `PipelineExecutorResult`**\n But it is recommended to prepare the pipeline during collection preparation\n\n @see more at https://ptbk.io/prepare-pipeline\n ")));
3158
+ console.warn(spaceTrim.spaceTrim(function (block) { return "\n Pipeline is not prepared\n\n ".concat(block(pipelineIdentification), "\n\n It will be prepared ad-hoc before the first execution and **returned as `preparedPipeline` in `PipelineExecutorResult`**\n But it is recommended to prepare the pipeline during collection preparation\n\n @see more at https://ptbk.io/prepare-pipeline\n "); }));
3146
3159
  }
3147
3160
  var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
3148
3161
  // TODO: !!! Extract to separate functions and files - ALL FUNCTIONS BELOW
@@ -3180,7 +3193,7 @@
3180
3193
  }
3181
3194
  function getReservedParametersForTemplate(template) {
3182
3195
  return __awaiter(this, void 0, void 0, function () {
3183
- var context, knowledge, samples, currentDate, modelName, reservedParameters, RESERVED_PARAMETER_NAMES_1, RESERVED_PARAMETER_NAMES_1_1, parameterName;
3196
+ var context, knowledge, samples, currentDate, modelName, reservedParameters, _loop_3, RESERVED_PARAMETER_NAMES_1, RESERVED_PARAMETER_NAMES_1_1, parameterName;
3184
3197
  var e_3, _a;
3185
3198
  return __generator(this, function (_b) {
3186
3199
  switch (_b.label) {
@@ -3203,13 +3216,16 @@
3203
3216
  currentDate: currentDate,
3204
3217
  modelName: modelName,
3205
3218
  };
3219
+ _loop_3 = function (parameterName) {
3220
+ if (reservedParameters[parameterName] === undefined) {
3221
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Reserved parameter {".concat(parameterName, "} is not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3222
+ }
3223
+ };
3206
3224
  try {
3207
3225
  // Note: Doublecheck that ALL reserved parameters are defined:
3208
3226
  for (RESERVED_PARAMETER_NAMES_1 = __values(RESERVED_PARAMETER_NAMES), RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next(); !RESERVED_PARAMETER_NAMES_1_1.done; RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next()) {
3209
3227
  parameterName = RESERVED_PARAMETER_NAMES_1_1.value;
3210
- if (reservedParameters[parameterName] === undefined) {
3211
- throw new UnexpectedError("Reserved parameter {".concat(parameterName, "} is not defined"));
3212
- }
3228
+ _loop_3(parameterName);
3213
3229
  }
3214
3230
  }
3215
3231
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
@@ -3226,10 +3242,10 @@
3226
3242
  }
3227
3243
  function executeSingleTemplate(currentTemplate) {
3228
3244
  return __awaiter(this, void 0, void 0, function () {
3229
- var name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _d, _e, parameterName, prompt, chatResult, completionResult, embeddingResult, result, resultString, expectError, scriptPipelineExecutionErrors, maxAttempts, jokerParameterNames, preparedContent, attempt, isJokerAttempt, jokerParameterName, _f, _g, _h, _j, scriptTools, error_2, e_4_1, _k, _l, functionName, postprocessingError, _m, _o, scriptTools, error_3, e_5_1, e_6_1, error_4;
3230
- var e_7, _p, e_4, _q, e_6, _r, e_5, _s, _t;
3231
- return __generator(this, function (_u) {
3232
- switch (_u.label) {
3245
+ var name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_4, _d, _e, parameterName, prompt, chatResult, completionResult, embeddingResult, result, resultString, expectError, scriptPipelineExecutionErrors, maxAttempts, jokerParameterNames, preparedContent, _loop_5, attempt, state_2;
3246
+ var e_4, _f, _g;
3247
+ return __generator(this, function (_h) {
3248
+ switch (_h.label) {
3233
3249
  case 0:
3234
3250
  name = "pipeline-executor-frame-".concat(currentTemplate.name);
3235
3251
  title = currentTemplate.title;
@@ -3246,47 +3262,48 @@
3246
3262
  // <- [3]
3247
3263
  })];
3248
3264
  case 1:
3249
- _u.sent();
3250
- _u.label = 2;
3265
+ _h.sent();
3266
+ _h.label = 2;
3251
3267
  case 2:
3252
3268
  usedParameterNames = extractParameterNamesFromPromptTemplate(currentTemplate);
3253
3269
  dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
3254
3270
  if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3255
- throw new UnexpectedError(spaceTrim.spaceTrim("\n Dependent parameters are not consistent used parameters:\n\n Dependent parameters:\n ".concat(Array.from(dependentParameterNames).join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames).join(', '), "\n\n ")));
3271
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Dependent parameters are not consistent used parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Dependent parameters:\n ").concat(Array.from(dependentParameterNames).join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames).join(', '), "\n\n "); }));
3256
3272
  }
3257
3273
  _b = (_a = Object).freeze;
3258
3274
  _c = [{}];
3259
3275
  return [4 /*yield*/, getReservedParametersForTemplate(currentTemplate)];
3260
3276
  case 3:
3261
- definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_u.sent())])), parametersToPass])]);
3277
+ definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_h.sent())])), parametersToPass])]);
3262
3278
  definedParameterNames = new Set(Object.keys(definedParameters));
3263
3279
  parameters = {};
3280
+ _loop_4 = function (parameterName) {
3281
+ // Situation: Parameter is defined and used
3282
+ if (definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3283
+ parameters[parameterName] = definedParameters[parameterName];
3284
+ }
3285
+ // Situation: Parameter is defined but NOT used
3286
+ else if (definedParameterNames.has(parameterName) && !usedParameterNames.has(parameterName)) ;
3287
+ // Situation: Parameter is NOT defined BUT used
3288
+ else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3289
+ // Houston, we have a problem
3290
+ // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
3291
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Parameter {".concat(parameterName, "} is NOT defined\n BUT used in template \"").concat(currentTemplate.title || currentTemplate.name, "\"\n\n This should be catched in `validatePipeline`\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3292
+ }
3293
+ };
3264
3294
  try {
3265
3295
  // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
3266
3296
  for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
3267
3297
  parameterName = _e.value;
3268
- // Situation: Parameter is defined and used
3269
- if (definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3270
- parameters[parameterName] = definedParameters[parameterName];
3271
- }
3272
- // Situation: Parameter is defined but NOT used
3273
- else if (definedParameterNames.has(parameterName) && !usedParameterNames.has(parameterName)) {
3274
- // Do not pass this parameter to prompt
3275
- }
3276
- // Situation: Parameter is NOT defined BUT used
3277
- else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3278
- // Houston, we have a problem
3279
- // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
3280
- throw new UnexpectedError(spaceTrim.spaceTrim("\n Parameter {".concat(parameterName, "} is NOT defined\n BUT used in template \"").concat(currentTemplate.title || currentTemplate.name, "\"\n\n This should be catched in `validatePipeline`\n\n ")));
3281
- }
3298
+ _loop_4(parameterName);
3282
3299
  }
3283
3300
  }
3284
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
3301
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
3285
3302
  finally {
3286
3303
  try {
3287
- if (_e && !_e.done && (_p = _d.return)) _p.call(_d);
3304
+ if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
3288
3305
  }
3289
- finally { if (e_7) throw e_7.error; }
3306
+ finally { if (e_4) throw e_4.error; }
3290
3307
  }
3291
3308
  // Note: Now we can freeze `parameters` because we are sure that all and only used parameters are defined
3292
3309
  Object.freeze(parameters);
@@ -3298,297 +3315,310 @@
3298
3315
  preparedContent = (currentTemplate.preparedContent || '{content}')
3299
3316
  .split('{content}')
3300
3317
  .join(currentTemplate.content);
3318
+ _loop_5 = function (attempt) {
3319
+ var isJokerAttempt, jokerParameterName, _j, _k, _l, _m, scriptTools, error_2, e_5_1, _o, _p, functionName, postprocessingError, _q, _r, scriptTools, error_3, e_6_1, e_7_1, error_4;
3320
+ var e_5, _s, e_7, _t, e_6, _u;
3321
+ return __generator(this, function (_v) {
3322
+ switch (_v.label) {
3323
+ case 0:
3324
+ isJokerAttempt = attempt < 0;
3325
+ jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3326
+ if (isJokerAttempt && !jokerParameterName) {
3327
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3328
+ }
3329
+ result = null;
3330
+ resultString = null;
3331
+ expectError = null;
3332
+ if (isJokerAttempt) {
3333
+ if (parameters[jokerParameterName] === undefined) {
3334
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3335
+ // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3336
+ }
3337
+ else {
3338
+ resultString = parameters[jokerParameterName];
3339
+ }
3340
+ }
3341
+ _v.label = 1;
3342
+ case 1:
3343
+ _v.trys.push([1, 44, 45, 46]);
3344
+ if (!!isJokerAttempt) return [3 /*break*/, 26];
3345
+ _j = currentTemplate.blockType;
3346
+ switch (_j) {
3347
+ case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3348
+ case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3349
+ case 'SCRIPT': return [3 /*break*/, 12];
3350
+ case 'PROMPT_DIALOG': return [3 /*break*/, 23];
3351
+ }
3352
+ return [3 /*break*/, 25];
3353
+ case 2:
3354
+ resultString = replaceParameters(preparedContent, parameters);
3355
+ return [3 /*break*/, 26];
3356
+ case 3:
3357
+ prompt = {
3358
+ title: currentTemplate.title,
3359
+ pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3360
+ ? preparedPipeline.pipelineUrl
3361
+ : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
3362
+ parameters: parameters,
3363
+ content: preparedContent,
3364
+ modelRequirements: currentTemplate.modelRequirements,
3365
+ expectations: __assign(__assign({}, (preparedPipeline.personas.find(function (_a) {
3366
+ var name = _a.name;
3367
+ return name === currentTemplate.personaName;
3368
+ }) || {})), currentTemplate.expectations),
3369
+ expectFormat: currentTemplate.expectFormat,
3370
+ postprocessingFunctionNames: currentTemplate.postprocessingFunctionNames,
3371
+ }; // <- TODO: Not very good type guard
3372
+ _k = currentTemplate.modelRequirements.modelVariant;
3373
+ switch (_k) {
3374
+ case 'CHAT': return [3 /*break*/, 4];
3375
+ case 'COMPLETION': return [3 /*break*/, 6];
3376
+ case 'EMBEDDING': return [3 /*break*/, 8];
3377
+ }
3378
+ return [3 /*break*/, 10];
3379
+ case 4: return [4 /*yield*/, llmTools.callChatModel($deepFreeze(prompt))];
3380
+ case 5:
3381
+ chatResult = _v.sent();
3382
+ // TODO: [🍬] Destroy chatThread
3383
+ result = chatResult;
3384
+ resultString = chatResult.content;
3385
+ return [3 /*break*/, 11];
3386
+ case 6: return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze(prompt))];
3387
+ case 7:
3388
+ completionResult = _v.sent();
3389
+ result = completionResult;
3390
+ resultString = completionResult.content;
3391
+ return [3 /*break*/, 11];
3392
+ case 8: return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze(prompt))];
3393
+ case 9:
3394
+ embeddingResult = _v.sent();
3395
+ result = embeddingResult;
3396
+ resultString = embeddingResult.content.join(',');
3397
+ return [3 /*break*/, 11];
3398
+ case 10: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n\n "); }));
3399
+ case 11: return [3 /*break*/, 26];
3400
+ case 12:
3401
+ if (arrayableToArray(tools.script).length === 0) {
3402
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3403
+ }
3404
+ if (!currentTemplate.contentLanguage) {
3405
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script language is not defined for prompt template \"".concat(currentTemplate.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3406
+ }
3407
+ // TODO: DRY [1]
3408
+ scriptPipelineExecutionErrors = [];
3409
+ _v.label = 13;
3410
+ case 13:
3411
+ _v.trys.push([13, 20, 21, 22]);
3412
+ _l = (e_5 = void 0, __values(arrayableToArray(tools.script))), _m = _l.next();
3413
+ _v.label = 14;
3414
+ case 14:
3415
+ if (!!_m.done) return [3 /*break*/, 19];
3416
+ scriptTools = _m.value;
3417
+ _v.label = 15;
3418
+ case 15:
3419
+ _v.trys.push([15, 17, , 18]);
3420
+ return [4 /*yield*/, scriptTools.execute($deepFreeze({
3421
+ scriptLanguage: currentTemplate.contentLanguage,
3422
+ script: preparedContent,
3423
+ parameters: parameters,
3424
+ }))];
3425
+ case 16:
3426
+ resultString = _v.sent();
3427
+ return [3 /*break*/, 19];
3428
+ case 17:
3429
+ error_2 = _v.sent();
3430
+ if (!(error_2 instanceof Error)) {
3431
+ throw error_2;
3432
+ }
3433
+ if (error_2 instanceof UnexpectedError) {
3434
+ throw error_2;
3435
+ }
3436
+ scriptPipelineExecutionErrors.push(error_2);
3437
+ return [3 /*break*/, 18];
3438
+ case 18:
3439
+ _m = _l.next();
3440
+ return [3 /*break*/, 14];
3441
+ case 19: return [3 /*break*/, 22];
3442
+ case 20:
3443
+ e_5_1 = _v.sent();
3444
+ e_5 = { error: e_5_1 };
3445
+ return [3 /*break*/, 22];
3446
+ case 21:
3447
+ try {
3448
+ if (_m && !_m.done && (_s = _l.return)) _s.call(_l);
3449
+ }
3450
+ finally { if (e_5) throw e_5.error; }
3451
+ return [7 /*endfinally*/];
3452
+ case 22:
3453
+ if (resultString !== null) {
3454
+ return [3 /*break*/, 26];
3455
+ }
3456
+ if (scriptPipelineExecutionErrors.length === 1) {
3457
+ throw scriptPipelineExecutionErrors[0];
3458
+ }
3459
+ else {
3460
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script execution failed ".concat(scriptPipelineExecutionErrors.length, " times\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block(scriptPipelineExecutionErrors
3461
+ .map(function (error) { return '- ' + error.message; })
3462
+ .join('\n\n')), "\n "); }));
3463
+ }
3464
+ case 23:
3465
+ if (tools.userInterface === undefined) {
3466
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3467
+ }
3468
+ return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3469
+ promptTitle: currentTemplate.title,
3470
+ promptMessage: replaceParameters(currentTemplate.description || '', parameters),
3471
+ defaultValue: replaceParameters(preparedContent, parameters),
3472
+ // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3473
+ placeholder: undefined,
3474
+ priority: priority,
3475
+ }))];
3476
+ case 24:
3477
+ // TODO: [🌹] When making next attempt for `PROMPT DIALOG`, preserve the previous user input
3478
+ resultString = _v.sent();
3479
+ return [3 /*break*/, 26];
3480
+ case 25: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown execution type \"".concat(currentTemplate.blockType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3481
+ case 26:
3482
+ if (!(!isJokerAttempt && currentTemplate.postprocessingFunctionNames)) return [3 /*break*/, 43];
3483
+ _v.label = 27;
3484
+ case 27:
3485
+ _v.trys.push([27, 41, 42, 43]);
3486
+ _o = (e_7 = void 0, __values(currentTemplate.postprocessingFunctionNames)), _p = _o.next();
3487
+ _v.label = 28;
3488
+ case 28:
3489
+ if (!!_p.done) return [3 /*break*/, 40];
3490
+ functionName = _p.value;
3491
+ // TODO: DRY [1]
3492
+ scriptPipelineExecutionErrors = [];
3493
+ postprocessingError = null;
3494
+ _v.label = 29;
3495
+ case 29:
3496
+ _v.trys.push([29, 36, 37, 38]);
3497
+ _q = (e_6 = void 0, __values(arrayableToArray(tools.script))), _r = _q.next();
3498
+ _v.label = 30;
3499
+ case 30:
3500
+ if (!!_r.done) return [3 /*break*/, 35];
3501
+ scriptTools = _r.value;
3502
+ _v.label = 31;
3503
+ case 31:
3504
+ _v.trys.push([31, 33, , 34]);
3505
+ return [4 /*yield*/, scriptTools.execute({
3506
+ scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3507
+ script: "".concat(functionName, "(resultString)"),
3508
+ parameters: {
3509
+ resultString: resultString || '',
3510
+ // Note: No ...parametersForTemplate, because working with result only
3511
+ },
3512
+ })];
3513
+ case 32:
3514
+ resultString = _v.sent();
3515
+ postprocessingError = null;
3516
+ return [3 /*break*/, 35];
3517
+ case 33:
3518
+ error_3 = _v.sent();
3519
+ if (!(error_3 instanceof Error)) {
3520
+ throw error_3;
3521
+ }
3522
+ if (error_3 instanceof UnexpectedError) {
3523
+ throw error_3;
3524
+ }
3525
+ postprocessingError = error_3;
3526
+ scriptPipelineExecutionErrors.push(error_3);
3527
+ return [3 /*break*/, 34];
3528
+ case 34:
3529
+ _r = _q.next();
3530
+ return [3 /*break*/, 30];
3531
+ case 35: return [3 /*break*/, 38];
3532
+ case 36:
3533
+ e_6_1 = _v.sent();
3534
+ e_6 = { error: e_6_1 };
3535
+ return [3 /*break*/, 38];
3536
+ case 37:
3537
+ try {
3538
+ if (_r && !_r.done && (_u = _q.return)) _u.call(_q);
3539
+ }
3540
+ finally { if (e_6) throw e_6.error; }
3541
+ return [7 /*endfinally*/];
3542
+ case 38:
3543
+ if (postprocessingError) {
3544
+ throw postprocessingError;
3545
+ }
3546
+ _v.label = 39;
3547
+ case 39:
3548
+ _p = _o.next();
3549
+ return [3 /*break*/, 28];
3550
+ case 40: return [3 /*break*/, 43];
3551
+ case 41:
3552
+ e_7_1 = _v.sent();
3553
+ e_7 = { error: e_7_1 };
3554
+ return [3 /*break*/, 43];
3555
+ case 42:
3556
+ try {
3557
+ if (_p && !_p.done && (_t = _o.return)) _t.call(_o);
3558
+ }
3559
+ finally { if (e_7) throw e_7.error; }
3560
+ return [7 /*endfinally*/];
3561
+ case 43:
3562
+ // TODO: [πŸ’] Unite object for expecting amount and format
3563
+ if (currentTemplate.expectFormat) {
3564
+ if (currentTemplate.expectFormat === 'JSON') {
3565
+ if (!isValidJsonString(resultString || '')) {
3566
+ throw new ExpectError(spaceTrim.spaceTrim(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(pipelineIdentification), "\n "); }));
3567
+ }
3568
+ }
3569
+ }
3570
+ // TODO: [πŸ’] Unite object for expecting amount and format
3571
+ if (currentTemplate.expectations) {
3572
+ checkExpectations(currentTemplate.expectations, resultString || '');
3573
+ }
3574
+ return [2 /*return*/, "break-attempts"];
3575
+ case 44:
3576
+ error_4 = _v.sent();
3577
+ if (!(error_4 instanceof ExpectError)) {
3578
+ throw error_4;
3579
+ }
3580
+ expectError = error_4;
3581
+ return [3 /*break*/, 46];
3582
+ case 45:
3583
+ if (!isJokerAttempt &&
3584
+ currentTemplate.blockType === 'PROMPT_TEMPLATE' &&
3585
+ prompt
3586
+ // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
3587
+ // In that case we don’t want to make a report about it because it’s not a llm execution error
3588
+ ) {
3589
+ // TODO: [🧠] Maybe put other blockTypes into report
3590
+ executionReport.promptExecutions.push({
3591
+ prompt: __assign({}, prompt),
3592
+ result: result || undefined,
3593
+ error: expectError === null ? undefined : serializeError(expectError),
3594
+ });
3595
+ }
3596
+ return [7 /*endfinally*/];
3597
+ case 46:
3598
+ if (expectError !== null && attempt === maxAttempts - 1) {
3599
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n LLM execution failed ".concat(maxExecutionAttempts, "x\n\n ---\n Last error ").concat((expectError === null || expectError === void 0 ? void 0 : expectError.name) || '', ":\n ").concat(block((expectError === null || expectError === void 0 ? void 0 : expectError.message) || ''), "\n\n Last result:\n ").concat(resultString, "\n ---\n "); }));
3600
+ }
3601
+ return [2 /*return*/];
3602
+ }
3603
+ });
3604
+ };
3301
3605
  attempt = -jokerParameterNames.length;
3302
- _u.label = 4;
3606
+ _h.label = 4;
3303
3607
  case 4:
3304
- if (!(attempt < maxAttempts)) return [3 /*break*/, 52];
3305
- isJokerAttempt = attempt < 0;
3306
- jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3307
- if (isJokerAttempt && !jokerParameterName) {
3308
- throw new UnexpectedError("Joker not found in attempt ".concat(attempt));
3309
- }
3310
- result = null;
3311
- resultString = null;
3312
- expectError = null;
3313
- if (isJokerAttempt) {
3314
- if (parameters[jokerParameterName] === undefined) {
3315
- throw new PipelineExecutionError("Joker parameter {".concat(jokerParameterName, "} not defined"));
3316
- // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3317
- }
3318
- else {
3319
- resultString = parameters[jokerParameterName];
3320
- }
3321
- }
3322
- _u.label = 5;
3608
+ if (!(attempt < maxAttempts)) return [3 /*break*/, 7];
3609
+ return [5 /*yield**/, _loop_5(attempt)];
3323
3610
  case 5:
3324
- _u.trys.push([5, 48, 49, 50]);
3325
- if (!!isJokerAttempt) return [3 /*break*/, 30];
3326
- _f = currentTemplate.blockType;
3327
- switch (_f) {
3328
- case 'SIMPLE_TEMPLATE': return [3 /*break*/, 6];
3329
- case 'PROMPT_TEMPLATE': return [3 /*break*/, 7];
3330
- case 'SCRIPT': return [3 /*break*/, 16];
3331
- case 'PROMPT_DIALOG': return [3 /*break*/, 27];
3611
+ state_2 = _h.sent();
3612
+ switch (state_2) {
3613
+ case "break-attempts": return [3 /*break*/, 7];
3332
3614
  }
3333
- return [3 /*break*/, 29];
3615
+ _h.label = 6;
3334
3616
  case 6:
3335
- resultString = replaceParameters(preparedContent, parameters);
3336
- return [3 /*break*/, 30];
3337
- case 7:
3338
- prompt = {
3339
- title: currentTemplate.title,
3340
- pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3341
- ? preparedPipeline.pipelineUrl
3342
- : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
3343
- parameters: parameters,
3344
- content: preparedContent,
3345
- modelRequirements: currentTemplate.modelRequirements,
3346
- expectations: __assign(__assign({}, (preparedPipeline.personas.find(function (_a) {
3347
- var name = _a.name;
3348
- return name === currentTemplate.personaName;
3349
- }) || {})), currentTemplate.expectations),
3350
- expectFormat: currentTemplate.expectFormat,
3351
- postprocessingFunctionNames: currentTemplate.postprocessingFunctionNames,
3352
- }; // <- TODO: Not very good type guard
3353
- _g = currentTemplate.modelRequirements.modelVariant;
3354
- switch (_g) {
3355
- case 'CHAT': return [3 /*break*/, 8];
3356
- case 'COMPLETION': return [3 /*break*/, 10];
3357
- case 'EMBEDDING': return [3 /*break*/, 12];
3358
- }
3359
- return [3 /*break*/, 14];
3360
- case 8: return [4 /*yield*/, llmTools.callChatModel($deepFreeze(prompt))];
3361
- case 9:
3362
- chatResult = _u.sent();
3363
- // TODO: [🍬] Destroy chatThread
3364
- result = chatResult;
3365
- resultString = chatResult.content;
3366
- return [3 /*break*/, 15];
3367
- case 10: return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze(prompt))];
3368
- case 11:
3369
- completionResult = _u.sent();
3370
- result = completionResult;
3371
- resultString = completionResult.content;
3372
- return [3 /*break*/, 15];
3373
- case 12: return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze(prompt))];
3374
- case 13:
3375
- embeddingResult = _u.sent();
3376
- result = embeddingResult;
3377
- resultString = embeddingResult.content.join(',');
3378
- return [3 /*break*/, 15];
3379
- case 14: throw new PipelineExecutionError("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
3380
- case 15: return [3 /*break*/, 30];
3381
- case 16:
3382
- if (arrayableToArray(tools.script).length === 0) {
3383
- throw new PipelineExecutionError('No script execution tools are available');
3384
- }
3385
- if (!currentTemplate.contentLanguage) {
3386
- throw new PipelineExecutionError("Script language is not defined for prompt template \"".concat(currentTemplate.name, "\""));
3387
- }
3388
- // TODO: DRY [1]
3389
- scriptPipelineExecutionErrors = [];
3390
- _u.label = 17;
3391
- case 17:
3392
- _u.trys.push([17, 24, 25, 26]);
3393
- _h = (e_4 = void 0, __values(arrayableToArray(tools.script))), _j = _h.next();
3394
- _u.label = 18;
3395
- case 18:
3396
- if (!!_j.done) return [3 /*break*/, 23];
3397
- scriptTools = _j.value;
3398
- _u.label = 19;
3399
- case 19:
3400
- _u.trys.push([19, 21, , 22]);
3401
- return [4 /*yield*/, scriptTools.execute($deepFreeze({
3402
- scriptLanguage: currentTemplate.contentLanguage,
3403
- script: preparedContent,
3404
- parameters: parameters,
3405
- }))];
3406
- case 20:
3407
- resultString = _u.sent();
3408
- return [3 /*break*/, 23];
3409
- case 21:
3410
- error_2 = _u.sent();
3411
- if (!(error_2 instanceof Error)) {
3412
- throw error_2;
3413
- }
3414
- if (error_2 instanceof UnexpectedError) {
3415
- throw error_2;
3416
- }
3417
- scriptPipelineExecutionErrors.push(error_2);
3418
- return [3 /*break*/, 22];
3419
- case 22:
3420
- _j = _h.next();
3421
- return [3 /*break*/, 18];
3422
- case 23: return [3 /*break*/, 26];
3423
- case 24:
3424
- e_4_1 = _u.sent();
3425
- e_4 = { error: e_4_1 };
3426
- return [3 /*break*/, 26];
3427
- case 25:
3428
- try {
3429
- if (_j && !_j.done && (_q = _h.return)) _q.call(_h);
3430
- }
3431
- finally { if (e_4) throw e_4.error; }
3432
- return [7 /*endfinally*/];
3433
- case 26:
3434
- if (resultString !== null) {
3435
- return [3 /*break*/, 30];
3436
- }
3437
- if (scriptPipelineExecutionErrors.length === 1) {
3438
- throw scriptPipelineExecutionErrors[0];
3439
- }
3440
- else {
3441
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script execution failed ".concat(scriptPipelineExecutionErrors.length, " times\n\n ").concat(block(scriptPipelineExecutionErrors
3442
- .map(function (error) { return '- ' + error.message; })
3443
- .join('\n\n')), "\n "); }));
3444
- }
3445
- case 27:
3446
- if (tools.userInterface === undefined) {
3447
- throw new PipelineExecutionError('User interface tools are not available');
3448
- }
3449
- return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3450
- promptTitle: currentTemplate.title,
3451
- promptMessage: replaceParameters(currentTemplate.description || '', parameters),
3452
- defaultValue: replaceParameters(preparedContent, parameters),
3453
- // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3454
- placeholder: undefined,
3455
- priority: priority,
3456
- }))];
3457
- case 28:
3458
- // TODO: [🌹] When making next attempt for `PROMPT DIALOG`, preserve the previous user input
3459
- resultString = _u.sent();
3460
- return [3 /*break*/, 30];
3461
- case 29: throw new PipelineExecutionError("Unknown execution type \"".concat(currentTemplate.blockType, "\""));
3462
- case 30:
3463
- if (!(!isJokerAttempt && currentTemplate.postprocessingFunctionNames)) return [3 /*break*/, 47];
3464
- _u.label = 31;
3465
- case 31:
3466
- _u.trys.push([31, 45, 46, 47]);
3467
- _k = (e_6 = void 0, __values(currentTemplate.postprocessingFunctionNames)), _l = _k.next();
3468
- _u.label = 32;
3469
- case 32:
3470
- if (!!_l.done) return [3 /*break*/, 44];
3471
- functionName = _l.value;
3472
- // TODO: DRY [1]
3473
- scriptPipelineExecutionErrors = [];
3474
- postprocessingError = null;
3475
- _u.label = 33;
3476
- case 33:
3477
- _u.trys.push([33, 40, 41, 42]);
3478
- _m = (e_5 = void 0, __values(arrayableToArray(tools.script))), _o = _m.next();
3479
- _u.label = 34;
3480
- case 34:
3481
- if (!!_o.done) return [3 /*break*/, 39];
3482
- scriptTools = _o.value;
3483
- _u.label = 35;
3484
- case 35:
3485
- _u.trys.push([35, 37, , 38]);
3486
- return [4 /*yield*/, scriptTools.execute({
3487
- scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3488
- script: "".concat(functionName, "(resultString)"),
3489
- parameters: {
3490
- resultString: resultString || '',
3491
- // Note: No ...parametersForTemplate, because working with result only
3492
- },
3493
- })];
3494
- case 36:
3495
- resultString = _u.sent();
3496
- postprocessingError = null;
3497
- return [3 /*break*/, 39];
3498
- case 37:
3499
- error_3 = _u.sent();
3500
- if (!(error_3 instanceof Error)) {
3501
- throw error_3;
3502
- }
3503
- if (error_3 instanceof UnexpectedError) {
3504
- throw error_3;
3505
- }
3506
- postprocessingError = error_3;
3507
- scriptPipelineExecutionErrors.push(error_3);
3508
- return [3 /*break*/, 38];
3509
- case 38:
3510
- _o = _m.next();
3511
- return [3 /*break*/, 34];
3512
- case 39: return [3 /*break*/, 42];
3513
- case 40:
3514
- e_5_1 = _u.sent();
3515
- e_5 = { error: e_5_1 };
3516
- return [3 /*break*/, 42];
3517
- case 41:
3518
- try {
3519
- if (_o && !_o.done && (_s = _m.return)) _s.call(_m);
3520
- }
3521
- finally { if (e_5) throw e_5.error; }
3522
- return [7 /*endfinally*/];
3523
- case 42:
3524
- if (postprocessingError) {
3525
- throw postprocessingError;
3526
- }
3527
- _u.label = 43;
3528
- case 43:
3529
- _l = _k.next();
3530
- return [3 /*break*/, 32];
3531
- case 44: return [3 /*break*/, 47];
3532
- case 45:
3533
- e_6_1 = _u.sent();
3534
- e_6 = { error: e_6_1 };
3535
- return [3 /*break*/, 47];
3536
- case 46:
3537
- try {
3538
- if (_l && !_l.done && (_r = _k.return)) _r.call(_k);
3539
- }
3540
- finally { if (e_6) throw e_6.error; }
3541
- return [7 /*endfinally*/];
3542
- case 47:
3543
- // TODO: [πŸ’] Unite object for expecting amount and format
3544
- if (currentTemplate.expectFormat) {
3545
- if (currentTemplate.expectFormat === 'JSON') {
3546
- if (!isValidJsonString(resultString || '')) {
3547
- throw new ExpectError('Expected valid JSON string');
3548
- }
3549
- }
3550
- }
3551
- // TODO: [πŸ’] Unite object for expecting amount and format
3552
- if (currentTemplate.expectations) {
3553
- checkExpectations(currentTemplate.expectations, resultString || '');
3554
- }
3555
- return [3 /*break*/, 52];
3556
- case 48:
3557
- error_4 = _u.sent();
3558
- if (!(error_4 instanceof ExpectError)) {
3559
- throw error_4;
3560
- }
3561
- if (error_4 instanceof UnexpectedError) {
3562
- throw error_4;
3563
- }
3564
- expectError = error_4;
3565
- return [3 /*break*/, 50];
3566
- case 49:
3567
- if (!isJokerAttempt &&
3568
- currentTemplate.blockType === 'PROMPT_TEMPLATE' &&
3569
- prompt
3570
- // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
3571
- // In that case we don’t want to make a report about it because it’s not a llm execution error
3572
- ) {
3573
- // TODO: [🧠] Maybe put other blockTypes into report
3574
- executionReport.promptExecutions.push({
3575
- prompt: __assign({}, prompt),
3576
- result: result || undefined,
3577
- error: expectError === null ? undefined : serializeError(expectError),
3578
- });
3579
- }
3580
- return [7 /*endfinally*/];
3581
- case 50:
3582
- if (expectError !== null && attempt === maxAttempts - 1) {
3583
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n LLM execution failed ".concat(maxExecutionAttempts, "x\n\n ---\n Last error ").concat((expectError === null || expectError === void 0 ? void 0 : expectError.name) || '', ":\n ").concat(block((expectError === null || expectError === void 0 ? void 0 : expectError.message) || ''), "\n\n Last result:\n ").concat(resultString, "\n ---\n "); }));
3584
- }
3585
- _u.label = 51;
3586
- case 51:
3587
3617
  attempt++;
3588
3618
  return [3 /*break*/, 4];
3589
- case 52:
3619
+ case 7:
3590
3620
  if (resultString === null) {
3591
- throw new UnexpectedError('Something went wrong and prompt result is null');
3621
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
3592
3622
  }
3593
3623
  if (onProgress /* <- [3] */) {
3594
3624
  onProgress({
@@ -3602,7 +3632,7 @@
3602
3632
  // <- [3]
3603
3633
  });
3604
3634
  }
3605
- parametersToPass = Object.freeze(__assign(__assign({}, parametersToPass), (_t = {}, _t[currentTemplate.resultingParameterName] = resultString /* <- Note: Not need to detect parameter collision here because pipeline checks logic consistency during construction */, _t)));
3635
+ parametersToPass = Object.freeze(__assign(__assign({}, parametersToPass), (_g = {}, _g[currentTemplate.resultingParameterName] = resultString /* <- Note: Not need to detect parameter collision here because pipeline checks logic consistency during construction */, _g)));
3606
3636
  return [2 /*return*/];
3607
3637
  }
3608
3638
  });
@@ -3611,6 +3641,14 @@
3611
3641
  function filterJustOutputParameters() {
3612
3642
  var e_8, _a;
3613
3643
  var outputParameters = {};
3644
+ var _loop_6 = function (parameter) {
3645
+ if (parametersToPass[parameter.name] === undefined) {
3646
+ // [4]
3647
+ warnings.push(new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Parameter {".concat(parameter.name, "} should be an output parameter, but it was not generated during pipeline execution\n\n ").concat(block(pipelineIdentification), "\n "); })));
3648
+ return "continue";
3649
+ }
3650
+ outputParameters[parameter.name] = parametersToPass[parameter.name] || '';
3651
+ };
3614
3652
  try {
3615
3653
  // Note: Filter ONLY output parameters
3616
3654
  for (var _b = __values(preparedPipeline.parameters.filter(function (_a) {
@@ -3618,12 +3656,7 @@
3618
3656
  return isOutput;
3619
3657
  })), _c = _b.next(); !_c.done; _c = _b.next()) {
3620
3658
  var parameter = _c.value;
3621
- if (parametersToPass[parameter.name] === undefined) {
3622
- // [4]
3623
- warnings.push(new PipelineExecutionError("Parameter {".concat(parameter.name, "} should be an output parameter, but it was not generated during pipeline execution")));
3624
- continue;
3625
- }
3626
- outputParameters[parameter.name] = parametersToPass[parameter.name] || '';
3659
+ _loop_6(parameter);
3627
3660
  }
3628
3661
  }
3629
3662
  catch (e_8_1) { e_8 = { error: e_8_1 }; }
@@ -3695,13 +3728,13 @@
3695
3728
  return name === parameterName;
3696
3729
  });
3697
3730
  if (parameter === undefined) {
3698
- warnings.push(new PipelineExecutionError("Extra parameter {".concat(parameterName, "} is being passed which is not part of the pipeline.")));
3731
+ warnings.push(new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Extra parameter {".concat(parameterName, "} is being passed which is not part of the pipeline.\n\n ").concat(block(pipelineIdentification), "\n "); })));
3699
3732
  }
3700
3733
  else if (parameter.isInput === false) {
3701
- return { value: $asDeeplyFrozenSerializableJson("Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult"), {
3734
+ return { value: $asDeeplyFrozenSerializableJson(spaceTrim.spaceTrim(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
3702
3735
  isSuccessful: false,
3703
3736
  errors: __spreadArray([
3704
- new PipelineExecutionError("Parameter {".concat(parameter.name, "} is passed as input parameter but it is not input"))
3737
+ new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Parameter {".concat(parameter.name, "} is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
3705
3738
  ], __read(errors), false).map(serializeError),
3706
3739
  warnings: warnings.map(serializeError),
3707
3740
  executionReport: executionReport,
@@ -3750,7 +3783,7 @@
3750
3783
  case 0:
3751
3784
  if (loopLimit-- < 0) {
3752
3785
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
3753
- throw new UnexpectedError('Loop limit reached during resolving parameters pipeline execution');
3786
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
3754
3787
  }
3755
3788
  currentTemplate = unresovedTemplates_1.find(function (template) {
3756
3789
  return template.dependentParameterNames.every(function (name) {
@@ -3760,7 +3793,7 @@
3760
3793
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
3761
3794
  throw new UnexpectedError(
3762
3795
  // TODO: [🐎] DRY
3763
- spaceTrim.spaceTrim(function (block) { return "\n Can not resolve some parameters:\n\n Can not resolve:\n ".concat(block(unresovedTemplates_1
3796
+ spaceTrim.spaceTrim(function (block) { return "\n Can not resolve some parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Can not resolve:\n ").concat(block(unresovedTemplates_1
3764
3797
  .map(function (_a) {
3765
3798
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
3766
3799
  return "- Parameter {".concat(resultingParameterName, "} which depends on ").concat(dependentParameterNames
@@ -3840,6 +3873,7 @@
3840
3873
  return pipelineExecutor;
3841
3874
  }
3842
3875
  /**
3876
+ * TODO: !!! Identify not only pipeline BUT exact template ${block(pipelineIdentification)}
3843
3877
  * TODO: Use isVerbose here (not only pass to `preparePipeline`)
3844
3878
  * TODO: [🧠][🌳] Use here `countTotalUsage` and put preparation and prepared pipiline to report
3845
3879
  * TODO: [πŸͺ‚] Use maxParallelCount here (not only pass to `preparePipeline`)
@@ -4379,6 +4413,8 @@
4379
4413
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
4380
4414
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
4381
4415
  * TODO: [πŸ› ] Actions, instruments (and maybe knowledge) => Functions and tools
4416
+ * TODO: [🧠][♏] Maybe if expecting JSON (In Anthropic Claude and other models without non-json) and its not specified in prompt content, append the instructions
4417
+ * @see https://docs.anthropic.com/en/docs/test-and-evaluate/strengthen-guardrails/increase-consistency#specify-the-desired-output-format
4382
4418
  */
4383
4419
 
4384
4420
  /**
@@ -7609,6 +7645,7 @@
7609
7645
  exports.EXPECTATION_UNITS = EXPECTATION_UNITS;
7610
7646
  exports.EnvironmentMismatchError = EnvironmentMismatchError;
7611
7647
  exports.ExecutionReportStringOptionsDefaults = ExecutionReportStringOptionsDefaults;
7648
+ exports.ExpectError = ExpectError;
7612
7649
  exports.IS_VERBOSE = IS_VERBOSE;
7613
7650
  exports.LimitReachedError = LimitReachedError;
7614
7651
  exports.MAX_EXECUTION_ATTEMPTS = MAX_EXECUTION_ATTEMPTS;