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