@promptbook/wizard 0.112.0-70 → 0.112.0-72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/index.es.js +1085 -954
- package/esm/index.es.js.map +1 -1
- package/esm/src/book-3.0/Book.d.ts +6 -0
- package/esm/src/book-components/Chat/utils/getToolCallChipletInfo.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agent/agentRunCliOptions.d.ts +12 -2
- package/esm/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -0
- package/esm/src/cli/cli-commands/run/prepareRunCommandResources.d.ts +20 -0
- package/esm/src/cli/cli-commands/run/resolveRunInputParameters.d.ts +12 -0
- package/esm/src/cli/cli-commands/run/runCommandAction.d.ts +21 -0
- package/esm/src/cli/cli-commands/run/runPipelineExecution.d.ts +14 -0
- package/esm/src/cli/cli-commands/run.d.ts +1 -1
- package/esm/src/conversion/parsePipeline/applyPipelineHead.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/createInitialPipelineJson.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/createUniqueSectionNameResolver.d.ts +14 -0
- package/esm/src/conversion/parsePipeline/defineParameter.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/extractPipelineDescription.d.ts +6 -0
- package/esm/src/conversion/parsePipeline/finalizeParsedPipeline.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/getPipelineIdentification.d.ts +7 -0
- package/esm/src/conversion/parsePipeline/parsePreparedPipelineSections.d.ts +18 -0
- package/esm/src/conversion/parsePipeline/preparePipelineString.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/processPipelineSection.d.ts +9 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +1085 -954
- package/umd/index.umd.js.map +1 -1
- package/umd/src/book-3.0/Book.d.ts +6 -0
- package/umd/src/book-components/Chat/utils/getToolCallChipletInfo.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agent/agentRunCliOptions.d.ts +12 -2
- package/umd/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -0
- package/umd/src/cli/cli-commands/run/prepareRunCommandResources.d.ts +20 -0
- package/umd/src/cli/cli-commands/run/resolveRunInputParameters.d.ts +12 -0
- package/umd/src/cli/cli-commands/run/runCommandAction.d.ts +21 -0
- package/umd/src/cli/cli-commands/run/runPipelineExecution.d.ts +14 -0
- package/umd/src/cli/cli-commands/run.d.ts +1 -1
- package/umd/src/conversion/parsePipeline/applyPipelineHead.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/createInitialPipelineJson.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/createUniqueSectionNameResolver.d.ts +14 -0
- package/umd/src/conversion/parsePipeline/defineParameter.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/extractPipelineDescription.d.ts +6 -0
- package/umd/src/conversion/parsePipeline/finalizeParsedPipeline.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/getPipelineIdentification.d.ts +7 -0
- package/umd/src/conversion/parsePipeline/parsePreparedPipelineSections.d.ts +18 -0
- package/umd/src/conversion/parsePipeline/preparePipelineString.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/processPipelineSection.d.ts +9 -0
- package/umd/src/version.d.ts +1 -1
package/esm/index.es.js
CHANGED
|
@@ -38,7 +38,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
38
38
|
* @generated
|
|
39
39
|
* @see https://github.com/webgptorg/promptbook
|
|
40
40
|
*/
|
|
41
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
41
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-72';
|
|
42
42
|
/**
|
|
43
43
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
44
44
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -22859,7 +22859,9 @@ const octopus3dAvatarVisual = {
|
|
|
22859
22859
|
};
|
|
22860
22860
|
const mantleRadiusX = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch;
|
|
22861
22861
|
const mantleRadiusY = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.1;
|
|
22862
|
-
const mantleRadiusZ = size *
|
|
22862
|
+
const mantleRadiusZ = size *
|
|
22863
|
+
morphologyProfile.body.bodyRadiusRatio *
|
|
22864
|
+
(0.9 + (morphologyProfile.body.horizontalStretch - 1) * 0.3);
|
|
22863
22865
|
const underbodyRadiusX = mantleRadiusX * (0.9 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.08);
|
|
22864
22866
|
const underbodyRadiusY = mantleRadiusY * (0.44 + morphologyProfile.body.lowerDropRatio * 3.1);
|
|
22865
22867
|
const underbodyRadiusZ = mantleRadiusZ * 0.78;
|
|
@@ -22945,7 +22947,11 @@ const octopus3dAvatarVisual = {
|
|
|
22945
22947
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
22946
22948
|
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
|
|
22947
22949
|
drawProjectedMouth(context, [
|
|
22948
|
-
{
|
|
22950
|
+
{
|
|
22951
|
+
x: -mouthHalfWidth,
|
|
22952
|
+
y: mouthY,
|
|
22953
|
+
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -mouthHalfWidth, mouthY),
|
|
22954
|
+
},
|
|
22949
22955
|
{
|
|
22950
22956
|
x: size * morphologyProfile.face.mouthCenterOffsetRatio,
|
|
22951
22957
|
y: mouthY +
|
|
@@ -22954,7 +22960,11 @@ const octopus3dAvatarVisual = {
|
|
|
22954
22960
|
interaction.gazeY * size * 0.01,
|
|
22955
22961
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, size * morphologyProfile.face.mouthCenterOffsetRatio, mouthY),
|
|
22956
22962
|
},
|
|
22957
|
-
{
|
|
22963
|
+
{
|
|
22964
|
+
x: mouthHalfWidth,
|
|
22965
|
+
y: mouthY,
|
|
22966
|
+
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, mouthHalfWidth, mouthY),
|
|
22967
|
+
},
|
|
22958
22968
|
], mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, palette, size);
|
|
22959
22969
|
},
|
|
22960
22970
|
};
|
|
@@ -23115,7 +23125,8 @@ function createOctopusTentacleStrokes(options) {
|
|
|
23115
23125
|
z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.3 + sway * size * 0.012,
|
|
23116
23126
|
};
|
|
23117
23127
|
const controlPointTwo = {
|
|
23118
|
-
x: anchorPoint.x +
|
|
23128
|
+
x: anchorPoint.x +
|
|
23129
|
+
Math.sin(orbitAngle) * lateralReach * (0.82 + morphologyProfile.tentacles.swayScale * 0.12),
|
|
23119
23130
|
y: anchorPoint.y + flowLength * 0.66,
|
|
23120
23131
|
z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.72 + sway * size * 0.02,
|
|
23121
23132
|
};
|
|
@@ -23180,8 +23191,7 @@ function drawTentacleStroke(context, tentacleStroke, palette) {
|
|
|
23180
23191
|
context.beginPath();
|
|
23181
23192
|
context.moveTo(startPoint.x, startPoint.y);
|
|
23182
23193
|
context.lineTo(endPoint.x, endPoint.y);
|
|
23183
|
-
context.strokeStyle =
|
|
23184
|
-
tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
|
|
23194
|
+
context.strokeStyle = tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
|
|
23185
23195
|
context.lineWidth = width;
|
|
23186
23196
|
context.lineCap = 'round';
|
|
23187
23197
|
context.stroke();
|
|
@@ -31166,6 +31176,212 @@ const DEFAULT_LIST_TIMEOUTS_LIMIT = 20;
|
|
|
31166
31176
|
* @private internal USE TIMEOUT constant
|
|
31167
31177
|
*/
|
|
31168
31178
|
const MAX_LIST_TIMEOUTS_LIMIT = 100;
|
|
31179
|
+
/**
|
|
31180
|
+
* Creates one formatted timeout-argument validation error.
|
|
31181
|
+
*
|
|
31182
|
+
* @private internal utility of USE TIMEOUT
|
|
31183
|
+
*/
|
|
31184
|
+
function createTimeoutToolArgsError(message) {
|
|
31185
|
+
return new PipelineExecutionError(spaceTrim$1(`
|
|
31186
|
+
${message}
|
|
31187
|
+
`));
|
|
31188
|
+
}
|
|
31189
|
+
/**
|
|
31190
|
+
* Normalizes one optional timeout id string.
|
|
31191
|
+
*
|
|
31192
|
+
* @private internal utility of USE TIMEOUT
|
|
31193
|
+
*/
|
|
31194
|
+
function normalizeOptionalTimeoutId(value) {
|
|
31195
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
31196
|
+
}
|
|
31197
|
+
/**
|
|
31198
|
+
* Parses timeout target selection for tools that accept either `timeoutId` or `allActive: true`.
|
|
31199
|
+
*
|
|
31200
|
+
* @private internal utility of USE TIMEOUT
|
|
31201
|
+
*/
|
|
31202
|
+
function parseTimeoutTargetSelection(args, options) {
|
|
31203
|
+
const timeoutId = normalizeOptionalTimeoutId(args.timeoutId);
|
|
31204
|
+
const allActive = args.allActive === true;
|
|
31205
|
+
if (timeoutId && allActive) {
|
|
31206
|
+
throw createTimeoutToolArgsError(options.bothMessage);
|
|
31207
|
+
}
|
|
31208
|
+
if (allActive) {
|
|
31209
|
+
return { allActive: true };
|
|
31210
|
+
}
|
|
31211
|
+
if (!timeoutId) {
|
|
31212
|
+
throw createTimeoutToolArgsError(options.missingMessage);
|
|
31213
|
+
}
|
|
31214
|
+
return {
|
|
31215
|
+
timeoutId,
|
|
31216
|
+
allActive: false,
|
|
31217
|
+
};
|
|
31218
|
+
}
|
|
31219
|
+
/**
|
|
31220
|
+
* Parses one explicit `dueAt` update value.
|
|
31221
|
+
*
|
|
31222
|
+
* @private internal utility of USE TIMEOUT
|
|
31223
|
+
*/
|
|
31224
|
+
function parseOptionalTimeoutDueAt(value) {
|
|
31225
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
31226
|
+
return undefined;
|
|
31227
|
+
}
|
|
31228
|
+
const normalizedDueAt = value.trim();
|
|
31229
|
+
const dueAtTimestamp = Date.parse(normalizedDueAt);
|
|
31230
|
+
if (!Number.isFinite(dueAtTimestamp)) {
|
|
31231
|
+
throw createTimeoutToolArgsError('Timeout `dueAt` must be one valid ISO timestamp.');
|
|
31232
|
+
}
|
|
31233
|
+
return new Date(dueAtTimestamp).toISOString();
|
|
31234
|
+
}
|
|
31235
|
+
/**
|
|
31236
|
+
* Parses one explicit `extendByMs` update value.
|
|
31237
|
+
*
|
|
31238
|
+
* @private internal utility of USE TIMEOUT
|
|
31239
|
+
*/
|
|
31240
|
+
function parseOptionalTimeoutExtendByMs(value) {
|
|
31241
|
+
if (typeof value !== 'number') {
|
|
31242
|
+
return undefined;
|
|
31243
|
+
}
|
|
31244
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
31245
|
+
throw createTimeoutToolArgsError('Timeout `extendByMs` must be a positive number of milliseconds.');
|
|
31246
|
+
}
|
|
31247
|
+
return Math.floor(value);
|
|
31248
|
+
}
|
|
31249
|
+
/**
|
|
31250
|
+
* Parses one explicit `recurrenceIntervalMs` update value.
|
|
31251
|
+
*
|
|
31252
|
+
* @private internal utility of USE TIMEOUT
|
|
31253
|
+
*/
|
|
31254
|
+
function parseOptionalTimeoutRecurrenceInterval(value) {
|
|
31255
|
+
if (value === null) {
|
|
31256
|
+
return null;
|
|
31257
|
+
}
|
|
31258
|
+
if (typeof value !== 'number') {
|
|
31259
|
+
return undefined;
|
|
31260
|
+
}
|
|
31261
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
31262
|
+
throw createTimeoutToolArgsError('Timeout `recurrenceIntervalMs` must be a positive number of milliseconds or `null`.');
|
|
31263
|
+
}
|
|
31264
|
+
return Math.floor(value);
|
|
31265
|
+
}
|
|
31266
|
+
/**
|
|
31267
|
+
* Parses one explicit `message` update value.
|
|
31268
|
+
*
|
|
31269
|
+
* @private internal utility of USE TIMEOUT
|
|
31270
|
+
*/
|
|
31271
|
+
function parseOptionalTimeoutMessage(value) {
|
|
31272
|
+
if (value === null) {
|
|
31273
|
+
return null;
|
|
31274
|
+
}
|
|
31275
|
+
if (typeof value !== 'string') {
|
|
31276
|
+
return undefined;
|
|
31277
|
+
}
|
|
31278
|
+
const normalizedMessage = value.trim();
|
|
31279
|
+
return normalizedMessage.length > 0 ? normalizedMessage : null;
|
|
31280
|
+
}
|
|
31281
|
+
/**
|
|
31282
|
+
* Parses one explicit `parameters` update value.
|
|
31283
|
+
*
|
|
31284
|
+
* @private internal utility of USE TIMEOUT
|
|
31285
|
+
*/
|
|
31286
|
+
function parseOptionalTimeoutParameters(value) {
|
|
31287
|
+
if (value === undefined) {
|
|
31288
|
+
return undefined;
|
|
31289
|
+
}
|
|
31290
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
31291
|
+
throw createTimeoutToolArgsError('Timeout `parameters` must be one JSON object.');
|
|
31292
|
+
}
|
|
31293
|
+
return value;
|
|
31294
|
+
}
|
|
31295
|
+
/**
|
|
31296
|
+
* Parses one explicit `paused` update value.
|
|
31297
|
+
*
|
|
31298
|
+
* @private internal utility of USE TIMEOUT
|
|
31299
|
+
*/
|
|
31300
|
+
function parseOptionalTimeoutPaused(value) {
|
|
31301
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
31302
|
+
}
|
|
31303
|
+
/**
|
|
31304
|
+
* Parses patch fields for `update_timeout`.
|
|
31305
|
+
*
|
|
31306
|
+
* @private internal utility of USE TIMEOUT
|
|
31307
|
+
*/
|
|
31308
|
+
function parseTimeoutUpdatePatch(args) {
|
|
31309
|
+
const patch = {};
|
|
31310
|
+
const dueAt = parseOptionalTimeoutDueAt(args.dueAt);
|
|
31311
|
+
const extendByMs = parseOptionalTimeoutExtendByMs(args.extendByMs);
|
|
31312
|
+
const recurrenceIntervalMs = parseOptionalTimeoutRecurrenceInterval(args.recurrenceIntervalMs);
|
|
31313
|
+
const message = parseOptionalTimeoutMessage(args.message);
|
|
31314
|
+
const parameters = parseOptionalTimeoutParameters(args.parameters);
|
|
31315
|
+
const paused = parseOptionalTimeoutPaused(args.paused);
|
|
31316
|
+
if (dueAt !== undefined) {
|
|
31317
|
+
patch.dueAt = dueAt;
|
|
31318
|
+
}
|
|
31319
|
+
if (extendByMs !== undefined) {
|
|
31320
|
+
patch.extendByMs = extendByMs;
|
|
31321
|
+
}
|
|
31322
|
+
if (patch.dueAt !== undefined && patch.extendByMs !== undefined) {
|
|
31323
|
+
throw createTimeoutToolArgsError('Timeout update cannot include both `dueAt` and `extendByMs`.');
|
|
31324
|
+
}
|
|
31325
|
+
if (recurrenceIntervalMs !== undefined) {
|
|
31326
|
+
patch.recurrenceIntervalMs = recurrenceIntervalMs;
|
|
31327
|
+
}
|
|
31328
|
+
if (message !== undefined) {
|
|
31329
|
+
patch.message = message;
|
|
31330
|
+
}
|
|
31331
|
+
if (parameters !== undefined) {
|
|
31332
|
+
patch.parameters = parameters;
|
|
31333
|
+
}
|
|
31334
|
+
if (paused !== undefined) {
|
|
31335
|
+
patch.paused = paused;
|
|
31336
|
+
}
|
|
31337
|
+
return patch;
|
|
31338
|
+
}
|
|
31339
|
+
/**
|
|
31340
|
+
* Determines whether the patch contains fields that are only supported for single-timeout updates.
|
|
31341
|
+
*
|
|
31342
|
+
* @private internal utility of USE TIMEOUT
|
|
31343
|
+
*/
|
|
31344
|
+
function hasSingleTimeoutOnlyPatchFields(patch) {
|
|
31345
|
+
return (patch.dueAt !== undefined ||
|
|
31346
|
+
patch.extendByMs !== undefined ||
|
|
31347
|
+
patch.recurrenceIntervalMs !== undefined ||
|
|
31348
|
+
patch.message !== undefined ||
|
|
31349
|
+
patch.parameters !== undefined);
|
|
31350
|
+
}
|
|
31351
|
+
/**
|
|
31352
|
+
* Parses bulk timeout update arguments.
|
|
31353
|
+
*
|
|
31354
|
+
* @private internal utility of USE TIMEOUT
|
|
31355
|
+
*/
|
|
31356
|
+
function parseBulkTimeoutUpdateArgs(patch) {
|
|
31357
|
+
if (patch.paused === undefined) {
|
|
31358
|
+
throw createTimeoutToolArgsError('Bulk timeout update with `allActive: true` requires `paused` to be explicitly set.');
|
|
31359
|
+
}
|
|
31360
|
+
if (hasSingleTimeoutOnlyPatchFields(patch)) {
|
|
31361
|
+
throw createTimeoutToolArgsError('Bulk timeout update only supports the `paused` field.');
|
|
31362
|
+
}
|
|
31363
|
+
return {
|
|
31364
|
+
allActive: true,
|
|
31365
|
+
paused: patch.paused,
|
|
31366
|
+
};
|
|
31367
|
+
}
|
|
31368
|
+
/**
|
|
31369
|
+
* Parses single-timeout update arguments.
|
|
31370
|
+
*
|
|
31371
|
+
* @private internal utility of USE TIMEOUT
|
|
31372
|
+
*/
|
|
31373
|
+
function parseSingleTimeoutUpdateArgs(timeoutId, patch) {
|
|
31374
|
+
if (!timeoutId) {
|
|
31375
|
+
throw createTimeoutToolArgsError('Timeout `timeoutId` is required for single-timeout updates.');
|
|
31376
|
+
}
|
|
31377
|
+
if (Object.keys(patch).length === 0) {
|
|
31378
|
+
throw createTimeoutToolArgsError('Timeout update must include at least one editable field.');
|
|
31379
|
+
}
|
|
31380
|
+
return {
|
|
31381
|
+
timeoutId,
|
|
31382
|
+
patch,
|
|
31383
|
+
};
|
|
31384
|
+
}
|
|
31169
31385
|
/**
|
|
31170
31386
|
* Parses and validates `USE TIMEOUT` tool arguments.
|
|
31171
31387
|
*
|
|
@@ -31192,22 +31408,14 @@ const parseTimeoutToolArgs = {
|
|
|
31192
31408
|
* Parses `cancel_timeout` input.
|
|
31193
31409
|
*/
|
|
31194
31410
|
cancel(args) {
|
|
31195
|
-
const
|
|
31196
|
-
|
|
31197
|
-
|
|
31198
|
-
|
|
31199
|
-
|
|
31200
|
-
`));
|
|
31201
|
-
}
|
|
31202
|
-
if (allActive) {
|
|
31411
|
+
const target = parseTimeoutTargetSelection(args, {
|
|
31412
|
+
bothMessage: 'Timeout cancellation must target either one `timeoutId` or `allActive: true`, not both.',
|
|
31413
|
+
missingMessage: 'Timeout `timeoutId` is required unless you pass `allActive: true`.',
|
|
31414
|
+
});
|
|
31415
|
+
if (target.allActive) {
|
|
31203
31416
|
return { allActive: true };
|
|
31204
31417
|
}
|
|
31205
|
-
|
|
31206
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31207
|
-
Timeout \`timeoutId\` is required unless you pass \`allActive: true\`.
|
|
31208
|
-
`));
|
|
31209
|
-
}
|
|
31210
|
-
return { timeoutId };
|
|
31418
|
+
return { timeoutId: target.timeoutId };
|
|
31211
31419
|
},
|
|
31212
31420
|
/**
|
|
31213
31421
|
* Parses `list_timeouts` input.
|
|
@@ -31238,106 +31446,14 @@ const parseTimeoutToolArgs = {
|
|
|
31238
31446
|
* Parses `update_timeout` input.
|
|
31239
31447
|
*/
|
|
31240
31448
|
update(args) {
|
|
31241
|
-
const
|
|
31242
|
-
|
|
31243
|
-
|
|
31244
|
-
|
|
31245
|
-
|
|
31246
|
-
|
|
31247
|
-
|
|
31248
|
-
|
|
31249
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31250
|
-
Timeout update requires one \`timeoutId\` or \`allActive: true\`.
|
|
31251
|
-
`));
|
|
31252
|
-
}
|
|
31253
|
-
const patch = {};
|
|
31254
|
-
if (typeof args.dueAt === 'string' && args.dueAt.trim().length > 0) {
|
|
31255
|
-
const normalizedDueAt = args.dueAt.trim();
|
|
31256
|
-
const dueAtTimestamp = Date.parse(normalizedDueAt);
|
|
31257
|
-
if (!Number.isFinite(dueAtTimestamp)) {
|
|
31258
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31259
|
-
Timeout \`dueAt\` must be one valid ISO timestamp.
|
|
31260
|
-
`));
|
|
31261
|
-
}
|
|
31262
|
-
patch.dueAt = new Date(dueAtTimestamp).toISOString();
|
|
31263
|
-
}
|
|
31264
|
-
if (typeof args.extendByMs === 'number') {
|
|
31265
|
-
if (!Number.isFinite(args.extendByMs) || args.extendByMs <= 0) {
|
|
31266
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31267
|
-
Timeout \`extendByMs\` must be a positive number of milliseconds.
|
|
31268
|
-
`));
|
|
31269
|
-
}
|
|
31270
|
-
patch.extendByMs = Math.floor(args.extendByMs);
|
|
31271
|
-
}
|
|
31272
|
-
if (patch.dueAt !== undefined && patch.extendByMs !== undefined) {
|
|
31273
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31274
|
-
Timeout update cannot include both \`dueAt\` and \`extendByMs\`.
|
|
31275
|
-
`));
|
|
31276
|
-
}
|
|
31277
|
-
if (args.recurrenceIntervalMs === null) {
|
|
31278
|
-
patch.recurrenceIntervalMs = null;
|
|
31279
|
-
}
|
|
31280
|
-
else if (typeof args.recurrenceIntervalMs === 'number') {
|
|
31281
|
-
if (!Number.isFinite(args.recurrenceIntervalMs) || args.recurrenceIntervalMs <= 0) {
|
|
31282
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31283
|
-
Timeout \`recurrenceIntervalMs\` must be a positive number of milliseconds or \`null\`.
|
|
31284
|
-
`));
|
|
31285
|
-
}
|
|
31286
|
-
patch.recurrenceIntervalMs = Math.floor(args.recurrenceIntervalMs);
|
|
31287
|
-
}
|
|
31288
|
-
if (args.message === null) {
|
|
31289
|
-
patch.message = null;
|
|
31290
|
-
}
|
|
31291
|
-
else if (typeof args.message === 'string') {
|
|
31292
|
-
const normalizedMessage = args.message.trim();
|
|
31293
|
-
patch.message = normalizedMessage.length > 0 ? normalizedMessage : null;
|
|
31294
|
-
}
|
|
31295
|
-
if (args.parameters !== undefined) {
|
|
31296
|
-
if (!args.parameters || typeof args.parameters !== 'object' || Array.isArray(args.parameters)) {
|
|
31297
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31298
|
-
Timeout \`parameters\` must be one JSON object.
|
|
31299
|
-
`));
|
|
31300
|
-
}
|
|
31301
|
-
patch.parameters = args.parameters;
|
|
31302
|
-
}
|
|
31303
|
-
if (typeof args.paused === 'boolean') {
|
|
31304
|
-
patch.paused = args.paused;
|
|
31305
|
-
}
|
|
31306
|
-
if (allActive) {
|
|
31307
|
-
if (patch.paused === undefined) {
|
|
31308
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31309
|
-
Bulk timeout update with \`allActive: true\` requires \`paused\` to be explicitly set.
|
|
31310
|
-
`));
|
|
31311
|
-
}
|
|
31312
|
-
const hasSingleOnlyPatch = patch.dueAt !== undefined ||
|
|
31313
|
-
patch.extendByMs !== undefined ||
|
|
31314
|
-
patch.recurrenceIntervalMs !== undefined ||
|
|
31315
|
-
patch.message !== undefined ||
|
|
31316
|
-
patch.parameters !== undefined;
|
|
31317
|
-
if (hasSingleOnlyPatch) {
|
|
31318
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31319
|
-
Bulk timeout update only supports the \`paused\` field.
|
|
31320
|
-
`));
|
|
31321
|
-
}
|
|
31322
|
-
return {
|
|
31323
|
-
allActive: true,
|
|
31324
|
-
paused: patch.paused,
|
|
31325
|
-
};
|
|
31326
|
-
}
|
|
31327
|
-
if (!timeoutId) {
|
|
31328
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31329
|
-
Timeout \`timeoutId\` is required for single-timeout updates.
|
|
31330
|
-
`));
|
|
31331
|
-
}
|
|
31332
|
-
if (Object.keys(patch).length === 0) {
|
|
31333
|
-
throw new PipelineExecutionError(spaceTrim$1(`
|
|
31334
|
-
Timeout update must include at least one editable field.
|
|
31335
|
-
`));
|
|
31336
|
-
}
|
|
31337
|
-
return {
|
|
31338
|
-
timeoutId,
|
|
31339
|
-
patch,
|
|
31340
|
-
};
|
|
31449
|
+
const target = parseTimeoutTargetSelection(args, {
|
|
31450
|
+
bothMessage: 'Timeout update must target either one `timeoutId` or `allActive: true`, not both.',
|
|
31451
|
+
missingMessage: 'Timeout update requires one `timeoutId` or `allActive: true`.',
|
|
31452
|
+
});
|
|
31453
|
+
const patch = parseTimeoutUpdatePatch(args);
|
|
31454
|
+
return target.allActive
|
|
31455
|
+
? parseBulkTimeoutUpdateArgs(patch)
|
|
31456
|
+
: parseSingleTimeoutUpdateArgs(target.timeoutId, patch);
|
|
31341
31457
|
},
|
|
31342
31458
|
};
|
|
31343
31459
|
|
|
@@ -41443,326 +41559,6 @@ async function loadArchive(filePath, fs) {
|
|
|
41443
41559
|
}
|
|
41444
41560
|
// Note: [🟢] Code for Node archive helper [loadArchive](src/conversion/archive/loadArchive.ts) should never be published into packages that could be imported into browser environment
|
|
41445
41561
|
|
|
41446
|
-
/**
|
|
41447
|
-
* All available task types
|
|
41448
|
-
*
|
|
41449
|
-
* There is is distinction between task types and section types
|
|
41450
|
-
* - Every section in markdown has its SectionType
|
|
41451
|
-
* - Some sections are tasks but other can be non-task sections
|
|
41452
|
-
*
|
|
41453
|
-
* @public exported from `@promptbook/core`
|
|
41454
|
-
*/
|
|
41455
|
-
const TaskTypes = [
|
|
41456
|
-
'PROMPT',
|
|
41457
|
-
'SIMPLE',
|
|
41458
|
-
'SCRIPT',
|
|
41459
|
-
'DIALOG',
|
|
41460
|
-
// <- [🅱]
|
|
41461
|
-
];
|
|
41462
|
-
|
|
41463
|
-
/**
|
|
41464
|
-
* All available sections which are not tasks
|
|
41465
|
-
*
|
|
41466
|
-
* @public exported from `@promptbook/core`
|
|
41467
|
-
*/
|
|
41468
|
-
const NonTaskSectionTypes = ['EXAMPLE', 'KNOWLEDGE', 'INSTRUMENT', 'ACTION'];
|
|
41469
|
-
/**
|
|
41470
|
-
* All available section types
|
|
41471
|
-
*
|
|
41472
|
-
* There is is distinction between task types and section types
|
|
41473
|
-
* - Every section in markdown has its SectionType
|
|
41474
|
-
* - Some sections are tasks but other can be non-task sections
|
|
41475
|
-
*
|
|
41476
|
-
* @public exported from `@promptbook/core`
|
|
41477
|
-
*/
|
|
41478
|
-
const SectionTypes = [
|
|
41479
|
-
...TaskTypes.map((TaskType) => `${TaskType}_TASK`),
|
|
41480
|
-
...NonTaskSectionTypes,
|
|
41481
|
-
];
|
|
41482
|
-
|
|
41483
|
-
/**
|
|
41484
|
-
* Parses the knowledge command
|
|
41485
|
-
*
|
|
41486
|
-
* @see `documentationUrl` for more details
|
|
41487
|
-
*
|
|
41488
|
-
* @public exported from `@promptbook/editable`
|
|
41489
|
-
*/
|
|
41490
|
-
const knowledgeCommandParser = {
|
|
41491
|
-
/**
|
|
41492
|
-
* Name of the command
|
|
41493
|
-
*/
|
|
41494
|
-
name: 'KNOWLEDGE',
|
|
41495
|
-
/**
|
|
41496
|
-
* BOILERPLATE command can be used in:
|
|
41497
|
-
*/
|
|
41498
|
-
isUsedInPipelineHead: true,
|
|
41499
|
-
isUsedInPipelineTask: false,
|
|
41500
|
-
/**
|
|
41501
|
-
* Description of the KNOWLEDGE command
|
|
41502
|
-
*/
|
|
41503
|
-
description: `Tells promptbook which external knowledge to use`,
|
|
41504
|
-
/**
|
|
41505
|
-
* Link to documentation
|
|
41506
|
-
*/
|
|
41507
|
-
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/41',
|
|
41508
|
-
/**
|
|
41509
|
-
* Example usages of the KNOWLEDGE command
|
|
41510
|
-
*/
|
|
41511
|
-
examples: [
|
|
41512
|
-
'KNOWLEDGE https://www.pavolhejny.com/',
|
|
41513
|
-
'KNOWLEDGE ./hejny-cv.txt',
|
|
41514
|
-
'KNOWLEDGE ./hejny-cv.md',
|
|
41515
|
-
'KNOWLEDGE ./hejny-cv.pdf',
|
|
41516
|
-
'KNOWLEDGE ./hejny-cv.docx',
|
|
41517
|
-
// <- TODO: [😿] Allow ONLY files scoped in the (sub)directory NOT ../ and test it
|
|
41518
|
-
],
|
|
41519
|
-
/**
|
|
41520
|
-
* Parses the KNOWLEDGE command
|
|
41521
|
-
*/
|
|
41522
|
-
parse(input) {
|
|
41523
|
-
const { args } = input;
|
|
41524
|
-
const knowledgeSourceContent = spaceTrim$1(args[0] || '');
|
|
41525
|
-
if (knowledgeSourceContent === '') {
|
|
41526
|
-
throw new ParseError(`Source is not defined`);
|
|
41527
|
-
}
|
|
41528
|
-
// TODO: [main] !!4 Following checks should be applied every link in the `sourceContent`
|
|
41529
|
-
if (knowledgeSourceContent.startsWith('http://')) {
|
|
41530
|
-
throw new ParseError(`Source is not secure`);
|
|
41531
|
-
}
|
|
41532
|
-
if (!(isValidFilePath(knowledgeSourceContent) || isValidUrl(knowledgeSourceContent))) {
|
|
41533
|
-
throw new ParseError(`Source not valid`);
|
|
41534
|
-
}
|
|
41535
|
-
if (knowledgeSourceContent.startsWith('../') ||
|
|
41536
|
-
knowledgeSourceContent.startsWith('/') ||
|
|
41537
|
-
/^[A-Z]:[\\/]+/i.test(knowledgeSourceContent)) {
|
|
41538
|
-
throw new ParseError(`Source cannot be outside of the .book.md folder`);
|
|
41539
|
-
}
|
|
41540
|
-
return {
|
|
41541
|
-
type: 'KNOWLEDGE',
|
|
41542
|
-
knowledgeSourceContent,
|
|
41543
|
-
};
|
|
41544
|
-
},
|
|
41545
|
-
/**
|
|
41546
|
-
* Apply the KNOWLEDGE command to the `pipelineJson`
|
|
41547
|
-
*
|
|
41548
|
-
* Note: `$` is used to indicate that this function mutates given `pipelineJson`
|
|
41549
|
-
*/
|
|
41550
|
-
$applyToPipelineJson(command, $pipelineJson) {
|
|
41551
|
-
const { knowledgeSourceContent } = command;
|
|
41552
|
-
$pipelineJson.knowledgeSources.push({
|
|
41553
|
-
name: knowledgeSourceContentToName(knowledgeSourceContent),
|
|
41554
|
-
knowledgeSourceContent,
|
|
41555
|
-
});
|
|
41556
|
-
},
|
|
41557
|
-
/**
|
|
41558
|
-
* Converts the KNOWLEDGE command back to string
|
|
41559
|
-
*
|
|
41560
|
-
* Note: This is used in `pipelineJsonToString` utility
|
|
41561
|
-
*/
|
|
41562
|
-
stringify(command) {
|
|
41563
|
-
return `---`; // <- TODO: [🛋] Implement
|
|
41564
|
-
},
|
|
41565
|
-
/**
|
|
41566
|
-
* Reads the KNOWLEDGE command from the `PipelineJson`
|
|
41567
|
-
*
|
|
41568
|
-
* Note: This is used in `pipelineJsonToString` utility
|
|
41569
|
-
*/
|
|
41570
|
-
takeFromPipelineJson(pipelineJson) {
|
|
41571
|
-
throw new NotYetImplementedError(`[🛋] Not implemented yet`); // <- TODO: [🛋] Implement
|
|
41572
|
-
},
|
|
41573
|
-
};
|
|
41574
|
-
// Note: [⛱] There are two types of KNOWLEDGE commands *...(read more in [⛱])*
|
|
41575
|
-
|
|
41576
|
-
/**
|
|
41577
|
-
* Parses the section command
|
|
41578
|
-
*
|
|
41579
|
-
* @see `documentationUrl` for more details
|
|
41580
|
-
*
|
|
41581
|
-
* @public exported from `@promptbook/editable`
|
|
41582
|
-
*/
|
|
41583
|
-
const sectionCommandParser = {
|
|
41584
|
-
/**
|
|
41585
|
-
* Name of the command
|
|
41586
|
-
*/
|
|
41587
|
-
name: 'SECTION',
|
|
41588
|
-
/**
|
|
41589
|
-
* Aliases for the SECTION command
|
|
41590
|
-
*/
|
|
41591
|
-
aliasNames: [
|
|
41592
|
-
'PROMPT',
|
|
41593
|
-
'SIMPLE',
|
|
41594
|
-
'SCRIPT',
|
|
41595
|
-
'DIALOG',
|
|
41596
|
-
'SAMPLE',
|
|
41597
|
-
'EXAMPLE',
|
|
41598
|
-
'KNOWLEDGE',
|
|
41599
|
-
'INSTRUMENT',
|
|
41600
|
-
'ACTION', // <- Note: [⛱]
|
|
41601
|
-
],
|
|
41602
|
-
/**
|
|
41603
|
-
* Aliases for the SECTION command
|
|
41604
|
-
*/
|
|
41605
|
-
deprecatedNames: ['TEMPLATE', 'BLOCK', 'EXECUTE'],
|
|
41606
|
-
/**
|
|
41607
|
-
* BOILERPLATE command can be used in:
|
|
41608
|
-
*/
|
|
41609
|
-
isUsedInPipelineHead: false,
|
|
41610
|
-
isUsedInPipelineTask: true,
|
|
41611
|
-
/**
|
|
41612
|
-
* Description of the SECTION command
|
|
41613
|
-
*/
|
|
41614
|
-
description: `Defines the purpose of the markdown section - if its a task and which type or something else`,
|
|
41615
|
-
/**
|
|
41616
|
-
* Link to documentation
|
|
41617
|
-
*/
|
|
41618
|
-
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/64',
|
|
41619
|
-
/**
|
|
41620
|
-
* Example usages of the SECTION command
|
|
41621
|
-
*/
|
|
41622
|
-
examples: [
|
|
41623
|
-
// Short form:
|
|
41624
|
-
'PROMPT',
|
|
41625
|
-
'SIMPLE',
|
|
41626
|
-
'SCRIPT',
|
|
41627
|
-
'DIALOG',
|
|
41628
|
-
// <- [🅱]
|
|
41629
|
-
'EXAMPLE',
|
|
41630
|
-
'KNOWLEDGE',
|
|
41631
|
-
'INSTRUMENT',
|
|
41632
|
-
'ACTION',
|
|
41633
|
-
// -----------------
|
|
41634
|
-
// Recommended (reversed) form:
|
|
41635
|
-
'PROMPT SECTION',
|
|
41636
|
-
'SIMPLE SECTION',
|
|
41637
|
-
'SCRIPT SECTION',
|
|
41638
|
-
'DIALOG SECTION',
|
|
41639
|
-
// <- [🅱]
|
|
41640
|
-
'EXAMPLE SECTION',
|
|
41641
|
-
'KNOWLEDGE SECTION',
|
|
41642
|
-
'INSTRUMENT SECTION',
|
|
41643
|
-
'ACTION SECTION',
|
|
41644
|
-
// -----------------
|
|
41645
|
-
// Standard form:
|
|
41646
|
-
'SECTION PROMPT',
|
|
41647
|
-
'SECTION SIMPLE',
|
|
41648
|
-
'SECTION SCRIPT',
|
|
41649
|
-
'SECTION DIALOG',
|
|
41650
|
-
// <- [🅱]
|
|
41651
|
-
'SECTION EXAMPLE',
|
|
41652
|
-
'SECTION KNOWLEDGE',
|
|
41653
|
-
'SECTION INSTRUMENT',
|
|
41654
|
-
'SECTION ACTION',
|
|
41655
|
-
],
|
|
41656
|
-
// TODO: [♓️] order: -10 /* <- Note: Putting before other commands */
|
|
41657
|
-
/**
|
|
41658
|
-
* Parses the SECTION command
|
|
41659
|
-
*/
|
|
41660
|
-
parse(input) {
|
|
41661
|
-
let { normalized } = input;
|
|
41662
|
-
normalized = normalized.split('SAMPLE').join('EXAMPLE');
|
|
41663
|
-
normalized = normalized.split('EXECUTE_').join('');
|
|
41664
|
-
normalized = normalized.split('DIALOGUE').join('DIALOG');
|
|
41665
|
-
const taskTypes = SectionTypes.filter((sectionType) => normalized.includes(sectionType.split('_TASK').join('')));
|
|
41666
|
-
if (taskTypes.length !== 1) {
|
|
41667
|
-
throw new ParseError(spaceTrim$1((block) => `
|
|
41668
|
-
Unknown section type "${normalized}"
|
|
41669
|
-
|
|
41670
|
-
Supported section types are:
|
|
41671
|
-
${block(SectionTypes.join(', '))}
|
|
41672
|
-
`));
|
|
41673
|
-
}
|
|
41674
|
-
const taskType = taskTypes[0];
|
|
41675
|
-
return {
|
|
41676
|
-
type: 'SECTION',
|
|
41677
|
-
taskType,
|
|
41678
|
-
};
|
|
41679
|
-
},
|
|
41680
|
-
/**
|
|
41681
|
-
* Apply the SECTION command to the `pipelineJson`
|
|
41682
|
-
*
|
|
41683
|
-
* Note: `$` is used to indicate that this function mutates given `taskJson`
|
|
41684
|
-
*/
|
|
41685
|
-
$applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
41686
|
-
if ($taskJson.isSectionTypeSet === true) {
|
|
41687
|
-
throw new ParseError(spaceTrim$1(`
|
|
41688
|
-
Section type is already defined in the section.
|
|
41689
|
-
It can be defined only once.
|
|
41690
|
-
`));
|
|
41691
|
-
}
|
|
41692
|
-
$taskJson.isSectionTypeSet = true;
|
|
41693
|
-
// TODO: [🍧][💩] Rearrange better - but at bottom and unwrap from function
|
|
41694
|
-
const expectResultingParameterName = () => {
|
|
41695
|
-
if ($taskJson.resultingParameterName) {
|
|
41696
|
-
return;
|
|
41697
|
-
}
|
|
41698
|
-
throw new ParseError(`Task section and example section must end with return statement -> {parameterName}`);
|
|
41699
|
-
};
|
|
41700
|
-
if ($taskJson.content === undefined) {
|
|
41701
|
-
throw new UnexpectedError(`Content is missing in the taskJson - probably commands are applied in wrong order`);
|
|
41702
|
-
}
|
|
41703
|
-
if (command.taskType === 'EXAMPLE') {
|
|
41704
|
-
expectResultingParameterName();
|
|
41705
|
-
const parameter = $pipelineJson.parameters.find((param) => param.name === $taskJson.resultingParameterName);
|
|
41706
|
-
if (parameter === undefined) {
|
|
41707
|
-
// TODO: !!6 Change to logic error for higher level abstraction of chatbot to work
|
|
41708
|
-
throw new ParseError(`Parameter \`{${$taskJson.resultingParameterName}}\` is not defined so can not define example value of it`);
|
|
41709
|
-
}
|
|
41710
|
-
parameter.exampleValues = parameter.exampleValues || [];
|
|
41711
|
-
parameter.exampleValues.push($taskJson.content);
|
|
41712
|
-
$taskJson.isTask = false;
|
|
41713
|
-
return;
|
|
41714
|
-
}
|
|
41715
|
-
if (command.taskType === 'KNOWLEDGE') {
|
|
41716
|
-
knowledgeCommandParser.$applyToPipelineJson({
|
|
41717
|
-
type: 'KNOWLEDGE',
|
|
41718
|
-
knowledgeSourceContent: $taskJson.content, // <- TODO: [🐝][main] !!3 Work with KNOWLEDGE which not referring to the source file or website, but its content itself
|
|
41719
|
-
}, $pipelineJson);
|
|
41720
|
-
$taskJson.isTask = false;
|
|
41721
|
-
return;
|
|
41722
|
-
}
|
|
41723
|
-
if (command.taskType === 'ACTION') {
|
|
41724
|
-
console.error(new NotYetImplementedError('Actions are not implemented yet'));
|
|
41725
|
-
$taskJson.isTask = false;
|
|
41726
|
-
return;
|
|
41727
|
-
}
|
|
41728
|
-
if (command.taskType === 'INSTRUMENT') {
|
|
41729
|
-
console.error(new NotYetImplementedError('Instruments are not implemented yet'));
|
|
41730
|
-
$taskJson.isTask = false;
|
|
41731
|
-
return;
|
|
41732
|
-
}
|
|
41733
|
-
expectResultingParameterName();
|
|
41734
|
-
$taskJson.taskType = command.taskType;
|
|
41735
|
-
$taskJson.isTask = true;
|
|
41736
|
-
},
|
|
41737
|
-
/**
|
|
41738
|
-
* Converts the SECTION command back to string
|
|
41739
|
-
*
|
|
41740
|
-
* Note: This is used in `pipelineJsonToString` utility
|
|
41741
|
-
*/
|
|
41742
|
-
stringify(command) {
|
|
41743
|
-
return `---`; // <- TODO: [🛋] Implement
|
|
41744
|
-
},
|
|
41745
|
-
/**
|
|
41746
|
-
* Reads the SECTION command from the `TaskJson`
|
|
41747
|
-
*
|
|
41748
|
-
* Note: This is used in `pipelineJsonToString` utility
|
|
41749
|
-
*/
|
|
41750
|
-
takeFromTaskJson($taskJson) {
|
|
41751
|
-
throw new NotYetImplementedError(`[🛋] Not implemented yet`); // <- TODO: [🛋] Implement
|
|
41752
|
-
},
|
|
41753
|
-
};
|
|
41754
|
-
/**
|
|
41755
|
-
* Note: [⛱] There are two types of KNOWLEDGE, ACTION and INSTRUMENT commands:
|
|
41756
|
-
* 1) There are commands `KNOWLEDGE`, `ACTION` and `INSTRUMENT` used in the pipeline head, they just define the knowledge, action or instrument as single line after the command
|
|
41757
|
-
* - KNOWLEDGE Look at https://en.wikipedia.org/wiki/Artificial_intelligence
|
|
41758
|
-
* 2) `KNOWLEDGE SECTION` which has short form `KNOWLEDGE` is used in the sectiom, does not refer the line itself, but the content of the section block
|
|
41759
|
-
* - KNOWLEDGE SECTION
|
|
41760
|
-
*
|
|
41761
|
-
* ```
|
|
41762
|
-
* Look at https://en.wikipedia.org/wiki/Artificial_intelligence
|
|
41763
|
-
* ```
|
|
41764
|
-
*/
|
|
41765
|
-
|
|
41766
41562
|
/**
|
|
41767
41563
|
* Parses the boilerplate command
|
|
41768
41564
|
*
|
|
@@ -42844,6 +42640,99 @@ const jokerCommandParser = {
|
|
|
42844
42640
|
},
|
|
42845
42641
|
};
|
|
42846
42642
|
|
|
42643
|
+
/**
|
|
42644
|
+
* Parses the knowledge command
|
|
42645
|
+
*
|
|
42646
|
+
* @see `documentationUrl` for more details
|
|
42647
|
+
*
|
|
42648
|
+
* @public exported from `@promptbook/editable`
|
|
42649
|
+
*/
|
|
42650
|
+
const knowledgeCommandParser = {
|
|
42651
|
+
/**
|
|
42652
|
+
* Name of the command
|
|
42653
|
+
*/
|
|
42654
|
+
name: 'KNOWLEDGE',
|
|
42655
|
+
/**
|
|
42656
|
+
* BOILERPLATE command can be used in:
|
|
42657
|
+
*/
|
|
42658
|
+
isUsedInPipelineHead: true,
|
|
42659
|
+
isUsedInPipelineTask: false,
|
|
42660
|
+
/**
|
|
42661
|
+
* Description of the KNOWLEDGE command
|
|
42662
|
+
*/
|
|
42663
|
+
description: `Tells promptbook which external knowledge to use`,
|
|
42664
|
+
/**
|
|
42665
|
+
* Link to documentation
|
|
42666
|
+
*/
|
|
42667
|
+
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/41',
|
|
42668
|
+
/**
|
|
42669
|
+
* Example usages of the KNOWLEDGE command
|
|
42670
|
+
*/
|
|
42671
|
+
examples: [
|
|
42672
|
+
'KNOWLEDGE https://www.pavolhejny.com/',
|
|
42673
|
+
'KNOWLEDGE ./hejny-cv.txt',
|
|
42674
|
+
'KNOWLEDGE ./hejny-cv.md',
|
|
42675
|
+
'KNOWLEDGE ./hejny-cv.pdf',
|
|
42676
|
+
'KNOWLEDGE ./hejny-cv.docx',
|
|
42677
|
+
// <- TODO: [😿] Allow ONLY files scoped in the (sub)directory NOT ../ and test it
|
|
42678
|
+
],
|
|
42679
|
+
/**
|
|
42680
|
+
* Parses the KNOWLEDGE command
|
|
42681
|
+
*/
|
|
42682
|
+
parse(input) {
|
|
42683
|
+
const { args } = input;
|
|
42684
|
+
const knowledgeSourceContent = spaceTrim$1(args[0] || '');
|
|
42685
|
+
if (knowledgeSourceContent === '') {
|
|
42686
|
+
throw new ParseError(`Source is not defined`);
|
|
42687
|
+
}
|
|
42688
|
+
// TODO: [main] !!4 Following checks should be applied every link in the `sourceContent`
|
|
42689
|
+
if (knowledgeSourceContent.startsWith('http://')) {
|
|
42690
|
+
throw new ParseError(`Source is not secure`);
|
|
42691
|
+
}
|
|
42692
|
+
if (!(isValidFilePath(knowledgeSourceContent) || isValidUrl(knowledgeSourceContent))) {
|
|
42693
|
+
throw new ParseError(`Source not valid`);
|
|
42694
|
+
}
|
|
42695
|
+
if (knowledgeSourceContent.startsWith('../') ||
|
|
42696
|
+
knowledgeSourceContent.startsWith('/') ||
|
|
42697
|
+
/^[A-Z]:[\\/]+/i.test(knowledgeSourceContent)) {
|
|
42698
|
+
throw new ParseError(`Source cannot be outside of the .book.md folder`);
|
|
42699
|
+
}
|
|
42700
|
+
return {
|
|
42701
|
+
type: 'KNOWLEDGE',
|
|
42702
|
+
knowledgeSourceContent,
|
|
42703
|
+
};
|
|
42704
|
+
},
|
|
42705
|
+
/**
|
|
42706
|
+
* Apply the KNOWLEDGE command to the `pipelineJson`
|
|
42707
|
+
*
|
|
42708
|
+
* Note: `$` is used to indicate that this function mutates given `pipelineJson`
|
|
42709
|
+
*/
|
|
42710
|
+
$applyToPipelineJson(command, $pipelineJson) {
|
|
42711
|
+
const { knowledgeSourceContent } = command;
|
|
42712
|
+
$pipelineJson.knowledgeSources.push({
|
|
42713
|
+
name: knowledgeSourceContentToName(knowledgeSourceContent),
|
|
42714
|
+
knowledgeSourceContent,
|
|
42715
|
+
});
|
|
42716
|
+
},
|
|
42717
|
+
/**
|
|
42718
|
+
* Converts the KNOWLEDGE command back to string
|
|
42719
|
+
*
|
|
42720
|
+
* Note: This is used in `pipelineJsonToString` utility
|
|
42721
|
+
*/
|
|
42722
|
+
stringify(command) {
|
|
42723
|
+
return `---`; // <- TODO: [🛋] Implement
|
|
42724
|
+
},
|
|
42725
|
+
/**
|
|
42726
|
+
* Reads the KNOWLEDGE command from the `PipelineJson`
|
|
42727
|
+
*
|
|
42728
|
+
* Note: This is used in `pipelineJsonToString` utility
|
|
42729
|
+
*/
|
|
42730
|
+
takeFromPipelineJson(pipelineJson) {
|
|
42731
|
+
throw new NotYetImplementedError(`[🛋] Not implemented yet`); // <- TODO: [🛋] Implement
|
|
42732
|
+
},
|
|
42733
|
+
};
|
|
42734
|
+
// Note: [⛱] There are two types of KNOWLEDGE commands *...(read more in [⛱])*
|
|
42735
|
+
|
|
42847
42736
|
/**
|
|
42848
42737
|
* Constant for model variants.
|
|
42849
42738
|
*
|
|
@@ -43362,6 +43251,233 @@ const postprocessCommandParser = {
|
|
|
43362
43251
|
},
|
|
43363
43252
|
};
|
|
43364
43253
|
|
|
43254
|
+
/**
|
|
43255
|
+
* All available task types
|
|
43256
|
+
*
|
|
43257
|
+
* There is is distinction between task types and section types
|
|
43258
|
+
* - Every section in markdown has its SectionType
|
|
43259
|
+
* - Some sections are tasks but other can be non-task sections
|
|
43260
|
+
*
|
|
43261
|
+
* @public exported from `@promptbook/core`
|
|
43262
|
+
*/
|
|
43263
|
+
const TaskTypes = [
|
|
43264
|
+
'PROMPT',
|
|
43265
|
+
'SIMPLE',
|
|
43266
|
+
'SCRIPT',
|
|
43267
|
+
'DIALOG',
|
|
43268
|
+
// <- [🅱]
|
|
43269
|
+
];
|
|
43270
|
+
|
|
43271
|
+
/**
|
|
43272
|
+
* All available sections which are not tasks
|
|
43273
|
+
*
|
|
43274
|
+
* @public exported from `@promptbook/core`
|
|
43275
|
+
*/
|
|
43276
|
+
const NonTaskSectionTypes = ['EXAMPLE', 'KNOWLEDGE', 'INSTRUMENT', 'ACTION'];
|
|
43277
|
+
/**
|
|
43278
|
+
* All available section types
|
|
43279
|
+
*
|
|
43280
|
+
* There is is distinction between task types and section types
|
|
43281
|
+
* - Every section in markdown has its SectionType
|
|
43282
|
+
* - Some sections are tasks but other can be non-task sections
|
|
43283
|
+
*
|
|
43284
|
+
* @public exported from `@promptbook/core`
|
|
43285
|
+
*/
|
|
43286
|
+
const SectionTypes = [
|
|
43287
|
+
...TaskTypes.map((TaskType) => `${TaskType}_TASK`),
|
|
43288
|
+
...NonTaskSectionTypes,
|
|
43289
|
+
];
|
|
43290
|
+
|
|
43291
|
+
/**
|
|
43292
|
+
* Parses the section command
|
|
43293
|
+
*
|
|
43294
|
+
* @see `documentationUrl` for more details
|
|
43295
|
+
*
|
|
43296
|
+
* @public exported from `@promptbook/editable`
|
|
43297
|
+
*/
|
|
43298
|
+
const sectionCommandParser = {
|
|
43299
|
+
/**
|
|
43300
|
+
* Name of the command
|
|
43301
|
+
*/
|
|
43302
|
+
name: 'SECTION',
|
|
43303
|
+
/**
|
|
43304
|
+
* Aliases for the SECTION command
|
|
43305
|
+
*/
|
|
43306
|
+
aliasNames: [
|
|
43307
|
+
'PROMPT',
|
|
43308
|
+
'SIMPLE',
|
|
43309
|
+
'SCRIPT',
|
|
43310
|
+
'DIALOG',
|
|
43311
|
+
'SAMPLE',
|
|
43312
|
+
'EXAMPLE',
|
|
43313
|
+
'KNOWLEDGE',
|
|
43314
|
+
'INSTRUMENT',
|
|
43315
|
+
'ACTION', // <- Note: [⛱]
|
|
43316
|
+
],
|
|
43317
|
+
/**
|
|
43318
|
+
* Aliases for the SECTION command
|
|
43319
|
+
*/
|
|
43320
|
+
deprecatedNames: ['TEMPLATE', 'BLOCK', 'EXECUTE'],
|
|
43321
|
+
/**
|
|
43322
|
+
* BOILERPLATE command can be used in:
|
|
43323
|
+
*/
|
|
43324
|
+
isUsedInPipelineHead: false,
|
|
43325
|
+
isUsedInPipelineTask: true,
|
|
43326
|
+
/**
|
|
43327
|
+
* Description of the SECTION command
|
|
43328
|
+
*/
|
|
43329
|
+
description: `Defines the purpose of the markdown section - if its a task and which type or something else`,
|
|
43330
|
+
/**
|
|
43331
|
+
* Link to documentation
|
|
43332
|
+
*/
|
|
43333
|
+
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/64',
|
|
43334
|
+
/**
|
|
43335
|
+
* Example usages of the SECTION command
|
|
43336
|
+
*/
|
|
43337
|
+
examples: [
|
|
43338
|
+
// Short form:
|
|
43339
|
+
'PROMPT',
|
|
43340
|
+
'SIMPLE',
|
|
43341
|
+
'SCRIPT',
|
|
43342
|
+
'DIALOG',
|
|
43343
|
+
// <- [🅱]
|
|
43344
|
+
'EXAMPLE',
|
|
43345
|
+
'KNOWLEDGE',
|
|
43346
|
+
'INSTRUMENT',
|
|
43347
|
+
'ACTION',
|
|
43348
|
+
// -----------------
|
|
43349
|
+
// Recommended (reversed) form:
|
|
43350
|
+
'PROMPT SECTION',
|
|
43351
|
+
'SIMPLE SECTION',
|
|
43352
|
+
'SCRIPT SECTION',
|
|
43353
|
+
'DIALOG SECTION',
|
|
43354
|
+
// <- [🅱]
|
|
43355
|
+
'EXAMPLE SECTION',
|
|
43356
|
+
'KNOWLEDGE SECTION',
|
|
43357
|
+
'INSTRUMENT SECTION',
|
|
43358
|
+
'ACTION SECTION',
|
|
43359
|
+
// -----------------
|
|
43360
|
+
// Standard form:
|
|
43361
|
+
'SECTION PROMPT',
|
|
43362
|
+
'SECTION SIMPLE',
|
|
43363
|
+
'SECTION SCRIPT',
|
|
43364
|
+
'SECTION DIALOG',
|
|
43365
|
+
// <- [🅱]
|
|
43366
|
+
'SECTION EXAMPLE',
|
|
43367
|
+
'SECTION KNOWLEDGE',
|
|
43368
|
+
'SECTION INSTRUMENT',
|
|
43369
|
+
'SECTION ACTION',
|
|
43370
|
+
],
|
|
43371
|
+
// TODO: [♓️] order: -10 /* <- Note: Putting before other commands */
|
|
43372
|
+
/**
|
|
43373
|
+
* Parses the SECTION command
|
|
43374
|
+
*/
|
|
43375
|
+
parse(input) {
|
|
43376
|
+
let { normalized } = input;
|
|
43377
|
+
normalized = normalized.split('SAMPLE').join('EXAMPLE');
|
|
43378
|
+
normalized = normalized.split('EXECUTE_').join('');
|
|
43379
|
+
normalized = normalized.split('DIALOGUE').join('DIALOG');
|
|
43380
|
+
const taskTypes = SectionTypes.filter((sectionType) => normalized.includes(sectionType.split('_TASK').join('')));
|
|
43381
|
+
if (taskTypes.length !== 1) {
|
|
43382
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
43383
|
+
Unknown section type "${normalized}"
|
|
43384
|
+
|
|
43385
|
+
Supported section types are:
|
|
43386
|
+
${block(SectionTypes.join(', '))}
|
|
43387
|
+
`));
|
|
43388
|
+
}
|
|
43389
|
+
const taskType = taskTypes[0];
|
|
43390
|
+
return {
|
|
43391
|
+
type: 'SECTION',
|
|
43392
|
+
taskType,
|
|
43393
|
+
};
|
|
43394
|
+
},
|
|
43395
|
+
/**
|
|
43396
|
+
* Apply the SECTION command to the `pipelineJson`
|
|
43397
|
+
*
|
|
43398
|
+
* Note: `$` is used to indicate that this function mutates given `taskJson`
|
|
43399
|
+
*/
|
|
43400
|
+
$applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
43401
|
+
if ($taskJson.isSectionTypeSet === true) {
|
|
43402
|
+
throw new ParseError(spaceTrim$1(`
|
|
43403
|
+
Section type is already defined in the section.
|
|
43404
|
+
It can be defined only once.
|
|
43405
|
+
`));
|
|
43406
|
+
}
|
|
43407
|
+
$taskJson.isSectionTypeSet = true;
|
|
43408
|
+
// TODO: [🍧][💩] Rearrange better - but at bottom and unwrap from function
|
|
43409
|
+
const expectResultingParameterName = () => {
|
|
43410
|
+
if ($taskJson.resultingParameterName) {
|
|
43411
|
+
return;
|
|
43412
|
+
}
|
|
43413
|
+
throw new ParseError(`Task section and example section must end with return statement -> {parameterName}`);
|
|
43414
|
+
};
|
|
43415
|
+
if ($taskJson.content === undefined) {
|
|
43416
|
+
throw new UnexpectedError(`Content is missing in the taskJson - probably commands are applied in wrong order`);
|
|
43417
|
+
}
|
|
43418
|
+
if (command.taskType === 'EXAMPLE') {
|
|
43419
|
+
expectResultingParameterName();
|
|
43420
|
+
const parameter = $pipelineJson.parameters.find((param) => param.name === $taskJson.resultingParameterName);
|
|
43421
|
+
if (parameter === undefined) {
|
|
43422
|
+
// TODO: !!6 Change to logic error for higher level abstraction of chatbot to work
|
|
43423
|
+
throw new ParseError(`Parameter \`{${$taskJson.resultingParameterName}}\` is not defined so can not define example value of it`);
|
|
43424
|
+
}
|
|
43425
|
+
parameter.exampleValues = parameter.exampleValues || [];
|
|
43426
|
+
parameter.exampleValues.push($taskJson.content);
|
|
43427
|
+
$taskJson.isTask = false;
|
|
43428
|
+
return;
|
|
43429
|
+
}
|
|
43430
|
+
if (command.taskType === 'KNOWLEDGE') {
|
|
43431
|
+
knowledgeCommandParser.$applyToPipelineJson({
|
|
43432
|
+
type: 'KNOWLEDGE',
|
|
43433
|
+
knowledgeSourceContent: $taskJson.content, // <- TODO: [🐝][main] !!3 Work with KNOWLEDGE which not referring to the source file or website, but its content itself
|
|
43434
|
+
}, $pipelineJson);
|
|
43435
|
+
$taskJson.isTask = false;
|
|
43436
|
+
return;
|
|
43437
|
+
}
|
|
43438
|
+
if (command.taskType === 'ACTION') {
|
|
43439
|
+
console.error(new NotYetImplementedError('Actions are not implemented yet'));
|
|
43440
|
+
$taskJson.isTask = false;
|
|
43441
|
+
return;
|
|
43442
|
+
}
|
|
43443
|
+
if (command.taskType === 'INSTRUMENT') {
|
|
43444
|
+
console.error(new NotYetImplementedError('Instruments are not implemented yet'));
|
|
43445
|
+
$taskJson.isTask = false;
|
|
43446
|
+
return;
|
|
43447
|
+
}
|
|
43448
|
+
expectResultingParameterName();
|
|
43449
|
+
$taskJson.taskType = command.taskType;
|
|
43450
|
+
$taskJson.isTask = true;
|
|
43451
|
+
},
|
|
43452
|
+
/**
|
|
43453
|
+
* Converts the SECTION command back to string
|
|
43454
|
+
*
|
|
43455
|
+
* Note: This is used in `pipelineJsonToString` utility
|
|
43456
|
+
*/
|
|
43457
|
+
stringify(command) {
|
|
43458
|
+
return `---`; // <- TODO: [🛋] Implement
|
|
43459
|
+
},
|
|
43460
|
+
/**
|
|
43461
|
+
* Reads the SECTION command from the `TaskJson`
|
|
43462
|
+
*
|
|
43463
|
+
* Note: This is used in `pipelineJsonToString` utility
|
|
43464
|
+
*/
|
|
43465
|
+
takeFromTaskJson($taskJson) {
|
|
43466
|
+
throw new NotYetImplementedError(`[🛋] Not implemented yet`); // <- TODO: [🛋] Implement
|
|
43467
|
+
},
|
|
43468
|
+
};
|
|
43469
|
+
/**
|
|
43470
|
+
* Note: [⛱] There are two types of KNOWLEDGE, ACTION and INSTRUMENT commands:
|
|
43471
|
+
* 1) There are commands `KNOWLEDGE`, `ACTION` and `INSTRUMENT` used in the pipeline head, they just define the knowledge, action or instrument as single line after the command
|
|
43472
|
+
* - KNOWLEDGE Look at https://en.wikipedia.org/wiki/Artificial_intelligence
|
|
43473
|
+
* 2) `KNOWLEDGE SECTION` which has short form `KNOWLEDGE` is used in the sectiom, does not refer the line itself, but the content of the section block
|
|
43474
|
+
* - KNOWLEDGE SECTION
|
|
43475
|
+
*
|
|
43476
|
+
* ```
|
|
43477
|
+
* Look at https://en.wikipedia.org/wiki/Artificial_intelligence
|
|
43478
|
+
* ```
|
|
43479
|
+
*/
|
|
43480
|
+
|
|
43365
43481
|
/**
|
|
43366
43482
|
* Parses the url command
|
|
43367
43483
|
*
|
|
@@ -43815,6 +43931,242 @@ function parseCommandVariant(input) {
|
|
|
43815
43931
|
return null;
|
|
43816
43932
|
}
|
|
43817
43933
|
|
|
43934
|
+
/**
|
|
43935
|
+
* Utility function to extract all list items from markdown
|
|
43936
|
+
*
|
|
43937
|
+
* Note: It works with both ul and ol
|
|
43938
|
+
* Note: It omits list items in code blocks
|
|
43939
|
+
* Note: It flattens nested lists
|
|
43940
|
+
* Note: It can not work with html syntax and comments
|
|
43941
|
+
*
|
|
43942
|
+
* @param markdown any valid markdown
|
|
43943
|
+
* @returns An array of strings, each representing an individual list item found in the markdown
|
|
43944
|
+
*
|
|
43945
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
43946
|
+
*/
|
|
43947
|
+
function extractAllListItemsFromMarkdown(markdown) {
|
|
43948
|
+
const lines = markdown.split(/\r?\n/);
|
|
43949
|
+
const listItems = [];
|
|
43950
|
+
let isInCodeBlock = false;
|
|
43951
|
+
for (const line of lines) {
|
|
43952
|
+
const trimmedLine = line.trim();
|
|
43953
|
+
if (trimmedLine.startsWith('```')) {
|
|
43954
|
+
isInCodeBlock = !isInCodeBlock;
|
|
43955
|
+
}
|
|
43956
|
+
if (!isInCodeBlock && (trimmedLine.startsWith('-') || trimmedLine.match(/^\d+\./))) {
|
|
43957
|
+
const listItem = trimmedLine.replace(/^-|\d+\./, '').trim();
|
|
43958
|
+
listItems.push(listItem);
|
|
43959
|
+
}
|
|
43960
|
+
}
|
|
43961
|
+
return listItems;
|
|
43962
|
+
}
|
|
43963
|
+
|
|
43964
|
+
/**
|
|
43965
|
+
* Builds a short file/url identification block for parse errors.
|
|
43966
|
+
*
|
|
43967
|
+
* @private internal utility of `parsePipeline`
|
|
43968
|
+
*/
|
|
43969
|
+
function getPipelineIdentification($pipelineJson) {
|
|
43970
|
+
// Note: This is a 😐 implementation of [🚞]
|
|
43971
|
+
const pipelineIdentificationParts = [];
|
|
43972
|
+
if ($pipelineJson.sourceFile !== undefined) {
|
|
43973
|
+
pipelineIdentificationParts.push(`File: ${$pipelineJson.sourceFile}`);
|
|
43974
|
+
}
|
|
43975
|
+
if ($pipelineJson.pipelineUrl !== undefined) {
|
|
43976
|
+
pipelineIdentificationParts.push(`Url: ${$pipelineJson.pipelineUrl}`);
|
|
43977
|
+
}
|
|
43978
|
+
return pipelineIdentificationParts.join('\n');
|
|
43979
|
+
}
|
|
43980
|
+
|
|
43981
|
+
/**
|
|
43982
|
+
* Merges one parameter declaration into the mutable pipeline parameter list.
|
|
43983
|
+
*
|
|
43984
|
+
* @private internal utility of `parsePipeline`
|
|
43985
|
+
*/
|
|
43986
|
+
function defineParameter($pipelineJson, parameterCommand) {
|
|
43987
|
+
const { parameterName, parameterDescription, isInput, isOutput } = parameterCommand;
|
|
43988
|
+
if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
|
|
43989
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
43990
|
+
Parameter name {${parameterName}} is reserved and cannot be used as resulting parameter name
|
|
43991
|
+
|
|
43992
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
43993
|
+
`) /* <- TODO: [🚞] */);
|
|
43994
|
+
}
|
|
43995
|
+
const existingParameter = $pipelineJson.parameters.find((parameter) => parameter.name === parameterName);
|
|
43996
|
+
if (existingParameter &&
|
|
43997
|
+
existingParameter.description &&
|
|
43998
|
+
existingParameter.description !== parameterDescription &&
|
|
43999
|
+
parameterDescription) {
|
|
44000
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
44001
|
+
Parameter \`{${parameterName}}\` is defined multiple times with different description:
|
|
44002
|
+
|
|
44003
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
44004
|
+
|
|
44005
|
+
First definition:
|
|
44006
|
+
${block(existingParameter.description || '[undefined]')}
|
|
44007
|
+
|
|
44008
|
+
Second definition:
|
|
44009
|
+
${block(parameterDescription || '[undefined]')}
|
|
44010
|
+
`));
|
|
44011
|
+
}
|
|
44012
|
+
if (existingParameter) {
|
|
44013
|
+
if (parameterDescription) {
|
|
44014
|
+
existingParameter.description = parameterDescription;
|
|
44015
|
+
}
|
|
44016
|
+
existingParameter.isInput = existingParameter.isInput || isInput;
|
|
44017
|
+
existingParameter.isOutput = existingParameter.isOutput || isOutput;
|
|
44018
|
+
return;
|
|
44019
|
+
}
|
|
44020
|
+
$pipelineJson.parameters.push({
|
|
44021
|
+
name: parameterName,
|
|
44022
|
+
description: parameterDescription || undefined,
|
|
44023
|
+
isInput,
|
|
44024
|
+
isOutput,
|
|
44025
|
+
});
|
|
44026
|
+
}
|
|
44027
|
+
|
|
44028
|
+
/**
|
|
44029
|
+
* Removes fenced code blocks when deriving human-readable section descriptions.
|
|
44030
|
+
*
|
|
44031
|
+
* @private internal utility of `extractPipelineDescription`
|
|
44032
|
+
*/
|
|
44033
|
+
const DESCRIPTION_CODE_BLOCK_REGEXP = /^```.*^```/gms;
|
|
44034
|
+
/**
|
|
44035
|
+
* Removes blockquote lines when deriving human-readable section descriptions.
|
|
44036
|
+
*
|
|
44037
|
+
* @private internal utility of `extractPipelineDescription`
|
|
44038
|
+
*/
|
|
44039
|
+
const DESCRIPTION_BLOCKQUOTE_REGEXP = /^>.*$/gm;
|
|
44040
|
+
/**
|
|
44041
|
+
* Removes list items and return statements when deriving human-readable section descriptions.
|
|
44042
|
+
*
|
|
44043
|
+
* @private internal utility of `extractPipelineDescription`
|
|
44044
|
+
*/
|
|
44045
|
+
const DESCRIPTION_LIST_ITEM_REGEXP = /^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm;
|
|
44046
|
+
/**
|
|
44047
|
+
* Extracts the plain-text description from a head or task section body.
|
|
44048
|
+
*
|
|
44049
|
+
* @private internal utility of `parsePipeline`
|
|
44050
|
+
*/
|
|
44051
|
+
function extractPipelineDescription(sectionContent) {
|
|
44052
|
+
let description = sectionContent;
|
|
44053
|
+
description = description.split(DESCRIPTION_CODE_BLOCK_REGEXP).join('');
|
|
44054
|
+
description = description.split(DESCRIPTION_BLOCKQUOTE_REGEXP).join('');
|
|
44055
|
+
description = description.split(DESCRIPTION_LIST_ITEM_REGEXP).join('');
|
|
44056
|
+
description = spaceTrim$1(description);
|
|
44057
|
+
if (description === '') {
|
|
44058
|
+
return undefined;
|
|
44059
|
+
}
|
|
44060
|
+
return description;
|
|
44061
|
+
}
|
|
44062
|
+
|
|
44063
|
+
/**
|
|
44064
|
+
* Applies the pipeline head title, description, and head-level commands.
|
|
44065
|
+
*
|
|
44066
|
+
* @private internal utility of `parsePipeline`
|
|
44067
|
+
*/
|
|
44068
|
+
function applyPipelineHead(pipelineHead, $pipelineJson) {
|
|
44069
|
+
$pipelineJson.title = pipelineHead.title;
|
|
44070
|
+
$pipelineJson.description = extractPipelineDescription(pipelineHead.content);
|
|
44071
|
+
for (const listItem of extractAllListItemsFromMarkdown(pipelineHead.content)) {
|
|
44072
|
+
applyPipelineHeadCommand(listItem, $pipelineJson);
|
|
44073
|
+
}
|
|
44074
|
+
}
|
|
44075
|
+
/**
|
|
44076
|
+
* Parses and applies one command declared in the pipeline head.
|
|
44077
|
+
*
|
|
44078
|
+
* @private internal utility of `applyPipelineHead`
|
|
44079
|
+
*/
|
|
44080
|
+
function applyPipelineHeadCommand(listItem, $pipelineJson) {
|
|
44081
|
+
const command = parseCommand(listItem, 'PIPELINE_HEAD');
|
|
44082
|
+
const commandParser = getParserForCommand(command);
|
|
44083
|
+
if (commandParser.isUsedInPipelineHead !== true /* <- Note: [🦦][4] */) {
|
|
44084
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
44085
|
+
Command \`${command.type}\` is not allowed in the head of the pipeline ONLY at the pipeline task
|
|
44086
|
+
|
|
44087
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
44088
|
+
`)); // <- TODO: [🚞]
|
|
44089
|
+
}
|
|
44090
|
+
try {
|
|
44091
|
+
commandParser.$applyToPipelineJson(command, $pipelineJson);
|
|
44092
|
+
// <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitly
|
|
44093
|
+
}
|
|
44094
|
+
catch (error) {
|
|
44095
|
+
if (!(error instanceof ParseError)) {
|
|
44096
|
+
throw error;
|
|
44097
|
+
}
|
|
44098
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
44099
|
+
Command ${command.type} failed to apply to the pipeline
|
|
44100
|
+
|
|
44101
|
+
The error:
|
|
44102
|
+
${block(error.message)}
|
|
44103
|
+
|
|
44104
|
+
Raw command:
|
|
44105
|
+
- ${listItem}
|
|
44106
|
+
|
|
44107
|
+
Usage of ${command.type}:
|
|
44108
|
+
${block(commandParser.examples.map((example) => `- ${example}`).join('\n'))}
|
|
44109
|
+
|
|
44110
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
44111
|
+
`)); // <- TODO: [🚞]
|
|
44112
|
+
}
|
|
44113
|
+
if (command.type === 'PARAMETER') {
|
|
44114
|
+
defineParameter($pipelineJson, command);
|
|
44115
|
+
// <- Note: [🍣]
|
|
44116
|
+
}
|
|
44117
|
+
}
|
|
44118
|
+
|
|
44119
|
+
/**
|
|
44120
|
+
* Creates the mutable pipeline JSON structure used throughout parsing.
|
|
44121
|
+
*
|
|
44122
|
+
* @private internal utility of `parsePipeline`
|
|
44123
|
+
*/
|
|
44124
|
+
function createInitialPipelineJson(pipelineString) {
|
|
44125
|
+
return {
|
|
44126
|
+
title: DEFAULT_BOOK_TITLE,
|
|
44127
|
+
parameters: [],
|
|
44128
|
+
tasks: [],
|
|
44129
|
+
knowledgeSources: [],
|
|
44130
|
+
knowledgePieces: [],
|
|
44131
|
+
personas: [],
|
|
44132
|
+
preparations: [],
|
|
44133
|
+
sources: [
|
|
44134
|
+
{
|
|
44135
|
+
type: 'BOOK',
|
|
44136
|
+
path: null,
|
|
44137
|
+
// <- TODO: !!6 Pass here path of the file
|
|
44138
|
+
content: pipelineString,
|
|
44139
|
+
},
|
|
44140
|
+
],
|
|
44141
|
+
};
|
|
44142
|
+
}
|
|
44143
|
+
|
|
44144
|
+
/**
|
|
44145
|
+
* Creates stable unique task names for duplicate section titles.
|
|
44146
|
+
*
|
|
44147
|
+
* @private internal utility of `parsePipeline`
|
|
44148
|
+
*/
|
|
44149
|
+
function createUniqueSectionNameResolver(pipelineSections) {
|
|
44150
|
+
const sectionCounts = {};
|
|
44151
|
+
for (const pipelineSection of pipelineSections) {
|
|
44152
|
+
const sectionName = titleToName(pipelineSection.title);
|
|
44153
|
+
if (sectionCounts[sectionName] === undefined) {
|
|
44154
|
+
sectionCounts[sectionName] = { count: 0, currentIndex: 0 };
|
|
44155
|
+
}
|
|
44156
|
+
sectionCounts[sectionName].count++;
|
|
44157
|
+
}
|
|
44158
|
+
return (title) => {
|
|
44159
|
+
const sectionName = titleToName(title);
|
|
44160
|
+
const sectionCount = sectionCounts[sectionName];
|
|
44161
|
+
if (sectionCount.count === 1) {
|
|
44162
|
+
return sectionName;
|
|
44163
|
+
}
|
|
44164
|
+
const nameWithSuffix = `${sectionName}-${sectionCount.currentIndex}`;
|
|
44165
|
+
sectionCount.currentIndex++;
|
|
44166
|
+
return nameWithSuffix;
|
|
44167
|
+
};
|
|
44168
|
+
}
|
|
44169
|
+
|
|
43818
44170
|
/**
|
|
43819
44171
|
* Extracts the interface (input and output parameters) from a pipeline.
|
|
43820
44172
|
*
|
|
@@ -44076,12 +44428,261 @@ const HIGH_LEVEL_ABSTRACTIONS = [
|
|
|
44076
44428
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44077
44429
|
|
|
44078
44430
|
/**
|
|
44079
|
-
*
|
|
44431
|
+
* Applies postprocessing and exports the parsed pipeline JSON.
|
|
44080
44432
|
*
|
|
44081
|
-
* @private internal
|
|
44433
|
+
* @private internal utility of `parsePipeline`
|
|
44082
44434
|
*/
|
|
44083
|
-
|
|
44084
|
-
|
|
44435
|
+
function finalizeParsedPipeline($pipelineJson) {
|
|
44436
|
+
applyImplicitParameterDirections($pipelineJson);
|
|
44437
|
+
removeUndefinedValuesFromPipeline($pipelineJson);
|
|
44438
|
+
applySyncHighLevelAbstractions($pipelineJson);
|
|
44439
|
+
ensurePipelineFormfactor($pipelineJson);
|
|
44440
|
+
return exportParsedPipelineJson($pipelineJson);
|
|
44441
|
+
}
|
|
44442
|
+
/**
|
|
44443
|
+
* Applies default INPUT/OUTPUT flags when the author did not specify them explicitly.
|
|
44444
|
+
*
|
|
44445
|
+
* @private internal utility of `finalizeParsedPipeline`
|
|
44446
|
+
*/
|
|
44447
|
+
function applyImplicitParameterDirections($pipelineJson) {
|
|
44448
|
+
markImplicitInputParameters($pipelineJson);
|
|
44449
|
+
markImplicitOutputParameters($pipelineJson);
|
|
44450
|
+
}
|
|
44451
|
+
/**
|
|
44452
|
+
* Marks non-result parameters as pipeline inputs when no input was declared.
|
|
44453
|
+
*
|
|
44454
|
+
* @private internal utility of `finalizeParsedPipeline`
|
|
44455
|
+
*/
|
|
44456
|
+
function markImplicitInputParameters($pipelineJson) {
|
|
44457
|
+
if ($pipelineJson.parameters.some((parameter) => parameter.isInput)) {
|
|
44458
|
+
return;
|
|
44459
|
+
}
|
|
44460
|
+
for (const parameter of $pipelineJson.parameters) {
|
|
44461
|
+
const isThisParameterResulting = $pipelineJson.tasks.some((task) => task.resultingParameterName === parameter.name);
|
|
44462
|
+
if (!isThisParameterResulting) {
|
|
44463
|
+
parameter.isInput = true;
|
|
44464
|
+
// <- TODO: [💔] Why this is making typescript error in vscode but not in cli
|
|
44465
|
+
// > Type 'true' is not assignable to type 'false'.ts(2322)
|
|
44466
|
+
// > (property) isInput: false
|
|
44467
|
+
// > The parameter is input of the pipeline The parameter is NOT input of the pipeline
|
|
44468
|
+
}
|
|
44469
|
+
}
|
|
44470
|
+
}
|
|
44471
|
+
/**
|
|
44472
|
+
* Marks every non-input parameter as output when no output was declared.
|
|
44473
|
+
*
|
|
44474
|
+
* @private internal utility of `finalizeParsedPipeline`
|
|
44475
|
+
*/
|
|
44476
|
+
function markImplicitOutputParameters($pipelineJson) {
|
|
44477
|
+
if ($pipelineJson.parameters.some((parameter) => parameter.isOutput)) {
|
|
44478
|
+
return;
|
|
44479
|
+
}
|
|
44480
|
+
for (const parameter of $pipelineJson.parameters) {
|
|
44481
|
+
if (!parameter.isInput) {
|
|
44482
|
+
parameter.isOutput = true;
|
|
44483
|
+
// <- TODO: [💔]
|
|
44484
|
+
}
|
|
44485
|
+
}
|
|
44486
|
+
}
|
|
44487
|
+
/**
|
|
44488
|
+
* Removes `undefined` properties from serialized tasks and parameters.
|
|
44489
|
+
*
|
|
44490
|
+
* @private internal utility of `finalizeParsedPipeline`
|
|
44491
|
+
*/
|
|
44492
|
+
function removeUndefinedValuesFromPipeline($pipelineJson) {
|
|
44493
|
+
$pipelineJson.tasks.forEach(removeUndefinedProperties);
|
|
44494
|
+
$pipelineJson.parameters.forEach(removeUndefinedProperties);
|
|
44495
|
+
}
|
|
44496
|
+
/**
|
|
44497
|
+
* Deletes all own properties with `undefined` values from a mutable JSON entity.
|
|
44498
|
+
*
|
|
44499
|
+
* @private internal utility of `finalizeParsedPipeline`
|
|
44500
|
+
*/
|
|
44501
|
+
function removeUndefinedProperties(entity) {
|
|
44502
|
+
for (const [key, value] of Object.entries(entity)) {
|
|
44503
|
+
if (value === undefined) {
|
|
44504
|
+
delete entity[key];
|
|
44505
|
+
}
|
|
44506
|
+
}
|
|
44507
|
+
}
|
|
44508
|
+
/**
|
|
44509
|
+
* Applies all sync-only high-level abstractions after parsing.
|
|
44510
|
+
*
|
|
44511
|
+
* @private internal utility of `finalizeParsedPipeline`
|
|
44512
|
+
*/
|
|
44513
|
+
function applySyncHighLevelAbstractions($pipelineJson) {
|
|
44514
|
+
for (const highLevelAbstraction of HIGH_LEVEL_ABSTRACTIONS.filter(({ type }) => type === 'SYNC')) {
|
|
44515
|
+
highLevelAbstraction.$applyToPipelineJson($pipelineJson);
|
|
44516
|
+
}
|
|
44517
|
+
}
|
|
44518
|
+
/**
|
|
44519
|
+
* Ensures parsed pipelines always have the default `GENERIC` formfactor.
|
|
44520
|
+
*
|
|
44521
|
+
* @private internal utility of `finalizeParsedPipeline`
|
|
44522
|
+
*/
|
|
44523
|
+
function ensurePipelineFormfactor($pipelineJson) {
|
|
44524
|
+
// Note: [🔆] If formfactor is still not set, set it to 'GENERIC'
|
|
44525
|
+
if ($pipelineJson.formfactorName === undefined) {
|
|
44526
|
+
$pipelineJson.formfactorName = 'GENERIC';
|
|
44527
|
+
}
|
|
44528
|
+
}
|
|
44529
|
+
/**
|
|
44530
|
+
* Finalizes ordering and exports the parsed pipeline JSON.
|
|
44531
|
+
*
|
|
44532
|
+
* @private internal utility of `finalizeParsedPipeline`
|
|
44533
|
+
*/
|
|
44534
|
+
function exportParsedPipelineJson($pipelineJson) {
|
|
44535
|
+
return exportJson({
|
|
44536
|
+
name: 'pipelineJson',
|
|
44537
|
+
message: `Result of \`parsePipeline\``,
|
|
44538
|
+
order: ORDER_OF_PIPELINE_JSON,
|
|
44539
|
+
value: {
|
|
44540
|
+
formfactorName: 'GENERIC',
|
|
44541
|
+
// <- Note: [🔆] Setting `formfactorName` is redundant to satisfy the typescript
|
|
44542
|
+
...$pipelineJson,
|
|
44543
|
+
},
|
|
44544
|
+
});
|
|
44545
|
+
}
|
|
44546
|
+
// TODO: Use spaceTrim more effectively
|
|
44547
|
+
// TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
|
|
44548
|
+
// TODO: [♈] Probably move expectations from tasks to parameters
|
|
44549
|
+
// TODO: [🍙] Make some standard order of json properties
|
|
44550
|
+
|
|
44551
|
+
/**
|
|
44552
|
+
* Parses markdown section to title its level and content
|
|
44553
|
+
*
|
|
44554
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
44555
|
+
*/
|
|
44556
|
+
function parseMarkdownSection(value) {
|
|
44557
|
+
var _a, _b;
|
|
44558
|
+
const lines = value.split(/\r?\n/);
|
|
44559
|
+
if (!lines[0].startsWith('#')) {
|
|
44560
|
+
throw new ParseError('Markdown section must start with heading');
|
|
44561
|
+
}
|
|
44562
|
+
const title = lines[0].replace(/^#+\s*/, '');
|
|
44563
|
+
const level = (_b = (_a = lines[0].match(/^#+/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
|
|
44564
|
+
const content = spaceTrim$1(lines.slice(1).join('\n'));
|
|
44565
|
+
if (level < 1 || level > 6) {
|
|
44566
|
+
throw new ParseError('Markdown section must have heading level between 1 and 6');
|
|
44567
|
+
}
|
|
44568
|
+
return { title, level: level, content };
|
|
44569
|
+
}
|
|
44570
|
+
/**
|
|
44571
|
+
* Note: [🕞] In past (commit 42086e1603cbed506482997c00a8ee979af0a247) there was much more
|
|
44572
|
+
* sophisticated implementation of this function through parsing markdown into JSON structure
|
|
44573
|
+
* and flattening the actual structure
|
|
44574
|
+
* NOW we are working just with markdown string and its good enough
|
|
44575
|
+
*/
|
|
44576
|
+
|
|
44577
|
+
/**
|
|
44578
|
+
* Splits the markdown into sections by headings
|
|
44579
|
+
*
|
|
44580
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
44581
|
+
*/
|
|
44582
|
+
function splitMarkdownIntoSections(markdown) {
|
|
44583
|
+
const lines = markdown.split(/\r?\n/);
|
|
44584
|
+
const sections = [];
|
|
44585
|
+
// TODO: [🧽] DRY
|
|
44586
|
+
let currentType = 'MARKDOWN';
|
|
44587
|
+
let buffer = [];
|
|
44588
|
+
const finishSection = () => {
|
|
44589
|
+
if (buffer.length === 0) {
|
|
44590
|
+
return;
|
|
44591
|
+
}
|
|
44592
|
+
let section = spaceTrim$1(buffer.join('\n'));
|
|
44593
|
+
if (section === '') {
|
|
44594
|
+
return;
|
|
44595
|
+
}
|
|
44596
|
+
if (!section.startsWith('#')) {
|
|
44597
|
+
section = `# ${DEFAULT_BOOK_TITLE}\n\n${section}`;
|
|
44598
|
+
}
|
|
44599
|
+
sections.push(section);
|
|
44600
|
+
buffer = [];
|
|
44601
|
+
};
|
|
44602
|
+
for (const line of lines) {
|
|
44603
|
+
if (currentType === 'MARKDOWN') {
|
|
44604
|
+
if (line.startsWith('#')) {
|
|
44605
|
+
finishSection();
|
|
44606
|
+
}
|
|
44607
|
+
buffer.push(line);
|
|
44608
|
+
if (line.startsWith('```')) {
|
|
44609
|
+
currentType = 'CODE_BLOCK';
|
|
44610
|
+
}
|
|
44611
|
+
else if (line.includes('<!--')) {
|
|
44612
|
+
currentType = 'COMMENT';
|
|
44613
|
+
}
|
|
44614
|
+
}
|
|
44615
|
+
else if (currentType === 'CODE_BLOCK') {
|
|
44616
|
+
buffer.push(line);
|
|
44617
|
+
if (line.startsWith('```')) {
|
|
44618
|
+
currentType = 'MARKDOWN';
|
|
44619
|
+
}
|
|
44620
|
+
}
|
|
44621
|
+
else if (currentType === 'COMMENT') {
|
|
44622
|
+
buffer.push(line);
|
|
44623
|
+
if (line.includes('-->')) {
|
|
44624
|
+
currentType = 'MARKDOWN';
|
|
44625
|
+
}
|
|
44626
|
+
}
|
|
44627
|
+
}
|
|
44628
|
+
finishSection();
|
|
44629
|
+
return sections;
|
|
44630
|
+
}
|
|
44631
|
+
/**
|
|
44632
|
+
* TODO: [🏛] This can be part of markdown builder
|
|
44633
|
+
* Note: [🕞] In past (commit 42086e1603cbed506482997c00a8ee979af0a247) there was much more
|
|
44634
|
+
* sophisticated implementation of this function through parsing markdown into JSON structure
|
|
44635
|
+
* and flattening the actual structure
|
|
44636
|
+
* NOW we are working just with markdown string and its good enough
|
|
44637
|
+
*/
|
|
44638
|
+
|
|
44639
|
+
/**
|
|
44640
|
+
* Splits the prepared markdown into the pipeline head and task sections.
|
|
44641
|
+
*
|
|
44642
|
+
* @private internal utility of `parsePipeline`
|
|
44643
|
+
*/
|
|
44644
|
+
function parsePreparedPipelineSections(pipelineString, $pipelineJson) {
|
|
44645
|
+
const [pipelineHead, ...pipelineSections] = splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection); /* <- Note: [🥞] */
|
|
44646
|
+
assertPipelineSectionsStructure(pipelineHead, pipelineSections, $pipelineJson);
|
|
44647
|
+
return {
|
|
44648
|
+
pipelineHead,
|
|
44649
|
+
pipelineSections,
|
|
44650
|
+
};
|
|
44651
|
+
}
|
|
44652
|
+
/**
|
|
44653
|
+
* Ensures the flattened markdown has exactly one h1 head followed by only h2 sections.
|
|
44654
|
+
*
|
|
44655
|
+
* @private internal utility of `parsePreparedPipelineSections`
|
|
44656
|
+
*/
|
|
44657
|
+
function assertPipelineSectionsStructure(pipelineHead, pipelineSections, $pipelineJson) {
|
|
44658
|
+
if (pipelineHead === undefined) {
|
|
44659
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
44660
|
+
Pipeline head is not defined
|
|
44661
|
+
|
|
44662
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
44663
|
+
|
|
44664
|
+
This should never happen, because the pipeline already flattened
|
|
44665
|
+
`));
|
|
44666
|
+
}
|
|
44667
|
+
if (pipelineHead.level !== 1) {
|
|
44668
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
44669
|
+
Pipeline head is not h1
|
|
44670
|
+
|
|
44671
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
44672
|
+
|
|
44673
|
+
This should never happen, because the pipeline already flattened
|
|
44674
|
+
`));
|
|
44675
|
+
}
|
|
44676
|
+
if (!pipelineSections.every((pipelineSection) => pipelineSection.level === 2)) {
|
|
44677
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
44678
|
+
Not every pipeline section is h2
|
|
44679
|
+
|
|
44680
|
+
${block(getPipelineIdentification($pipelineJson))}
|
|
44681
|
+
|
|
44682
|
+
This should never happen, because the pipeline already flattened
|
|
44683
|
+
`));
|
|
44684
|
+
}
|
|
44685
|
+
}
|
|
44085
44686
|
|
|
44086
44687
|
/**
|
|
44087
44688
|
* Number of padding lines to add at the end of the book content
|
|
@@ -44208,124 +44809,6 @@ function deflatePipeline(pipelineString) {
|
|
|
44208
44809
|
}
|
|
44209
44810
|
// TODO: Unit test
|
|
44210
44811
|
|
|
44211
|
-
/**
|
|
44212
|
-
* Utility function to extract all list items from markdown
|
|
44213
|
-
*
|
|
44214
|
-
* Note: It works with both ul and ol
|
|
44215
|
-
* Note: It omits list items in code blocks
|
|
44216
|
-
* Note: It flattens nested lists
|
|
44217
|
-
* Note: It can not work with html syntax and comments
|
|
44218
|
-
*
|
|
44219
|
-
* @param markdown any valid markdown
|
|
44220
|
-
* @returns An array of strings, each representing an individual list item found in the markdown
|
|
44221
|
-
*
|
|
44222
|
-
* @public exported from `@promptbook/markdown-utils`
|
|
44223
|
-
*/
|
|
44224
|
-
function extractAllListItemsFromMarkdown(markdown) {
|
|
44225
|
-
const lines = markdown.split(/\r?\n/);
|
|
44226
|
-
const listItems = [];
|
|
44227
|
-
let isInCodeBlock = false;
|
|
44228
|
-
for (const line of lines) {
|
|
44229
|
-
const trimmedLine = line.trim();
|
|
44230
|
-
if (trimmedLine.startsWith('```')) {
|
|
44231
|
-
isInCodeBlock = !isInCodeBlock;
|
|
44232
|
-
}
|
|
44233
|
-
if (!isInCodeBlock && (trimmedLine.startsWith('-') || trimmedLine.match(/^\d+\./))) {
|
|
44234
|
-
const listItem = trimmedLine.replace(/^-|\d+\./, '').trim();
|
|
44235
|
-
listItems.push(listItem);
|
|
44236
|
-
}
|
|
44237
|
-
}
|
|
44238
|
-
return listItems;
|
|
44239
|
-
}
|
|
44240
|
-
|
|
44241
|
-
/**
|
|
44242
|
-
* Parses markdown section to title its level and content
|
|
44243
|
-
*
|
|
44244
|
-
* @public exported from `@promptbook/markdown-utils`
|
|
44245
|
-
*/
|
|
44246
|
-
function parseMarkdownSection(value) {
|
|
44247
|
-
var _a, _b;
|
|
44248
|
-
const lines = value.split(/\r?\n/);
|
|
44249
|
-
if (!lines[0].startsWith('#')) {
|
|
44250
|
-
throw new ParseError('Markdown section must start with heading');
|
|
44251
|
-
}
|
|
44252
|
-
const title = lines[0].replace(/^#+\s*/, '');
|
|
44253
|
-
const level = (_b = (_a = lines[0].match(/^#+/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
|
|
44254
|
-
const content = spaceTrim$1(lines.slice(1).join('\n'));
|
|
44255
|
-
if (level < 1 || level > 6) {
|
|
44256
|
-
throw new ParseError('Markdown section must have heading level between 1 and 6');
|
|
44257
|
-
}
|
|
44258
|
-
return { title, level: level, content };
|
|
44259
|
-
}
|
|
44260
|
-
/**
|
|
44261
|
-
* Note: [🕞] In past (commit 42086e1603cbed506482997c00a8ee979af0a247) there was much more
|
|
44262
|
-
* sophisticated implementation of this function through parsing markdown into JSON structure
|
|
44263
|
-
* and flattening the actual structure
|
|
44264
|
-
* NOW we are working just with markdown string and its good enough
|
|
44265
|
-
*/
|
|
44266
|
-
|
|
44267
|
-
/**
|
|
44268
|
-
* Splits the markdown into sections by headings
|
|
44269
|
-
*
|
|
44270
|
-
* @public exported from `@promptbook/markdown-utils`
|
|
44271
|
-
*/
|
|
44272
|
-
function splitMarkdownIntoSections(markdown) {
|
|
44273
|
-
const lines = markdown.split(/\r?\n/);
|
|
44274
|
-
const sections = [];
|
|
44275
|
-
// TODO: [🧽] DRY
|
|
44276
|
-
let currentType = 'MARKDOWN';
|
|
44277
|
-
let buffer = [];
|
|
44278
|
-
const finishSection = () => {
|
|
44279
|
-
if (buffer.length === 0) {
|
|
44280
|
-
return;
|
|
44281
|
-
}
|
|
44282
|
-
let section = spaceTrim$1(buffer.join('\n'));
|
|
44283
|
-
if (section === '') {
|
|
44284
|
-
return;
|
|
44285
|
-
}
|
|
44286
|
-
if (!section.startsWith('#')) {
|
|
44287
|
-
section = `# ${DEFAULT_BOOK_TITLE}\n\n${section}`;
|
|
44288
|
-
}
|
|
44289
|
-
sections.push(section);
|
|
44290
|
-
buffer = [];
|
|
44291
|
-
};
|
|
44292
|
-
for (const line of lines) {
|
|
44293
|
-
if (currentType === 'MARKDOWN') {
|
|
44294
|
-
if (line.startsWith('#')) {
|
|
44295
|
-
finishSection();
|
|
44296
|
-
}
|
|
44297
|
-
buffer.push(line);
|
|
44298
|
-
if (line.startsWith('```')) {
|
|
44299
|
-
currentType = 'CODE_BLOCK';
|
|
44300
|
-
}
|
|
44301
|
-
else if (line.includes('<!--')) {
|
|
44302
|
-
currentType = 'COMMENT';
|
|
44303
|
-
}
|
|
44304
|
-
}
|
|
44305
|
-
else if (currentType === 'CODE_BLOCK') {
|
|
44306
|
-
buffer.push(line);
|
|
44307
|
-
if (line.startsWith('```')) {
|
|
44308
|
-
currentType = 'MARKDOWN';
|
|
44309
|
-
}
|
|
44310
|
-
}
|
|
44311
|
-
else if (currentType === 'COMMENT') {
|
|
44312
|
-
buffer.push(line);
|
|
44313
|
-
if (line.includes('-->')) {
|
|
44314
|
-
currentType = 'MARKDOWN';
|
|
44315
|
-
}
|
|
44316
|
-
}
|
|
44317
|
-
}
|
|
44318
|
-
finishSection();
|
|
44319
|
-
return sections;
|
|
44320
|
-
}
|
|
44321
|
-
/**
|
|
44322
|
-
* TODO: [🏛] This can be part of markdown builder
|
|
44323
|
-
* Note: [🕞] In past (commit 42086e1603cbed506482997c00a8ee979af0a247) there was much more
|
|
44324
|
-
* sophisticated implementation of this function through parsing markdown into JSON structure
|
|
44325
|
-
* and flattening the actual structure
|
|
44326
|
-
* NOW we are working just with markdown string and its good enough
|
|
44327
|
-
*/
|
|
44328
|
-
|
|
44329
44812
|
/**
|
|
44330
44813
|
* Normalizes the markdown by flattening the structure
|
|
44331
44814
|
*
|
|
@@ -44367,111 +44850,15 @@ function flattenMarkdown(markdown) {
|
|
|
44367
44850
|
/**
|
|
44368
44851
|
* Normalizes inline parameter mentions wrapped in code spans before markdown flattening.
|
|
44369
44852
|
*
|
|
44370
|
-
* @private internal utility of `
|
|
44853
|
+
* @private internal utility of `preparePipelineString`
|
|
44371
44854
|
*/
|
|
44372
44855
|
const INLINE_CODE_PARAMETER_REGEXP = /`\{(?<parameterName>[a-z0-9_]+)\}`/gi;
|
|
44373
44856
|
/**
|
|
44374
44857
|
* Normalizes inline return statements wrapped in code spans before markdown flattening.
|
|
44375
44858
|
*
|
|
44376
|
-
* @private internal utility of `
|
|
44859
|
+
* @private internal utility of `preparePipelineString`
|
|
44377
44860
|
*/
|
|
44378
44861
|
const INLINE_CODE_RETURN_PARAMETER_REGEXP = /`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi;
|
|
44379
|
-
/**
|
|
44380
|
-
* Matches the trailing return statement of a task section.
|
|
44381
|
-
*
|
|
44382
|
-
* @private internal utility of `parsePipeline`
|
|
44383
|
-
*/
|
|
44384
|
-
const RESULTING_PARAMETER_LINE_REGEXP = /^->\s*\{(?<resultingParamName>[a-z0-9_]+)\}/im;
|
|
44385
|
-
/**
|
|
44386
|
-
* Removes fenced code blocks when deriving human-readable section descriptions.
|
|
44387
|
-
*
|
|
44388
|
-
* @private internal utility of `parsePipeline`
|
|
44389
|
-
*/
|
|
44390
|
-
const DESCRIPTION_CODE_BLOCK_REGEXP = /^```.*^```/gms;
|
|
44391
|
-
/**
|
|
44392
|
-
* Removes blockquote lines when deriving human-readable section descriptions.
|
|
44393
|
-
*
|
|
44394
|
-
* @private internal utility of `parsePipeline`
|
|
44395
|
-
*/
|
|
44396
|
-
const DESCRIPTION_BLOCKQUOTE_REGEXP = /^>.*$/gm;
|
|
44397
|
-
/**
|
|
44398
|
-
* Removes list items and return statements when deriving human-readable section descriptions.
|
|
44399
|
-
*
|
|
44400
|
-
* @private internal utility of `parsePipeline`
|
|
44401
|
-
*/
|
|
44402
|
-
const DESCRIPTION_LIST_ITEM_REGEXP = /^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm;
|
|
44403
|
-
/**
|
|
44404
|
-
* Compile pipeline from string (markdown) format to JSON format synchronously
|
|
44405
|
-
*
|
|
44406
|
-
* Note: There are 3 similar functions:
|
|
44407
|
-
* - `compilePipeline` **(preferred)** - which properly compiles the promptbook and uses embedding for external knowledge
|
|
44408
|
-
* - `parsePipeline` - use only if you need to compile promptbook synchronously and it contains NO external knowledge
|
|
44409
|
-
* - `preparePipeline` - just one step in the compilation process
|
|
44410
|
-
*
|
|
44411
|
-
* Note: This function does not validate logic of the pipeline only the parsing
|
|
44412
|
-
* Note: This function acts as compilation process
|
|
44413
|
-
*
|
|
44414
|
-
* @param pipelineString {Promptbook} in string markdown format (.book.md)
|
|
44415
|
-
* @returns {Promptbook} compiled in JSON format (.bookc)
|
|
44416
|
-
* @throws {ParseError} if the promptbook string is not valid
|
|
44417
|
-
*
|
|
44418
|
-
* @public exported from `@promptbook/core`
|
|
44419
|
-
*/
|
|
44420
|
-
function parsePipeline(pipelineString) {
|
|
44421
|
-
const $pipelineJson = createInitialPipelineJson(pipelineString);
|
|
44422
|
-
const preparedPipelineString = preparePipelineString(pipelineString, $pipelineJson);
|
|
44423
|
-
const { pipelineHead, pipelineSections } = parsePreparedPipelineSections(preparedPipelineString, $pipelineJson);
|
|
44424
|
-
const getUniqueSectionName = createUniqueSectionNameResolver(pipelineSections);
|
|
44425
|
-
applyPipelineHead(pipelineHead, $pipelineJson);
|
|
44426
|
-
for (const pipelineSection of pipelineSections) {
|
|
44427
|
-
processPipelineSection(pipelineSection, $pipelineJson, getUniqueSectionName);
|
|
44428
|
-
}
|
|
44429
|
-
applyImplicitParameterDirections($pipelineJson);
|
|
44430
|
-
removeUndefinedValuesFromPipeline($pipelineJson);
|
|
44431
|
-
applySyncHighLevelAbstractions($pipelineJson);
|
|
44432
|
-
ensurePipelineFormfactor($pipelineJson);
|
|
44433
|
-
return exportParsedPipelineJson($pipelineJson);
|
|
44434
|
-
}
|
|
44435
|
-
/**
|
|
44436
|
-
* Creates the mutable pipeline JSON structure used throughout parsing.
|
|
44437
|
-
*
|
|
44438
|
-
* @private internal utility of `parsePipeline`
|
|
44439
|
-
*/
|
|
44440
|
-
function createInitialPipelineJson(pipelineString) {
|
|
44441
|
-
return {
|
|
44442
|
-
title: DEFAULT_BOOK_TITLE,
|
|
44443
|
-
parameters: [],
|
|
44444
|
-
tasks: [],
|
|
44445
|
-
knowledgeSources: [],
|
|
44446
|
-
knowledgePieces: [],
|
|
44447
|
-
personas: [],
|
|
44448
|
-
preparations: [],
|
|
44449
|
-
sources: [
|
|
44450
|
-
{
|
|
44451
|
-
type: 'BOOK',
|
|
44452
|
-
path: null,
|
|
44453
|
-
// <- TODO: !!6 Pass here path of the file
|
|
44454
|
-
content: pipelineString,
|
|
44455
|
-
},
|
|
44456
|
-
],
|
|
44457
|
-
};
|
|
44458
|
-
}
|
|
44459
|
-
/**
|
|
44460
|
-
* Builds a short file/url identification block for parse errors.
|
|
44461
|
-
*
|
|
44462
|
-
* @private internal utility of `parsePipeline`
|
|
44463
|
-
*/
|
|
44464
|
-
function getPipelineIdentification($pipelineJson) {
|
|
44465
|
-
// Note: This is a 😐 implementation of [🚞]
|
|
44466
|
-
const pipelineIdentificationParts = [];
|
|
44467
|
-
if ($pipelineJson.sourceFile !== undefined) {
|
|
44468
|
-
pipelineIdentificationParts.push(`File: ${$pipelineJson.sourceFile}`);
|
|
44469
|
-
}
|
|
44470
|
-
if ($pipelineJson.pipelineUrl !== undefined) {
|
|
44471
|
-
pipelineIdentificationParts.push(`Url: ${$pipelineJson.pipelineUrl}`);
|
|
44472
|
-
}
|
|
44473
|
-
return pipelineIdentificationParts.join('\n');
|
|
44474
|
-
}
|
|
44475
44862
|
/**
|
|
44476
44863
|
* Removes shebang/comments and normalizes markdown into a parseable pipeline form.
|
|
44477
44864
|
*
|
|
@@ -44491,7 +44878,7 @@ function preparePipelineString(pipelineString, $pipelineJson) {
|
|
|
44491
44878
|
/**
|
|
44492
44879
|
* Validates and removes the optional `#!` shebang line for `.book` files.
|
|
44493
44880
|
*
|
|
44494
|
-
* @private internal utility of `
|
|
44881
|
+
* @private internal utility of `preparePipelineString`
|
|
44495
44882
|
*/
|
|
44496
44883
|
function removePipelineShebang(pipelineString, $pipelineJson) {
|
|
44497
44884
|
if (!pipelineString.startsWith('#!')) {
|
|
@@ -44515,195 +44902,21 @@ function removePipelineShebang(pipelineString, $pipelineJson) {
|
|
|
44515
44902
|
}
|
|
44516
44903
|
return validatePipelineString(restLines.join('\n'));
|
|
44517
44904
|
}
|
|
44518
|
-
/**
|
|
44519
|
-
* Splits the prepared markdown into the pipeline head and task sections.
|
|
44520
|
-
*
|
|
44521
|
-
* @private internal utility of `parsePipeline`
|
|
44522
|
-
*/
|
|
44523
|
-
function parsePreparedPipelineSections(pipelineString, $pipelineJson) {
|
|
44524
|
-
const [pipelineHead, ...pipelineSections] = splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection); /* <- Note: [🥞] */
|
|
44525
|
-
assertPipelineSectionsStructure(pipelineHead, pipelineSections, $pipelineJson);
|
|
44526
|
-
return {
|
|
44527
|
-
pipelineHead,
|
|
44528
|
-
pipelineSections,
|
|
44529
|
-
};
|
|
44530
|
-
}
|
|
44531
|
-
/**
|
|
44532
|
-
* Ensures the flattened markdown has exactly one h1 head followed by only h2 sections.
|
|
44533
|
-
*
|
|
44534
|
-
* @private internal utility of `parsePipeline`
|
|
44535
|
-
*/
|
|
44536
|
-
function assertPipelineSectionsStructure(pipelineHead, pipelineSections, $pipelineJson) {
|
|
44537
|
-
if (pipelineHead === undefined) {
|
|
44538
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
44539
|
-
Pipeline head is not defined
|
|
44540
|
-
|
|
44541
|
-
${block(getPipelineIdentification($pipelineJson))}
|
|
44542
|
-
|
|
44543
|
-
This should never happen, because the pipeline already flattened
|
|
44544
|
-
`));
|
|
44545
|
-
}
|
|
44546
|
-
if (pipelineHead.level !== 1) {
|
|
44547
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
44548
|
-
Pipeline head is not h1
|
|
44549
|
-
|
|
44550
|
-
${block(getPipelineIdentification($pipelineJson))}
|
|
44551
|
-
|
|
44552
|
-
This should never happen, because the pipeline already flattened
|
|
44553
|
-
`));
|
|
44554
|
-
}
|
|
44555
|
-
if (!pipelineSections.every((pipelineSection) => pipelineSection.level === 2)) {
|
|
44556
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
44557
|
-
Not every pipeline section is h2
|
|
44558
|
-
|
|
44559
|
-
${block(getPipelineIdentification($pipelineJson))}
|
|
44560
|
-
|
|
44561
|
-
This should never happen, because the pipeline already flattened
|
|
44562
|
-
`));
|
|
44563
|
-
}
|
|
44564
|
-
}
|
|
44565
|
-
/**
|
|
44566
|
-
* Applies the pipeline head title, description, and head-level commands.
|
|
44567
|
-
*
|
|
44568
|
-
* @private internal utility of `parsePipeline`
|
|
44569
|
-
*/
|
|
44570
|
-
function applyPipelineHead(pipelineHead, $pipelineJson) {
|
|
44571
|
-
$pipelineJson.title = pipelineHead.title;
|
|
44572
|
-
$pipelineJson.description = extractPipelineDescription(pipelineHead.content);
|
|
44573
|
-
for (const listItem of extractAllListItemsFromMarkdown(pipelineHead.content)) {
|
|
44574
|
-
applyPipelineHeadCommand(listItem, $pipelineJson);
|
|
44575
|
-
}
|
|
44576
|
-
}
|
|
44577
|
-
/**
|
|
44578
|
-
* Extracts the plain-text description from a head or task section body.
|
|
44579
|
-
*
|
|
44580
|
-
* @private internal utility of `parsePipeline`
|
|
44581
|
-
*/
|
|
44582
|
-
function extractPipelineDescription(sectionContent) {
|
|
44583
|
-
let description = sectionContent;
|
|
44584
|
-
description = description.split(DESCRIPTION_CODE_BLOCK_REGEXP).join('');
|
|
44585
|
-
description = description.split(DESCRIPTION_BLOCKQUOTE_REGEXP).join('');
|
|
44586
|
-
description = description.split(DESCRIPTION_LIST_ITEM_REGEXP).join('');
|
|
44587
|
-
description = spaceTrim$1(description);
|
|
44588
|
-
if (description === '') {
|
|
44589
|
-
return undefined;
|
|
44590
|
-
}
|
|
44591
|
-
return description;
|
|
44592
|
-
}
|
|
44593
|
-
/**
|
|
44594
|
-
* Parses and applies one command declared in the pipeline head.
|
|
44595
|
-
*
|
|
44596
|
-
* @private internal utility of `parsePipeline`
|
|
44597
|
-
*/
|
|
44598
|
-
function applyPipelineHeadCommand(listItem, $pipelineJson) {
|
|
44599
|
-
const command = parseCommand(listItem, 'PIPELINE_HEAD');
|
|
44600
|
-
const commandParser = getParserForCommand(command);
|
|
44601
|
-
if (commandParser.isUsedInPipelineHead !== true /* <- Note: [🦦][4] */) {
|
|
44602
|
-
throw new ParseError(spaceTrim$1((block) => `
|
|
44603
|
-
Command \`${command.type}\` is not allowed in the head of the pipeline ONLY at the pipeline task
|
|
44604
|
-
|
|
44605
|
-
${block(getPipelineIdentification($pipelineJson))}
|
|
44606
|
-
`)); // <- TODO: [🚞]
|
|
44607
|
-
}
|
|
44608
|
-
try {
|
|
44609
|
-
commandParser.$applyToPipelineJson(command, $pipelineJson);
|
|
44610
|
-
// <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitly
|
|
44611
|
-
}
|
|
44612
|
-
catch (error) {
|
|
44613
|
-
if (!(error instanceof ParseError)) {
|
|
44614
|
-
throw error;
|
|
44615
|
-
}
|
|
44616
|
-
throw new ParseError(spaceTrim$1((block) => `
|
|
44617
|
-
Command ${command.type} failed to apply to the pipeline
|
|
44618
|
-
|
|
44619
|
-
The error:
|
|
44620
|
-
${block(error.message)}
|
|
44621
|
-
|
|
44622
|
-
Raw command:
|
|
44623
|
-
- ${listItem}
|
|
44624
|
-
|
|
44625
|
-
Usage of ${command.type}:
|
|
44626
|
-
${block(commandParser.examples.map((example) => `- ${example}`).join('\n'))}
|
|
44627
44905
|
|
|
44628
|
-
${block(getPipelineIdentification($pipelineJson))}
|
|
44629
|
-
`)); // <- TODO: [🚞]
|
|
44630
|
-
}
|
|
44631
|
-
if (command.type === 'PARAMETER') {
|
|
44632
|
-
defineParameter($pipelineJson, command);
|
|
44633
|
-
// <- Note: [🍣]
|
|
44634
|
-
}
|
|
44635
|
-
}
|
|
44636
44906
|
/**
|
|
44637
|
-
*
|
|
44907
|
+
* Supported script languages
|
|
44638
44908
|
*
|
|
44639
|
-
* @private internal
|
|
44909
|
+
* @private internal base for `ScriptLanguage`
|
|
44640
44910
|
*/
|
|
44641
|
-
|
|
44642
|
-
|
|
44643
|
-
if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
|
|
44644
|
-
throw new ParseError(spaceTrim$1((block) => `
|
|
44645
|
-
Parameter name {${parameterName}} is reserved and cannot be used as resulting parameter name
|
|
44646
|
-
|
|
44647
|
-
${block(getPipelineIdentification($pipelineJson))}
|
|
44648
|
-
`) /* <- TODO: [🚞] */);
|
|
44649
|
-
}
|
|
44650
|
-
const existingParameter = $pipelineJson.parameters.find((parameter) => parameter.name === parameterName);
|
|
44651
|
-
if (existingParameter &&
|
|
44652
|
-
existingParameter.description &&
|
|
44653
|
-
existingParameter.description !== parameterDescription &&
|
|
44654
|
-
parameterDescription) {
|
|
44655
|
-
throw new ParseError(spaceTrim$1((block) => `
|
|
44656
|
-
Parameter \`{${parameterName}}\` is defined multiple times with different description:
|
|
44657
|
-
|
|
44658
|
-
${block(getPipelineIdentification($pipelineJson))}
|
|
44659
|
-
|
|
44660
|
-
First definition:
|
|
44661
|
-
${block(existingParameter.description || '[undefined]')}
|
|
44911
|
+
const SUPPORTED_SCRIPT_LANGUAGES = ['javascript', 'typescript', 'python'];
|
|
44912
|
+
// <- TODO: [🏥] DRY
|
|
44662
44913
|
|
|
44663
|
-
Second definition:
|
|
44664
|
-
${block(parameterDescription || '[undefined]')}
|
|
44665
|
-
`));
|
|
44666
|
-
}
|
|
44667
|
-
if (existingParameter) {
|
|
44668
|
-
if (parameterDescription) {
|
|
44669
|
-
existingParameter.description = parameterDescription;
|
|
44670
|
-
}
|
|
44671
|
-
existingParameter.isInput = existingParameter.isInput || isInput;
|
|
44672
|
-
existingParameter.isOutput = existingParameter.isOutput || isOutput;
|
|
44673
|
-
return;
|
|
44674
|
-
}
|
|
44675
|
-
$pipelineJson.parameters.push({
|
|
44676
|
-
name: parameterName,
|
|
44677
|
-
description: parameterDescription || undefined,
|
|
44678
|
-
isInput,
|
|
44679
|
-
isOutput,
|
|
44680
|
-
});
|
|
44681
|
-
}
|
|
44682
44914
|
/**
|
|
44683
|
-
*
|
|
44915
|
+
* Matches the trailing return statement of a task section.
|
|
44684
44916
|
*
|
|
44685
|
-
* @private internal utility of `
|
|
44917
|
+
* @private internal utility of `processPipelineSection`
|
|
44686
44918
|
*/
|
|
44687
|
-
|
|
44688
|
-
const sectionCounts = {};
|
|
44689
|
-
for (const pipelineSection of pipelineSections) {
|
|
44690
|
-
const sectionName = titleToName(pipelineSection.title);
|
|
44691
|
-
if (sectionCounts[sectionName] === undefined) {
|
|
44692
|
-
sectionCounts[sectionName] = { count: 0, currentIndex: 0 };
|
|
44693
|
-
}
|
|
44694
|
-
sectionCounts[sectionName].count++;
|
|
44695
|
-
}
|
|
44696
|
-
return (title) => {
|
|
44697
|
-
const sectionName = titleToName(title);
|
|
44698
|
-
const sectionCount = sectionCounts[sectionName];
|
|
44699
|
-
if (sectionCount.count === 1) {
|
|
44700
|
-
return sectionName;
|
|
44701
|
-
}
|
|
44702
|
-
const nameWithSuffix = `${sectionName}-${sectionCount.currentIndex}`;
|
|
44703
|
-
sectionCount.currentIndex++;
|
|
44704
|
-
return nameWithSuffix;
|
|
44705
|
-
};
|
|
44706
|
-
}
|
|
44919
|
+
const RESULTING_PARAMETER_LINE_REGEXP = /^->\s*\{(?<resultingParamName>[a-z0-9_]+)\}/im;
|
|
44707
44920
|
/**
|
|
44708
44921
|
* Parses, applies, and persists one h2 task section.
|
|
44709
44922
|
*
|
|
@@ -44723,7 +44936,7 @@ function processPipelineSection(pipelineSection, $pipelineJson, getUniqueSection
|
|
|
44723
44936
|
/**
|
|
44724
44937
|
* Creates the mutable task JSON shell from one markdown section.
|
|
44725
44938
|
*
|
|
44726
|
-
* @private internal utility of `
|
|
44939
|
+
* @private internal utility of `processPipelineSection`
|
|
44727
44940
|
*/
|
|
44728
44941
|
function createTaskJsonFromSection(pipelineSection, getUniqueSectionName) {
|
|
44729
44942
|
const { language, content } = extractOneBlockFromMarkdown(pipelineSection.content);
|
|
@@ -44751,7 +44964,7 @@ function createTaskJsonFromSection(pipelineSection, getUniqueSectionName) {
|
|
|
44751
44964
|
/**
|
|
44752
44965
|
* Extracts the optional trailing `-> {parameter}` statement from a section body.
|
|
44753
44966
|
*
|
|
44754
|
-
* @private internal utility of `
|
|
44967
|
+
* @private internal utility of `processPipelineSection`
|
|
44755
44968
|
*/
|
|
44756
44969
|
function extractResultingParameterName(sectionContent) {
|
|
44757
44970
|
var _a;
|
|
@@ -44762,7 +44975,7 @@ function extractResultingParameterName(sectionContent) {
|
|
|
44762
44975
|
/**
|
|
44763
44976
|
* Parses all list-item commands declared inside one task section.
|
|
44764
44977
|
*
|
|
44765
|
-
* @private internal utility of `
|
|
44978
|
+
* @private internal utility of `processPipelineSection`
|
|
44766
44979
|
*/
|
|
44767
44980
|
function parsePipelineTaskCommands(sectionContent) {
|
|
44768
44981
|
return extractAllListItemsFromMarkdown(sectionContent).map((listItem) => ({
|
|
@@ -44773,7 +44986,7 @@ function parsePipelineTaskCommands(sectionContent) {
|
|
|
44773
44986
|
/**
|
|
44774
44987
|
* Applies the implicit default `PROMPT_TASK` section type when no SECTION command is present.
|
|
44775
44988
|
*
|
|
44776
|
-
* @private internal utility of `
|
|
44989
|
+
* @private internal utility of `processPipelineSection`
|
|
44777
44990
|
*/
|
|
44778
44991
|
function applyDefaultTaskSectionType($taskJson, commands, $pipelineJson) {
|
|
44779
44992
|
const isSectionCommandPresent = commands.some(({ command }) => command.type === 'SECTION');
|
|
@@ -44785,7 +44998,7 @@ function applyDefaultTaskSectionType($taskJson, commands, $pipelineJson) {
|
|
|
44785
44998
|
/**
|
|
44786
44999
|
* Parses and applies one command declared inside a task section.
|
|
44787
45000
|
*
|
|
44788
|
-
* @private internal utility of `
|
|
45001
|
+
* @private internal utility of `processPipelineSection`
|
|
44789
45002
|
*/
|
|
44790
45003
|
function applyPipelineTaskCommand(commandItem, $taskJson, $pipelineJson) {
|
|
44791
45004
|
const { listItem, command } = commandItem;
|
|
@@ -44836,7 +45049,7 @@ function applyPipelineTaskCommand(commandItem, $taskJson, $pipelineJson) {
|
|
|
44836
45049
|
/**
|
|
44837
45050
|
* Validates and stores the language for SCRIPT tasks.
|
|
44838
45051
|
*
|
|
44839
|
-
* @private internal utility of `
|
|
45052
|
+
* @private internal utility of `processPipelineSection`
|
|
44840
45053
|
*/
|
|
44841
45054
|
function applyScriptTaskLanguage($taskJson, language, $pipelineJson) {
|
|
44842
45055
|
const isScriptTask = $taskJson.taskType === 'SCRIPT_TASK';
|
|
@@ -44853,7 +45066,6 @@ function applyScriptTaskLanguage($taskJson, language, $pipelineJson) {
|
|
|
44853
45066
|
if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
|
|
44854
45067
|
throw new ParseError(spaceTrim$1((block) => `
|
|
44855
45068
|
Script language ${language} is not supported.
|
|
44856
|
-
|
|
44857
45069
|
Supported languages are:
|
|
44858
45070
|
${block(SUPPORTED_SCRIPT_LANGUAGES.join(', '))}
|
|
44859
45071
|
|
|
@@ -44864,7 +45076,7 @@ function applyScriptTaskLanguage($taskJson, language, $pipelineJson) {
|
|
|
44864
45076
|
/**
|
|
44865
45077
|
* Extracts task dependencies and ensures referenced parameters exist.
|
|
44866
45078
|
*
|
|
44867
|
-
* @private internal utility of `
|
|
45079
|
+
* @private internal utility of `processPipelineSection`
|
|
44868
45080
|
*/
|
|
44869
45081
|
function registerTaskDependentParameters($taskJson, $pipelineJson) {
|
|
44870
45082
|
$taskJson.dependentParameterNames = Array.from(extractParameterNamesFromTask($taskJson));
|
|
@@ -44882,7 +45094,7 @@ function registerTaskDependentParameters($taskJson, $pipelineJson) {
|
|
|
44882
45094
|
/**
|
|
44883
45095
|
* Removes transient parsing flags and persists real tasks into the pipeline JSON.
|
|
44884
45096
|
*
|
|
44885
|
-
* @private internal utility of `
|
|
45097
|
+
* @private internal utility of `processPipelineSection`
|
|
44886
45098
|
*/
|
|
44887
45099
|
function persistTaskIfNeeded($taskJson, $pipelineJson) {
|
|
44888
45100
|
/*
|
|
@@ -44911,119 +45123,38 @@ function persistTaskIfNeeded($taskJson, $pipelineJson) {
|
|
|
44911
45123
|
// TODO: [🍙] Maybe do reorder of `$taskJson` here
|
|
44912
45124
|
$pipelineJson.tasks.push($taskJson);
|
|
44913
45125
|
}
|
|
45126
|
+
|
|
44914
45127
|
/**
|
|
44915
|
-
*
|
|
44916
|
-
*
|
|
44917
|
-
* @private internal utility of `parsePipeline`
|
|
44918
|
-
*/
|
|
44919
|
-
function applyImplicitParameterDirections($pipelineJson) {
|
|
44920
|
-
markImplicitInputParameters($pipelineJson);
|
|
44921
|
-
markImplicitOutputParameters($pipelineJson);
|
|
44922
|
-
}
|
|
44923
|
-
/**
|
|
44924
|
-
* Marks non-result parameters as pipeline inputs when no input was declared.
|
|
44925
|
-
*
|
|
44926
|
-
* @private internal utility of `parsePipeline`
|
|
44927
|
-
*/
|
|
44928
|
-
function markImplicitInputParameters($pipelineJson) {
|
|
44929
|
-
if ($pipelineJson.parameters.some((parameter) => parameter.isInput)) {
|
|
44930
|
-
return;
|
|
44931
|
-
}
|
|
44932
|
-
for (const parameter of $pipelineJson.parameters) {
|
|
44933
|
-
const isThisParameterResulting = $pipelineJson.tasks.some((task) => task.resultingParameterName === parameter.name);
|
|
44934
|
-
if (!isThisParameterResulting) {
|
|
44935
|
-
parameter.isInput = true;
|
|
44936
|
-
// <- TODO: [💔] Why this is making typescript error in vscode but not in cli
|
|
44937
|
-
// > Type 'true' is not assignable to type 'false'.ts(2322)
|
|
44938
|
-
// > (property) isInput: false
|
|
44939
|
-
// > The parameter is input of the pipeline The parameter is NOT input of the pipeline
|
|
44940
|
-
}
|
|
44941
|
-
}
|
|
44942
|
-
}
|
|
44943
|
-
/**
|
|
44944
|
-
* Marks every non-input parameter as output when no output was declared.
|
|
44945
|
-
*
|
|
44946
|
-
* @private internal utility of `parsePipeline`
|
|
44947
|
-
*/
|
|
44948
|
-
function markImplicitOutputParameters($pipelineJson) {
|
|
44949
|
-
if ($pipelineJson.parameters.some((parameter) => parameter.isOutput)) {
|
|
44950
|
-
return;
|
|
44951
|
-
}
|
|
44952
|
-
for (const parameter of $pipelineJson.parameters) {
|
|
44953
|
-
if (!parameter.isInput) {
|
|
44954
|
-
parameter.isOutput = true;
|
|
44955
|
-
// <- TODO: [💔]
|
|
44956
|
-
}
|
|
44957
|
-
}
|
|
44958
|
-
}
|
|
44959
|
-
/**
|
|
44960
|
-
* Removes `undefined` properties from serialized tasks and parameters.
|
|
45128
|
+
* Compile pipeline from string (markdown) format to JSON format synchronously
|
|
44961
45129
|
*
|
|
44962
|
-
*
|
|
44963
|
-
|
|
44964
|
-
|
|
44965
|
-
|
|
44966
|
-
$pipelineJson.parameters.forEach(removeUndefinedProperties);
|
|
44967
|
-
}
|
|
44968
|
-
/**
|
|
44969
|
-
* Deletes all own properties with `undefined` values from a mutable JSON entity.
|
|
45130
|
+
* Note: There are 3 similar functions:
|
|
45131
|
+
* - `compilePipeline` **(preferred)** - which properly compiles the promptbook and uses embedding for external knowledge
|
|
45132
|
+
* - `parsePipeline` - use only if you need to compile promptbook synchronously and it contains NO external knowledge
|
|
45133
|
+
* - `preparePipeline` - just one step in the compilation process
|
|
44970
45134
|
*
|
|
44971
|
-
*
|
|
44972
|
-
|
|
44973
|
-
function removeUndefinedProperties(entity) {
|
|
44974
|
-
for (const [key, value] of Object.entries(entity)) {
|
|
44975
|
-
if (value === undefined) {
|
|
44976
|
-
delete entity[key];
|
|
44977
|
-
}
|
|
44978
|
-
}
|
|
44979
|
-
}
|
|
44980
|
-
/**
|
|
44981
|
-
* Applies all sync-only high-level abstractions after parsing.
|
|
45135
|
+
* Note: This function does not validate logic of the pipeline only the parsing
|
|
45136
|
+
* Note: This function acts as compilation process
|
|
44982
45137
|
*
|
|
44983
|
-
* @
|
|
44984
|
-
|
|
44985
|
-
|
|
44986
|
-
for (const highLevelAbstraction of HIGH_LEVEL_ABSTRACTIONS.filter(({ type }) => type === 'SYNC')) {
|
|
44987
|
-
highLevelAbstraction.$applyToPipelineJson($pipelineJson);
|
|
44988
|
-
}
|
|
44989
|
-
}
|
|
44990
|
-
/**
|
|
44991
|
-
* Ensures parsed pipelines always have the default `GENERIC` formfactor.
|
|
45138
|
+
* @param pipelineString {Promptbook} in string markdown format (.book.md)
|
|
45139
|
+
* @returns {Promptbook} compiled in JSON format (.bookc)
|
|
45140
|
+
* @throws {ParseError} if the promptbook string is not valid
|
|
44992
45141
|
*
|
|
44993
|
-
* @
|
|
45142
|
+
* @public exported from `@promptbook/core`
|
|
44994
45143
|
*/
|
|
44995
|
-
function
|
|
44996
|
-
|
|
44997
|
-
|
|
44998
|
-
|
|
45144
|
+
function parsePipeline(pipelineString) {
|
|
45145
|
+
const $pipelineJson = createInitialPipelineJson(pipelineString);
|
|
45146
|
+
const preparedPipelineString = preparePipelineString(pipelineString, $pipelineJson);
|
|
45147
|
+
const { pipelineHead, pipelineSections } = parsePreparedPipelineSections(preparedPipelineString, $pipelineJson);
|
|
45148
|
+
const getUniqueSectionName = createUniqueSectionNameResolver(pipelineSections);
|
|
45149
|
+
applyPipelineHead(pipelineHead, $pipelineJson);
|
|
45150
|
+
for (const pipelineSection of pipelineSections) {
|
|
45151
|
+
processPipelineSection(pipelineSection, $pipelineJson, getUniqueSectionName);
|
|
44999
45152
|
}
|
|
45000
|
-
|
|
45001
|
-
/**
|
|
45002
|
-
* Finalizes ordering and exports the parsed pipeline JSON.
|
|
45003
|
-
*
|
|
45004
|
-
* @private internal utility of `parsePipeline`
|
|
45005
|
-
*/
|
|
45006
|
-
function exportParsedPipelineJson($pipelineJson) {
|
|
45007
|
-
return exportJson({
|
|
45008
|
-
name: 'pipelineJson',
|
|
45009
|
-
message: `Result of \`parsePipeline\``,
|
|
45010
|
-
order: ORDER_OF_PIPELINE_JSON,
|
|
45011
|
-
value: {
|
|
45012
|
-
formfactorName: 'GENERIC',
|
|
45013
|
-
// <- Note: [🔆] Setting `formfactorName` is redundant to satisfy the typescript
|
|
45014
|
-
...$pipelineJson,
|
|
45015
|
-
},
|
|
45016
|
-
});
|
|
45153
|
+
return finalizeParsedPipeline($pipelineJson);
|
|
45017
45154
|
}
|
|
45018
45155
|
// TODO: [🧠] Maybe more things here can be refactored as high-level abstractions
|
|
45019
45156
|
// TODO: [main] !!4 Warn if used only sync version
|
|
45020
45157
|
// TODO: [🚞] Report here line/column of error
|
|
45021
|
-
// TODO: Use spaceTrim more effectively
|
|
45022
|
-
// TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
|
|
45023
|
-
// TODO: [🥞] Not optimal parsing because `splitMarkdownIntoSections` is executed twice with same string, once through `flattenMarkdown` and second directly here
|
|
45024
|
-
// TODO: [♈] Probably move expectations from tasks to parameters
|
|
45025
|
-
// TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
|
|
45026
|
-
// TODO: [🍙] Make some standard order of json properties
|
|
45027
45158
|
|
|
45028
45159
|
/**
|
|
45029
45160
|
* Compile pipeline from string (markdown) format to JSON format
|