@promptbook/remote-client 0.112.0-39 → 0.112.0-41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -21
- package/esm/index.es.js +537 -321
- package/esm/index.es.js.map +1 -1
- package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.d.ts +8 -2
- package/esm/src/book-components/Chat/Chat/ChatInputArea.d.ts +0 -10
- package/esm/src/book-components/Chat/Chat/ChatInputUploadedFile.d.ts +10 -0
- package/esm/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +46 -0
- package/esm/src/book-components/Chat/Chat/resolveRunBrowserToolCallDetailsState.d.ts +146 -0
- package/esm/src/book-components/Chat/Chat/useChatInputAreaAttachments.d.ts +1 -1
- package/esm/src/book-components/Chat/Chat/useChatInputAreaComposer.d.ts +39 -0
- package/esm/src/book-components/Chat/Chat/useChatPostprocessedMessages.d.ts +17 -0
- package/esm/src/book-components/Chat/Chat/useChatScrollState.d.ts +34 -0
- package/esm/src/book-components/Chat/Chat/useChatToolCallModalState.d.ts +61 -0
- package/esm/src/book-components/Chat/Chat/useChatToolCallState.d.ts +35 -0
- package/esm/src/book-components/Chat/LlmChat/useLlmChatMessageHandler.d.ts +58 -0
- package/esm/src/book-components/Chat/LlmChat/useLlmChatMessages.d.ts +29 -0
- package/esm/src/book-components/Chat/LlmChat/useLlmChatState.d.ts +53 -0
- package/esm/src/collection/pipeline-collection/constructors/createPipelineCollectionFromDirectory.d.ts +7 -1
- package/esm/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +52 -0
- package/esm/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +128 -0
- package/esm/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +3 -3
- package/esm/src/llm-providers/openai/OpenAiVectorStoreHandler.d.ts +54 -0
- package/esm/src/llm-providers/openai/utils/OpenAiCompatibleUnsupportedParameterRetrier.d.ts +29 -0
- package/esm/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.d.ts +28 -0
- package/esm/src/types/number_usd.d.ts +1 -1
- package/esm/src/types/string_parameter_name.d.ts +2 -2
- package/esm/src/types/typeAliases.d.ts +2 -2
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +537 -321
- package/umd/index.umd.js.map +1 -1
- package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.d.ts +8 -2
- package/umd/src/book-components/Chat/Chat/ChatInputArea.d.ts +0 -10
- package/umd/src/book-components/Chat/Chat/ChatInputUploadedFile.d.ts +10 -0
- package/umd/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +46 -0
- package/umd/src/book-components/Chat/Chat/resolveRunBrowserToolCallDetailsState.d.ts +146 -0
- package/umd/src/book-components/Chat/Chat/useChatInputAreaAttachments.d.ts +1 -1
- package/umd/src/book-components/Chat/Chat/useChatInputAreaComposer.d.ts +39 -0
- package/umd/src/book-components/Chat/Chat/useChatPostprocessedMessages.d.ts +17 -0
- package/umd/src/book-components/Chat/Chat/useChatScrollState.d.ts +34 -0
- package/umd/src/book-components/Chat/Chat/useChatToolCallModalState.d.ts +61 -0
- package/umd/src/book-components/Chat/Chat/useChatToolCallState.d.ts +35 -0
- package/umd/src/book-components/Chat/LlmChat/useLlmChatMessageHandler.d.ts +58 -0
- package/umd/src/book-components/Chat/LlmChat/useLlmChatMessages.d.ts +29 -0
- package/umd/src/book-components/Chat/LlmChat/useLlmChatState.d.ts +53 -0
- package/umd/src/collection/pipeline-collection/constructors/createPipelineCollectionFromDirectory.d.ts +7 -1
- package/umd/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +52 -0
- package/umd/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +128 -0
- package/umd/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +3 -3
- package/umd/src/llm-providers/openai/OpenAiVectorStoreHandler.d.ts +54 -0
- package/umd/src/llm-providers/openai/utils/OpenAiCompatibleUnsupportedParameterRetrier.d.ts +29 -0
- package/umd/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.d.ts +28 -0
- package/umd/src/types/number_usd.d.ts +1 -1
- package/umd/src/types/string_parameter_name.d.ts +2 -2
- package/umd/src/types/typeAliases.d.ts +2 -2
- package/umd/src/version.d.ts +1 -1
package/umd/index.umd.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* @generated
|
|
23
23
|
* @see https://github.com/webgptorg/promptbook
|
|
24
24
|
*/
|
|
25
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
25
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-41';
|
|
26
26
|
/**
|
|
27
27
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
28
28
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -6199,6 +6199,42 @@
|
|
|
6199
6199
|
}
|
|
6200
6200
|
// TODO: [🔣] If script require contentLanguage
|
|
6201
6201
|
|
|
6202
|
+
/**
|
|
6203
|
+
* Normalizes inline parameter mentions wrapped in code spans before markdown flattening.
|
|
6204
|
+
*
|
|
6205
|
+
* @private internal utility of `parsePipeline`
|
|
6206
|
+
*/
|
|
6207
|
+
const INLINE_CODE_PARAMETER_REGEXP = /`\{(?<parameterName>[a-z0-9_]+)\}`/gi;
|
|
6208
|
+
/**
|
|
6209
|
+
* Normalizes inline return statements wrapped in code spans before markdown flattening.
|
|
6210
|
+
*
|
|
6211
|
+
* @private internal utility of `parsePipeline`
|
|
6212
|
+
*/
|
|
6213
|
+
const INLINE_CODE_RETURN_PARAMETER_REGEXP = /`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi;
|
|
6214
|
+
/**
|
|
6215
|
+
* Matches the trailing return statement of a task section.
|
|
6216
|
+
*
|
|
6217
|
+
* @private internal utility of `parsePipeline`
|
|
6218
|
+
*/
|
|
6219
|
+
const RESULTING_PARAMETER_LINE_REGEXP = /^->\s*\{(?<resultingParamName>[a-z0-9_]+)\}/im;
|
|
6220
|
+
/**
|
|
6221
|
+
* Removes fenced code blocks when deriving human-readable section descriptions.
|
|
6222
|
+
*
|
|
6223
|
+
* @private internal utility of `parsePipeline`
|
|
6224
|
+
*/
|
|
6225
|
+
const DESCRIPTION_CODE_BLOCK_REGEXP = /^```.*^```/gms;
|
|
6226
|
+
/**
|
|
6227
|
+
* Removes blockquote lines when deriving human-readable section descriptions.
|
|
6228
|
+
*
|
|
6229
|
+
* @private internal utility of `parsePipeline`
|
|
6230
|
+
*/
|
|
6231
|
+
const DESCRIPTION_BLOCKQUOTE_REGEXP = /^>.*$/gm;
|
|
6232
|
+
/**
|
|
6233
|
+
* Removes list items and return statements when deriving human-readable section descriptions.
|
|
6234
|
+
*
|
|
6235
|
+
* @private internal utility of `parsePipeline`
|
|
6236
|
+
*/
|
|
6237
|
+
const DESCRIPTION_LIST_ITEM_REGEXP = /^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm;
|
|
6202
6238
|
/**
|
|
6203
6239
|
* Compile pipeline from string (markdown) format to JSON format synchronously
|
|
6204
6240
|
*
|
|
@@ -6217,7 +6253,27 @@
|
|
|
6217
6253
|
* @public exported from `@promptbook/core`
|
|
6218
6254
|
*/
|
|
6219
6255
|
function parsePipeline(pipelineString) {
|
|
6220
|
-
const $pipelineJson =
|
|
6256
|
+
const $pipelineJson = createInitialPipelineJson(pipelineString);
|
|
6257
|
+
const preparedPipelineString = preparePipelineString(pipelineString, $pipelineJson);
|
|
6258
|
+
const { pipelineHead, pipelineSections } = parsePreparedPipelineSections(preparedPipelineString, $pipelineJson);
|
|
6259
|
+
const getUniqueSectionName = createUniqueSectionNameResolver(pipelineSections);
|
|
6260
|
+
applyPipelineHead(pipelineHead, $pipelineJson);
|
|
6261
|
+
for (const pipelineSection of pipelineSections) {
|
|
6262
|
+
processPipelineSection(pipelineSection, $pipelineJson, getUniqueSectionName);
|
|
6263
|
+
}
|
|
6264
|
+
applyImplicitParameterDirections($pipelineJson);
|
|
6265
|
+
removeUndefinedValuesFromPipeline($pipelineJson);
|
|
6266
|
+
applySyncHighLevelAbstractions($pipelineJson);
|
|
6267
|
+
ensurePipelineFormfactor($pipelineJson);
|
|
6268
|
+
return exportParsedPipelineJson($pipelineJson);
|
|
6269
|
+
}
|
|
6270
|
+
/**
|
|
6271
|
+
* Creates the mutable pipeline JSON structure used throughout parsing.
|
|
6272
|
+
*
|
|
6273
|
+
* @private internal utility of `parsePipeline`
|
|
6274
|
+
*/
|
|
6275
|
+
function createInitialPipelineJson(pipelineString) {
|
|
6276
|
+
return {
|
|
6221
6277
|
title: DEFAULT_BOOK_TITLE,
|
|
6222
6278
|
parameters: [],
|
|
6223
6279
|
tasks: [],
|
|
@@ -6234,56 +6290,90 @@
|
|
|
6234
6290
|
},
|
|
6235
6291
|
],
|
|
6236
6292
|
};
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
// =============================================================
|
|
6249
|
-
// Note: 1️⃣ Parsing of the markdown into object
|
|
6250
|
-
// ==============
|
|
6251
|
-
// Note: 1️⃣◽1️⃣ Remove #!shebang and comments
|
|
6252
|
-
if (pipelineString.startsWith('#!')) {
|
|
6253
|
-
const [shebangLine, ...restLines] = pipelineString.split(/\r?\n/);
|
|
6254
|
-
if (!(shebangLine || '').includes('ptbk')) {
|
|
6255
|
-
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6256
|
-
It seems that you try to parse a book file which has non-standard shebang line for book files:
|
|
6257
|
-
Shebang line must contain 'ptbk'
|
|
6258
|
-
|
|
6259
|
-
You have:
|
|
6260
|
-
${block(shebangLine || '(empty line)')}
|
|
6261
|
-
|
|
6262
|
-
It should look like this:
|
|
6263
|
-
#!/usr/bin/env ptbk
|
|
6264
|
-
|
|
6265
|
-
${block(getPipelineIdentification())}
|
|
6266
|
-
`));
|
|
6267
|
-
}
|
|
6268
|
-
pipelineString = validatePipelineString(restLines.join('\n'));
|
|
6293
|
+
}
|
|
6294
|
+
/**
|
|
6295
|
+
* Builds a short file/url identification block for parse errors.
|
|
6296
|
+
*
|
|
6297
|
+
* @private internal utility of `parsePipeline`
|
|
6298
|
+
*/
|
|
6299
|
+
function getPipelineIdentification($pipelineJson) {
|
|
6300
|
+
// Note: This is a 😐 implementation of [🚞]
|
|
6301
|
+
const pipelineIdentificationParts = [];
|
|
6302
|
+
if ($pipelineJson.sourceFile !== undefined) {
|
|
6303
|
+
pipelineIdentificationParts.push(`File: ${$pipelineJson.sourceFile}`);
|
|
6269
6304
|
}
|
|
6305
|
+
if ($pipelineJson.pipelineUrl !== undefined) {
|
|
6306
|
+
pipelineIdentificationParts.push(`Url: ${$pipelineJson.pipelineUrl}`);
|
|
6307
|
+
}
|
|
6308
|
+
return pipelineIdentificationParts.join('\n');
|
|
6309
|
+
}
|
|
6310
|
+
/**
|
|
6311
|
+
* Removes shebang/comments and normalizes markdown into a parseable pipeline form.
|
|
6312
|
+
*
|
|
6313
|
+
* @private internal utility of `parsePipeline`
|
|
6314
|
+
*/
|
|
6315
|
+
function preparePipelineString(pipelineString, $pipelineJson) {
|
|
6316
|
+
pipelineString = removePipelineShebang(pipelineString, $pipelineJson);
|
|
6270
6317
|
pipelineString = removeMarkdownComments(pipelineString);
|
|
6271
6318
|
pipelineString = spacetrim.spaceTrim(pipelineString);
|
|
6272
6319
|
// <- TODO: [😧] `spaceTrim` should preserve discriminated type *(or at lease `PipelineString`)*
|
|
6273
6320
|
pipelineString = deflatePipeline(pipelineString);
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
pipelineString =
|
|
6277
|
-
|
|
6278
|
-
|
|
6321
|
+
pipelineString = flattenMarkdown(pipelineString);
|
|
6322
|
+
pipelineString = pipelineString.replaceAll(INLINE_CODE_PARAMETER_REGEXP, '{$<parameterName>}');
|
|
6323
|
+
pipelineString = pipelineString.replaceAll(INLINE_CODE_RETURN_PARAMETER_REGEXP, '-> {$<parameterName>}');
|
|
6324
|
+
return pipelineString;
|
|
6325
|
+
}
|
|
6326
|
+
/**
|
|
6327
|
+
* Validates and removes the optional `#!` shebang line for `.book` files.
|
|
6328
|
+
*
|
|
6329
|
+
* @private internal utility of `parsePipeline`
|
|
6330
|
+
*/
|
|
6331
|
+
function removePipelineShebang(pipelineString, $pipelineJson) {
|
|
6332
|
+
if (!pipelineString.startsWith('#!')) {
|
|
6333
|
+
return pipelineString;
|
|
6334
|
+
}
|
|
6335
|
+
const [shebangLine, ...restLines] = pipelineString.split(/\r?\n/);
|
|
6336
|
+
const isBookShebang = (shebangLine || '').includes('ptbk');
|
|
6337
|
+
if (!isBookShebang) {
|
|
6338
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6339
|
+
It seems that you try to parse a book file which has non-standard shebang line for book files:
|
|
6340
|
+
Shebang line must contain 'ptbk'
|
|
6341
|
+
|
|
6342
|
+
You have:
|
|
6343
|
+
${block(shebangLine || '(empty line)')}
|
|
6344
|
+
|
|
6345
|
+
It should look like this:
|
|
6346
|
+
#!/usr/bin/env ptbk
|
|
6347
|
+
|
|
6348
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6349
|
+
`));
|
|
6350
|
+
}
|
|
6351
|
+
return validatePipelineString(restLines.join('\n'));
|
|
6352
|
+
}
|
|
6353
|
+
/**
|
|
6354
|
+
* Splits the prepared markdown into the pipeline head and task sections.
|
|
6355
|
+
*
|
|
6356
|
+
* @private internal utility of `parsePipeline`
|
|
6357
|
+
*/
|
|
6358
|
+
function parsePreparedPipelineSections(pipelineString, $pipelineJson) {
|
|
6279
6359
|
const [pipelineHead, ...pipelineSections] = splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection); /* <- Note: [🥞] */
|
|
6280
|
-
|
|
6281
|
-
|
|
6360
|
+
assertPipelineSectionsStructure(pipelineHead, pipelineSections, $pipelineJson);
|
|
6361
|
+
return {
|
|
6362
|
+
pipelineHead,
|
|
6363
|
+
pipelineSections,
|
|
6364
|
+
};
|
|
6365
|
+
}
|
|
6366
|
+
/**
|
|
6367
|
+
* Ensures the flattened markdown has exactly one h1 head followed by only h2 sections.
|
|
6368
|
+
*
|
|
6369
|
+
* @private internal utility of `parsePipeline`
|
|
6370
|
+
*/
|
|
6371
|
+
function assertPipelineSectionsStructure(pipelineHead, pipelineSections, $pipelineJson) {
|
|
6282
6372
|
if (pipelineHead === undefined) {
|
|
6283
6373
|
throw new UnexpectedError(spacetrim.spaceTrim((block) => `
|
|
6284
6374
|
Pipeline head is not defined
|
|
6285
6375
|
|
|
6286
|
-
${block(getPipelineIdentification())}
|
|
6376
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6287
6377
|
|
|
6288
6378
|
This should never happen, because the pipeline already flattened
|
|
6289
6379
|
`));
|
|
@@ -6292,337 +6382,463 @@
|
|
|
6292
6382
|
throw new UnexpectedError(spacetrim.spaceTrim((block) => `
|
|
6293
6383
|
Pipeline head is not h1
|
|
6294
6384
|
|
|
6295
|
-
${block(getPipelineIdentification())}
|
|
6385
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6296
6386
|
|
|
6297
6387
|
This should never happen, because the pipeline already flattened
|
|
6298
6388
|
`));
|
|
6299
6389
|
}
|
|
6300
|
-
if (!pipelineSections.every((
|
|
6390
|
+
if (!pipelineSections.every((pipelineSection) => pipelineSection.level === 2)) {
|
|
6301
6391
|
throw new UnexpectedError(spacetrim.spaceTrim((block) => `
|
|
6302
6392
|
Not every pipeline section is h2
|
|
6303
6393
|
|
|
6304
|
-
${block(getPipelineIdentification())}
|
|
6394
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6305
6395
|
|
|
6306
6396
|
This should never happen, because the pipeline already flattened
|
|
6307
6397
|
`));
|
|
6308
6398
|
}
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6399
|
+
}
|
|
6400
|
+
/**
|
|
6401
|
+
* Applies the pipeline head title, description, and head-level commands.
|
|
6402
|
+
*
|
|
6403
|
+
* @private internal utility of `parsePipeline`
|
|
6404
|
+
*/
|
|
6405
|
+
function applyPipelineHead(pipelineHead, $pipelineJson) {
|
|
6406
|
+
$pipelineJson.title = pipelineHead.title;
|
|
6407
|
+
$pipelineJson.description = extractPipelineDescription(pipelineHead.content);
|
|
6408
|
+
for (const listItem of extractAllListItemsFromMarkdown(pipelineHead.content)) {
|
|
6409
|
+
applyPipelineHeadCommand(listItem, $pipelineJson);
|
|
6410
|
+
}
|
|
6411
|
+
}
|
|
6412
|
+
/**
|
|
6413
|
+
* Extracts the plain-text description from a head or task section body.
|
|
6414
|
+
*
|
|
6415
|
+
* @private internal utility of `parsePipeline`
|
|
6416
|
+
*/
|
|
6417
|
+
function extractPipelineDescription(sectionContent) {
|
|
6418
|
+
let description = sectionContent;
|
|
6419
|
+
description = description.split(DESCRIPTION_CODE_BLOCK_REGEXP).join('');
|
|
6420
|
+
description = description.split(DESCRIPTION_BLOCKQUOTE_REGEXP).join('');
|
|
6421
|
+
description = description.split(DESCRIPTION_LIST_ITEM_REGEXP).join('');
|
|
6422
|
+
description = spacetrim.spaceTrim(description);
|
|
6423
|
+
if (description === '') {
|
|
6424
|
+
return undefined;
|
|
6425
|
+
}
|
|
6426
|
+
return description;
|
|
6427
|
+
}
|
|
6428
|
+
/**
|
|
6429
|
+
* Parses and applies one command declared in the pipeline head.
|
|
6430
|
+
*
|
|
6431
|
+
* @private internal utility of `parsePipeline`
|
|
6432
|
+
*/
|
|
6433
|
+
function applyPipelineHeadCommand(listItem, $pipelineJson) {
|
|
6434
|
+
const command = parseCommand(listItem, 'PIPELINE_HEAD');
|
|
6435
|
+
const commandParser = getParserForCommand(command);
|
|
6436
|
+
if (commandParser.isUsedInPipelineHead !== true /* <- Note: [🦦][4] */) {
|
|
6437
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6438
|
+
Command \`${command.type}\` is not allowed in the head of the pipeline ONLY at the pipeline task
|
|
6316
6439
|
|
|
6317
|
-
|
|
6318
|
-
|
|
6440
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6441
|
+
`)); // <- TODO: [🚞]
|
|
6442
|
+
}
|
|
6443
|
+
try {
|
|
6444
|
+
commandParser.$applyToPipelineJson(command, $pipelineJson);
|
|
6445
|
+
// <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitly
|
|
6446
|
+
}
|
|
6447
|
+
catch (error) {
|
|
6448
|
+
if (!(error instanceof ParseError)) {
|
|
6449
|
+
throw error;
|
|
6319
6450
|
}
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
existingParameter.description &&
|
|
6323
|
-
existingParameter.description !== parameterDescription &&
|
|
6324
|
-
parameterDescription) {
|
|
6325
|
-
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6326
|
-
Parameter \`{${parameterName}}\` is defined multiple times with different description:
|
|
6451
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6452
|
+
Command ${command.type} failed to apply to the pipeline
|
|
6327
6453
|
|
|
6328
|
-
|
|
6454
|
+
The error:
|
|
6455
|
+
${block(error.message)}
|
|
6329
6456
|
|
|
6330
|
-
|
|
6331
|
-
|
|
6457
|
+
Raw command:
|
|
6458
|
+
- ${listItem}
|
|
6332
6459
|
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
`));
|
|
6336
|
-
}
|
|
6337
|
-
if (existingParameter) {
|
|
6338
|
-
if (parameterDescription) {
|
|
6339
|
-
existingParameter.description = parameterDescription;
|
|
6340
|
-
}
|
|
6341
|
-
existingParameter.isInput = existingParameter.isInput || isInput;
|
|
6342
|
-
existingParameter.isOutput = existingParameter.isOutput || isOutput;
|
|
6343
|
-
}
|
|
6344
|
-
else {
|
|
6345
|
-
$pipelineJson.parameters.push({
|
|
6346
|
-
name: parameterName,
|
|
6347
|
-
description: parameterDescription || undefined,
|
|
6348
|
-
isInput,
|
|
6349
|
-
isOutput,
|
|
6350
|
-
});
|
|
6351
|
-
}
|
|
6352
|
-
};
|
|
6353
|
-
// =============================================================
|
|
6354
|
-
// Note: 3️⃣ Process pipeline head
|
|
6355
|
-
$pipelineJson.title = pipelineHead.title;
|
|
6356
|
-
// TODO: [🎾][1] DRY description
|
|
6357
|
-
let description = pipelineHead.content;
|
|
6358
|
-
// Note: Remove codeblocks - TODO: [🎾] Make util removeAllBlocksFromMarkdown (exported from `@promptbool/utils`)
|
|
6359
|
-
description = description.split(/^```.*^```/gms).join('');
|
|
6360
|
-
description = description.split(/^>.*$/gm).join('');
|
|
6361
|
-
//Note: Remove lists and return statement - TODO: [🎾] Make util (exported from `@promptbool/utils`)
|
|
6362
|
-
description = description.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
|
|
6363
|
-
description = spacetrim.spaceTrim(description);
|
|
6364
|
-
if (description === '') {
|
|
6365
|
-
description = undefined;
|
|
6366
|
-
}
|
|
6367
|
-
$pipelineJson.description = description;
|
|
6368
|
-
const listItems = extractAllListItemsFromMarkdown(pipelineHead.content);
|
|
6369
|
-
for (const listItem of listItems) {
|
|
6370
|
-
// TODO: [🥥] Maybe move this logic to `$parseAndApplyPipelineHeadCommands`
|
|
6371
|
-
const command = parseCommand(listItem, 'PIPELINE_HEAD');
|
|
6372
|
-
const commandParser = getParserForCommand(command);
|
|
6373
|
-
if (commandParser.isUsedInPipelineHead !== true /* <- Note: [🦦][4] */) {
|
|
6374
|
-
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6375
|
-
Command \`${command.type}\` is not allowed in the head of the pipeline ONLY at the pipeline task
|
|
6460
|
+
Usage of ${command.type}:
|
|
6461
|
+
${block(commandParser.examples.map((example) => `- ${example}`).join('\n'))}
|
|
6376
6462
|
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6463
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6464
|
+
`)); // <- TODO: [🚞]
|
|
6465
|
+
}
|
|
6466
|
+
if (command.type === 'PARAMETER') {
|
|
6467
|
+
defineParameter($pipelineJson, command);
|
|
6468
|
+
// <- Note: [🍣]
|
|
6469
|
+
}
|
|
6470
|
+
}
|
|
6471
|
+
/**
|
|
6472
|
+
* Merges one parameter declaration into the mutable pipeline parameter list.
|
|
6473
|
+
*
|
|
6474
|
+
* @private internal utility of `parsePipeline`
|
|
6475
|
+
*/
|
|
6476
|
+
function defineParameter($pipelineJson, parameterCommand) {
|
|
6477
|
+
const { parameterName, parameterDescription, isInput, isOutput } = parameterCommand;
|
|
6478
|
+
if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
|
|
6479
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6480
|
+
Parameter name {${parameterName}} is reserved and cannot be used as resulting parameter name
|
|
6390
6481
|
|
|
6391
|
-
|
|
6392
|
-
|
|
6482
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6483
|
+
`) /* <- TODO: [🚞] */);
|
|
6484
|
+
}
|
|
6485
|
+
const existingParameter = $pipelineJson.parameters.find((parameter) => parameter.name === parameterName);
|
|
6486
|
+
if (existingParameter &&
|
|
6487
|
+
existingParameter.description &&
|
|
6488
|
+
existingParameter.description !== parameterDescription &&
|
|
6489
|
+
parameterDescription) {
|
|
6490
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6491
|
+
Parameter \`{${parameterName}}\` is defined multiple times with different description:
|
|
6393
6492
|
|
|
6394
|
-
|
|
6395
|
-
- ${listItem}
|
|
6493
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6396
6494
|
|
|
6397
|
-
|
|
6398
|
-
|
|
6495
|
+
First definition:
|
|
6496
|
+
${block(existingParameter.description || '[undefined]')}
|
|
6399
6497
|
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6498
|
+
Second definition:
|
|
6499
|
+
${block(parameterDescription || '[undefined]')}
|
|
6500
|
+
`));
|
|
6501
|
+
}
|
|
6502
|
+
if (existingParameter) {
|
|
6503
|
+
if (parameterDescription) {
|
|
6504
|
+
existingParameter.description = parameterDescription;
|
|
6406
6505
|
}
|
|
6506
|
+
existingParameter.isInput = existingParameter.isInput || isInput;
|
|
6507
|
+
existingParameter.isOutput = existingParameter.isOutput || isOutput;
|
|
6508
|
+
return;
|
|
6407
6509
|
}
|
|
6408
|
-
|
|
6409
|
-
|
|
6510
|
+
$pipelineJson.parameters.push({
|
|
6511
|
+
name: parameterName,
|
|
6512
|
+
description: parameterDescription || undefined,
|
|
6513
|
+
isInput,
|
|
6514
|
+
isOutput,
|
|
6515
|
+
});
|
|
6516
|
+
}
|
|
6517
|
+
/**
|
|
6518
|
+
* Creates stable unique task names for duplicate section titles.
|
|
6519
|
+
*
|
|
6520
|
+
* @private internal utility of `parsePipeline`
|
|
6521
|
+
*/
|
|
6522
|
+
function createUniqueSectionNameResolver(pipelineSections) {
|
|
6410
6523
|
const sectionCounts = {};
|
|
6411
|
-
for (const
|
|
6412
|
-
const
|
|
6413
|
-
if (sectionCounts[
|
|
6414
|
-
sectionCounts[
|
|
6524
|
+
for (const pipelineSection of pipelineSections) {
|
|
6525
|
+
const sectionName = titleToName(pipelineSection.title);
|
|
6526
|
+
if (sectionCounts[sectionName] === undefined) {
|
|
6527
|
+
sectionCounts[sectionName] = { count: 0, currentIndex: 0 };
|
|
6415
6528
|
}
|
|
6416
|
-
sectionCounts[
|
|
6529
|
+
sectionCounts[sectionName].count++;
|
|
6417
6530
|
}
|
|
6418
|
-
|
|
6419
|
-
const
|
|
6420
|
-
const
|
|
6421
|
-
if (
|
|
6422
|
-
return
|
|
6531
|
+
return (title) => {
|
|
6532
|
+
const sectionName = titleToName(title);
|
|
6533
|
+
const sectionCount = sectionCounts[sectionName];
|
|
6534
|
+
if (sectionCount.count === 1) {
|
|
6535
|
+
return sectionName;
|
|
6423
6536
|
}
|
|
6424
|
-
const nameWithSuffix = `${
|
|
6425
|
-
|
|
6537
|
+
const nameWithSuffix = `${sectionName}-${sectionCount.currentIndex}`;
|
|
6538
|
+
sectionCount.currentIndex++;
|
|
6426
6539
|
return nameWithSuffix;
|
|
6427
6540
|
};
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
// TODO: [
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6541
|
+
}
|
|
6542
|
+
/**
|
|
6543
|
+
* Parses, applies, and persists one h2 task section.
|
|
6544
|
+
*
|
|
6545
|
+
* @private internal utility of `parsePipeline`
|
|
6546
|
+
*/
|
|
6547
|
+
function processPipelineSection(pipelineSection, $pipelineJson, getUniqueSectionName) {
|
|
6548
|
+
const { $taskJson, language } = createTaskJsonFromSection(pipelineSection, getUniqueSectionName);
|
|
6549
|
+
const commands = parsePipelineTaskCommands(pipelineSection.content);
|
|
6550
|
+
applyDefaultTaskSectionType($taskJson, commands, $pipelineJson);
|
|
6551
|
+
for (const commandItem of commands) {
|
|
6552
|
+
applyPipelineTaskCommand(commandItem, $taskJson, $pipelineJson);
|
|
6553
|
+
}
|
|
6554
|
+
applyScriptTaskLanguage($taskJson, language, $pipelineJson);
|
|
6555
|
+
registerTaskDependentParameters($taskJson, $pipelineJson);
|
|
6556
|
+
persistTaskIfNeeded($taskJson, $pipelineJson);
|
|
6557
|
+
}
|
|
6558
|
+
/**
|
|
6559
|
+
* Creates the mutable task JSON shell from one markdown section.
|
|
6560
|
+
*
|
|
6561
|
+
* @private internal utility of `parsePipeline`
|
|
6562
|
+
*/
|
|
6563
|
+
function createTaskJsonFromSection(pipelineSection, getUniqueSectionName) {
|
|
6564
|
+
const { language, content } = extractOneBlockFromMarkdown(pipelineSection.content);
|
|
6565
|
+
const normalizedLanguage = language || undefined;
|
|
6566
|
+
const title = pipelineSection.title || DEFAULT_TASK_TITLE;
|
|
6567
|
+
const $taskJson = {
|
|
6568
|
+
isSectionTypeSet: false,
|
|
6569
|
+
isTask: true,
|
|
6570
|
+
taskType: undefined /* <- Note: [🍙] Putting here placeholder to keep `taskType` on top at final JSON */,
|
|
6571
|
+
name: getUniqueSectionName(title),
|
|
6572
|
+
title,
|
|
6573
|
+
description: extractPipelineDescription(pipelineSection.content),
|
|
6574
|
+
content,
|
|
6575
|
+
// <- TODO: [🍙] Some standard order of properties
|
|
6576
|
+
};
|
|
6577
|
+
const resultingParameterName = extractResultingParameterName(pipelineSection.content);
|
|
6578
|
+
if (resultingParameterName !== undefined) {
|
|
6579
|
+
$taskJson.resultingParameterName = resultingParameterName;
|
|
6580
|
+
}
|
|
6581
|
+
return {
|
|
6582
|
+
$taskJson,
|
|
6583
|
+
language: normalizedLanguage,
|
|
6584
|
+
};
|
|
6585
|
+
}
|
|
6586
|
+
/**
|
|
6587
|
+
* Extracts the optional trailing `-> {parameter}` statement from a section body.
|
|
6588
|
+
*
|
|
6589
|
+
* @private internal utility of `parsePipeline`
|
|
6590
|
+
*/
|
|
6591
|
+
function extractResultingParameterName(sectionContent) {
|
|
6592
|
+
var _a;
|
|
6593
|
+
const lastLine = sectionContent.split(/\r?\n/).pop();
|
|
6594
|
+
const resultingParameterNameMatch = RESULTING_PARAMETER_LINE_REGEXP.exec(lastLine);
|
|
6595
|
+
return (_a = resultingParameterNameMatch === null || resultingParameterNameMatch === void 0 ? void 0 : resultingParameterNameMatch.groups) === null || _a === void 0 ? void 0 : _a.resultingParamName;
|
|
6596
|
+
}
|
|
6597
|
+
/**
|
|
6598
|
+
* Parses all list-item commands declared inside one task section.
|
|
6599
|
+
*
|
|
6600
|
+
* @private internal utility of `parsePipeline`
|
|
6601
|
+
*/
|
|
6602
|
+
function parsePipelineTaskCommands(sectionContent) {
|
|
6603
|
+
return extractAllListItemsFromMarkdown(sectionContent).map((listItem) => ({
|
|
6604
|
+
listItem,
|
|
6605
|
+
command: parseCommand(listItem, 'PIPELINE_TASK'),
|
|
6606
|
+
}));
|
|
6607
|
+
}
|
|
6608
|
+
/**
|
|
6609
|
+
* Applies the implicit default `PROMPT_TASK` section type when no SECTION command is present.
|
|
6610
|
+
*
|
|
6611
|
+
* @private internal utility of `parsePipeline`
|
|
6612
|
+
*/
|
|
6613
|
+
function applyDefaultTaskSectionType($taskJson, commands, $pipelineJson) {
|
|
6614
|
+
const isSectionCommandPresent = commands.some(({ command }) => command.type === 'SECTION');
|
|
6615
|
+
if (isSectionCommandPresent) {
|
|
6616
|
+
return;
|
|
6617
|
+
}
|
|
6618
|
+
sectionCommandParser.$applyToTaskJson({ type: 'SECTION', taskType: 'PROMPT_TASK' }, $taskJson, $pipelineJson);
|
|
6619
|
+
}
|
|
6620
|
+
/**
|
|
6621
|
+
* Parses and applies one command declared inside a task section.
|
|
6622
|
+
*
|
|
6623
|
+
* @private internal utility of `parsePipeline`
|
|
6624
|
+
*/
|
|
6625
|
+
function applyPipelineTaskCommand(commandItem, $taskJson, $pipelineJson) {
|
|
6626
|
+
const { listItem, command } = commandItem;
|
|
6627
|
+
const commandParser = getParserForCommand(command);
|
|
6628
|
+
if (commandParser.isUsedInPipelineTask !== true /* <- Note: [🦦][4] */) {
|
|
6629
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6630
|
+
Command \`${command.type}\` is not allowed in the task of the promptbook ONLY at the pipeline head
|
|
6495
6631
|
|
|
6496
|
-
|
|
6497
|
-
|
|
6632
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6633
|
+
`)); // <- TODO: [🚞]
|
|
6634
|
+
}
|
|
6635
|
+
try {
|
|
6636
|
+
commandParser.$applyToTaskJson(command, $taskJson, $pipelineJson);
|
|
6637
|
+
// <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitly
|
|
6638
|
+
}
|
|
6639
|
+
catch (error) {
|
|
6640
|
+
if (!(error instanceof ParseError)) {
|
|
6641
|
+
throw error;
|
|
6642
|
+
}
|
|
6643
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6644
|
+
Command \`${command.type}\` failed to apply to the task
|
|
6498
6645
|
|
|
6499
|
-
|
|
6500
|
-
|
|
6646
|
+
The error:
|
|
6647
|
+
${block(error.message)}
|
|
6501
6648
|
|
|
6502
|
-
|
|
6649
|
+
Current state of the task:
|
|
6650
|
+
${block(JSON.stringify($taskJson, null, 4))}
|
|
6503
6651
|
|
|
6504
|
-
|
|
6505
|
-
|
|
6652
|
+
Command that failed to apply:
|
|
6653
|
+
${block(JSON.stringify(command, null, 4))}
|
|
6506
6654
|
|
|
6507
|
-
|
|
6508
|
-
${block(commandParser.examples.map((example) => `- ${example}`).join('\n'))}
|
|
6655
|
+
*<- Maybe wrong order of commands in section?*
|
|
6509
6656
|
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
}
|
|
6513
|
-
if (command.type === 'PARAMETER') {
|
|
6514
|
-
defineParam(command);
|
|
6515
|
-
// <- Note: [🍣]
|
|
6516
|
-
}
|
|
6517
|
-
}
|
|
6518
|
-
// TODO: [🍧] Should be done in SECTION command
|
|
6519
|
-
if ($taskJson.taskType === 'SCRIPT_TASK') {
|
|
6520
|
-
if (!language) {
|
|
6521
|
-
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6522
|
-
You must specify the language of the script in the \`SCRIPT\` task
|
|
6657
|
+
Raw command:
|
|
6658
|
+
- ${listItem}
|
|
6523
6659
|
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
}
|
|
6527
|
-
if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
|
|
6528
|
-
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6529
|
-
Script language ${language} is not supported.
|
|
6660
|
+
Usage of ${command.type}:
|
|
6661
|
+
${block(commandParser.examples.map((example) => `- ${example}`).join('\n'))}
|
|
6530
6662
|
|
|
6531
|
-
|
|
6532
|
-
|
|
6663
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6664
|
+
`)); // <- TODO: [🚞]
|
|
6665
|
+
}
|
|
6666
|
+
if (command.type === 'PARAMETER') {
|
|
6667
|
+
defineParameter($pipelineJson, command);
|
|
6668
|
+
// <- Note: [🍣]
|
|
6669
|
+
}
|
|
6670
|
+
}
|
|
6671
|
+
/**
|
|
6672
|
+
* Validates and stores the language for SCRIPT tasks.
|
|
6673
|
+
*
|
|
6674
|
+
* @private internal utility of `parsePipeline`
|
|
6675
|
+
*/
|
|
6676
|
+
function applyScriptTaskLanguage($taskJson, language, $pipelineJson) {
|
|
6677
|
+
const isScriptTask = $taskJson.taskType === 'SCRIPT_TASK';
|
|
6678
|
+
if (!isScriptTask) {
|
|
6679
|
+
return;
|
|
6680
|
+
}
|
|
6681
|
+
if (!language) {
|
|
6682
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6683
|
+
You must specify the language of the script in the \`SCRIPT\` task
|
|
6533
6684
|
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
// TODO: [🧠] This definition should be made first in the task
|
|
6541
|
-
defineParam({
|
|
6542
|
-
parameterName,
|
|
6543
|
-
parameterDescription: null,
|
|
6544
|
-
isInput: false,
|
|
6545
|
-
isOutput: false,
|
|
6546
|
-
// <- Note: In this case null+false+false means that we do not know yet if it is input or output and we will set it later
|
|
6547
|
-
});
|
|
6548
|
-
}
|
|
6549
|
-
/*
|
|
6550
|
-
// TODO: [🍧] This should be checked in `MODEL` command + better error message
|
|
6551
|
-
if ($taskJson.taskType !== 'PROMPT_TASK' && $taskJson.modelRequirements !== undefined) {
|
|
6552
|
-
throw new UnexpectedError(
|
|
6553
|
-
spaceTrim(
|
|
6554
|
-
(block) => `
|
|
6555
|
-
Model requirements are defined for the block type ${
|
|
6556
|
-
$taskJson.taskType
|
|
6557
|
-
} which is not a \`PROMPT\` task
|
|
6685
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6686
|
+
`));
|
|
6687
|
+
}
|
|
6688
|
+
if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
|
|
6689
|
+
throw new ParseError(spacetrim.spaceTrim((block) => `
|
|
6690
|
+
Script language ${language} is not supported.
|
|
6558
6691
|
|
|
6559
|
-
|
|
6692
|
+
Supported languages are:
|
|
6693
|
+
${block(SUPPORTED_SCRIPT_LANGUAGES.join(', '))}
|
|
6560
6694
|
|
|
6561
|
-
|
|
6562
|
-
`,
|
|
6563
|
-
),
|
|
6564
|
-
);
|
|
6565
|
-
}
|
|
6566
|
-
*/
|
|
6567
|
-
if ($taskJson.isTask) {
|
|
6568
|
-
delete $taskJson.isSectionTypeSet;
|
|
6569
|
-
delete $taskJson.isTask;
|
|
6570
|
-
// TODO: [🍙] Maybe do reorder of `$taskJson` here
|
|
6571
|
-
$pipelineJson.tasks.push($taskJson);
|
|
6572
|
-
}
|
|
6573
|
-
}
|
|
6574
|
-
// =============================================================
|
|
6575
|
-
// Note: 6️⃣ Mark parameters as INPUT if not explicitly set
|
|
6576
|
-
if ($pipelineJson.parameters.every((parameter) => !parameter.isInput)) {
|
|
6577
|
-
for (const parameter of $pipelineJson.parameters) {
|
|
6578
|
-
const isThisParameterResulting = $pipelineJson.tasks.some((task) => task.resultingParameterName === parameter.name);
|
|
6579
|
-
if (!isThisParameterResulting) {
|
|
6580
|
-
parameter.isInput = true;
|
|
6581
|
-
// <- TODO: [💔] Why this is making typescript error in vscode but not in cli
|
|
6582
|
-
// > Type 'true' is not assignable to type 'false'.ts(2322)
|
|
6583
|
-
// > (property) isInput: false
|
|
6584
|
-
// > The parameter is input of the pipeline The parameter is NOT input of the pipeline
|
|
6585
|
-
}
|
|
6586
|
-
}
|
|
6695
|
+
`));
|
|
6587
6696
|
}
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6697
|
+
$taskJson.contentLanguage = language;
|
|
6698
|
+
}
|
|
6699
|
+
/**
|
|
6700
|
+
* Extracts task dependencies and ensures referenced parameters exist.
|
|
6701
|
+
*
|
|
6702
|
+
* @private internal utility of `parsePipeline`
|
|
6703
|
+
*/
|
|
6704
|
+
function registerTaskDependentParameters($taskJson, $pipelineJson) {
|
|
6705
|
+
$taskJson.dependentParameterNames = Array.from(extractParameterNamesFromTask($taskJson));
|
|
6706
|
+
for (const parameterName of $taskJson.dependentParameterNames) {
|
|
6707
|
+
// TODO: [🧠] This definition should be made first in the task
|
|
6708
|
+
defineParameter($pipelineJson, {
|
|
6709
|
+
parameterName,
|
|
6710
|
+
parameterDescription: null,
|
|
6711
|
+
isInput: false,
|
|
6712
|
+
isOutput: false,
|
|
6713
|
+
// <- Note: In this case null+false+false means that we do not know yet if it is input or output and we will set it later
|
|
6714
|
+
});
|
|
6715
|
+
}
|
|
6716
|
+
}
|
|
6717
|
+
/**
|
|
6718
|
+
* Removes transient parsing flags and persists real tasks into the pipeline JSON.
|
|
6719
|
+
*
|
|
6720
|
+
* @private internal utility of `parsePipeline`
|
|
6721
|
+
*/
|
|
6722
|
+
function persistTaskIfNeeded($taskJson, $pipelineJson) {
|
|
6723
|
+
/*
|
|
6724
|
+
// TODO: [🍧] This should be checked in `MODEL` command + better error message
|
|
6725
|
+
if ($taskJson.taskType !== 'PROMPT_TASK' && $taskJson.modelRequirements !== undefined) {
|
|
6726
|
+
throw new UnexpectedError(
|
|
6727
|
+
spaceTrim(
|
|
6728
|
+
(block) => `
|
|
6729
|
+
Model requirements are defined for the block type ${
|
|
6730
|
+
$taskJson.taskType
|
|
6731
|
+
} which is not a \`PROMPT\` task
|
|
6732
|
+
|
|
6733
|
+
This should be avoided by the \`modelCommandParser\`
|
|
6734
|
+
|
|
6735
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
6736
|
+
`,
|
|
6737
|
+
),
|
|
6738
|
+
);
|
|
6739
|
+
}
|
|
6740
|
+
*/
|
|
6741
|
+
if (!$taskJson.isTask) {
|
|
6742
|
+
return;
|
|
6743
|
+
}
|
|
6744
|
+
delete $taskJson.isSectionTypeSet;
|
|
6745
|
+
delete $taskJson.isTask;
|
|
6746
|
+
// TODO: [🍙] Maybe do reorder of `$taskJson` here
|
|
6747
|
+
$pipelineJson.tasks.push($taskJson);
|
|
6748
|
+
}
|
|
6749
|
+
/**
|
|
6750
|
+
* Applies default INPUT/OUTPUT flags when the author did not specify them explicitly.
|
|
6751
|
+
*
|
|
6752
|
+
* @private internal utility of `parsePipeline`
|
|
6753
|
+
*/
|
|
6754
|
+
function applyImplicitParameterDirections($pipelineJson) {
|
|
6755
|
+
markImplicitInputParameters($pipelineJson);
|
|
6756
|
+
markImplicitOutputParameters($pipelineJson);
|
|
6757
|
+
}
|
|
6758
|
+
/**
|
|
6759
|
+
* Marks non-result parameters as pipeline inputs when no input was declared.
|
|
6760
|
+
*
|
|
6761
|
+
* @private internal utility of `parsePipeline`
|
|
6762
|
+
*/
|
|
6763
|
+
function markImplicitInputParameters($pipelineJson) {
|
|
6764
|
+
if ($pipelineJson.parameters.some((parameter) => parameter.isInput)) {
|
|
6765
|
+
return;
|
|
6766
|
+
}
|
|
6767
|
+
for (const parameter of $pipelineJson.parameters) {
|
|
6768
|
+
const isThisParameterResulting = $pipelineJson.tasks.some((task) => task.resultingParameterName === parameter.name);
|
|
6769
|
+
if (!isThisParameterResulting) {
|
|
6770
|
+
parameter.isInput = true;
|
|
6771
|
+
// <- TODO: [💔] Why this is making typescript error in vscode but not in cli
|
|
6772
|
+
// > Type 'true' is not assignable to type 'false'.ts(2322)
|
|
6773
|
+
// > (property) isInput: false
|
|
6774
|
+
// > The parameter is input of the pipeline The parameter is NOT input of the pipeline
|
|
6596
6775
|
}
|
|
6597
6776
|
}
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6777
|
+
}
|
|
6778
|
+
/**
|
|
6779
|
+
* Marks every non-input parameter as output when no output was declared.
|
|
6780
|
+
*
|
|
6781
|
+
* @private internal utility of `parsePipeline`
|
|
6782
|
+
*/
|
|
6783
|
+
function markImplicitOutputParameters($pipelineJson) {
|
|
6784
|
+
if ($pipelineJson.parameters.some((parameter) => parameter.isOutput)) {
|
|
6785
|
+
return;
|
|
6786
|
+
}
|
|
6787
|
+
for (const parameter of $pipelineJson.parameters) {
|
|
6788
|
+
if (!parameter.isInput) {
|
|
6789
|
+
parameter.isOutput = true;
|
|
6790
|
+
// <- TODO: [💔]
|
|
6605
6791
|
}
|
|
6606
|
-
}
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6792
|
+
}
|
|
6793
|
+
}
|
|
6794
|
+
/**
|
|
6795
|
+
* Removes `undefined` properties from serialized tasks and parameters.
|
|
6796
|
+
*
|
|
6797
|
+
* @private internal utility of `parsePipeline`
|
|
6798
|
+
*/
|
|
6799
|
+
function removeUndefinedValuesFromPipeline($pipelineJson) {
|
|
6800
|
+
$pipelineJson.tasks.forEach(removeUndefinedProperties);
|
|
6801
|
+
$pipelineJson.parameters.forEach(removeUndefinedProperties);
|
|
6802
|
+
}
|
|
6803
|
+
/**
|
|
6804
|
+
* Deletes all own properties with `undefined` values from a mutable JSON entity.
|
|
6805
|
+
*
|
|
6806
|
+
* @private internal utility of `parsePipeline`
|
|
6807
|
+
*/
|
|
6808
|
+
function removeUndefinedProperties(entity) {
|
|
6809
|
+
for (const [key, value] of Object.entries(entity)) {
|
|
6810
|
+
if (value === undefined) {
|
|
6811
|
+
delete entity[key];
|
|
6612
6812
|
}
|
|
6613
|
-
}
|
|
6614
|
-
|
|
6615
|
-
|
|
6813
|
+
}
|
|
6814
|
+
}
|
|
6815
|
+
/**
|
|
6816
|
+
* Applies all sync-only high-level abstractions after parsing.
|
|
6817
|
+
*
|
|
6818
|
+
* @private internal utility of `parsePipeline`
|
|
6819
|
+
*/
|
|
6820
|
+
function applySyncHighLevelAbstractions($pipelineJson) {
|
|
6616
6821
|
for (const highLevelAbstraction of HIGH_LEVEL_ABSTRACTIONS.filter(({ type }) => type === 'SYNC')) {
|
|
6617
6822
|
highLevelAbstraction.$applyToPipelineJson($pipelineJson);
|
|
6618
6823
|
}
|
|
6619
|
-
|
|
6620
|
-
|
|
6824
|
+
}
|
|
6825
|
+
/**
|
|
6826
|
+
* Ensures parsed pipelines always have the default `GENERIC` formfactor.
|
|
6827
|
+
*
|
|
6828
|
+
* @private internal utility of `parsePipeline`
|
|
6829
|
+
*/
|
|
6830
|
+
function ensurePipelineFormfactor($pipelineJson) {
|
|
6621
6831
|
// Note: [🔆] If formfactor is still not set, set it to 'GENERIC'
|
|
6622
6832
|
if ($pipelineJson.formfactorName === undefined) {
|
|
6623
6833
|
$pipelineJson.formfactorName = 'GENERIC';
|
|
6624
6834
|
}
|
|
6625
|
-
|
|
6835
|
+
}
|
|
6836
|
+
/**
|
|
6837
|
+
* Finalizes ordering and exports the parsed pipeline JSON.
|
|
6838
|
+
*
|
|
6839
|
+
* @private internal utility of `parsePipeline`
|
|
6840
|
+
*/
|
|
6841
|
+
function exportParsedPipelineJson($pipelineJson) {
|
|
6626
6842
|
return exportJson({
|
|
6627
6843
|
name: 'pipelineJson',
|
|
6628
6844
|
message: `Result of \`parsePipeline\``,
|